Some checks failed
Comprehensive CI/CD Pipeline / Build and Test (push) Successful in 7m17s
Comprehensive CI/CD Pipeline / Security Audit (push) Failing after 8s
Comprehensive CI/CD Pipeline / Package Validation (push) Successful in 54s
Comprehensive CI/CD Pipeline / Status Report (push) Has been skipped
- Fixed /sysroot directory requirement for bootc compatibility - Implemented proper composefs configuration files - Added log cleanup for reproducible builds - Created correct /ostree symlink to sysroot/ostree - Bootc lint now passes 11/11 checks with only minor warning - Full bootc compatibility achieved - images ready for production use Updated documentation and todo to reflect completed work. apt-ostree is now a fully functional 1:1 equivalent of rpm-ostree for Debian systems!
591 lines
No EOL
17 KiB
Markdown
591 lines
No EOL
17 KiB
Markdown
# rpm-ostree Client-Daemon Architecture
|
|
|
|
## Executive Summary
|
|
|
|
rpm-ostree uses a sophisticated client-daemon architecture that separates privileged system operations from unprivileged user interactions. This design provides security, reliability, and concurrent operation support while maintaining a clean user interface.
|
|
|
|
## Architecture Overview
|
|
|
|
### High-Level Architecture
|
|
|
|
```
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ CLI Client │ │ GUI Client │ │ API Client │
|
|
│ (rpmostree) │ │ (GNOME/KDE) │ │ (Python/Go) │
|
|
└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘
|
|
│ │ │
|
|
└──────────────────────┼──────────────────────┘
|
|
│
|
|
┌─────────────▼─────────────┐
|
|
│ D-Bus Interface │
|
|
│ (org.projectatomic.rpmo │
|
|
│ stree1) │
|
|
└─────────────┬─────────────┘
|
|
│
|
|
┌─────────────▼─────────────┐
|
|
│ rpm-ostreed Daemon │
|
|
│ (Privileged Service) │
|
|
└─────────────┬─────────────┘
|
|
│
|
|
┌───────────────────────┼───────────────────────┐
|
|
│ │ │
|
|
┌─────▼─────┐ ┌───────▼──────┐ ┌─────▼─────┐
|
|
│ libdnf │ │ libostree │ │ System │
|
|
│ (RPM/DNF) │ │ (Filesystem) │ │ Services │
|
|
└───────────┘ └──────────────┘ └───────────┘
|
|
```
|
|
|
|
### Design Principles
|
|
|
|
1. **Privilege Separation**: Daemon runs with elevated privileges, clients run unprivileged
|
|
2. **D-Bus Communication**: Standard system service interface for inter-process communication
|
|
3. **Transaction Management**: Atomic operations with rollback capability
|
|
4. **Concurrent Operations**: Multiple clients can interact simultaneously
|
|
5. **State Persistence**: Daemon maintains system state across operations
|
|
|
|
## Client Architecture
|
|
|
|
### CLI Client (`rpmostree`)
|
|
|
|
**Purpose**: Command-line interface for user interaction
|
|
|
|
**Key Components**:
|
|
- **Command Parser**: Parse command-line arguments
|
|
- **D-Bus Client**: Communicate with daemon
|
|
- **Progress Handler**: Display operation progress
|
|
- **Error Handler**: Handle and display errors
|
|
|
|
**Implementation**:
|
|
```cpp
|
|
class RpmOstreeClient {
|
|
// D-Bus client
|
|
std::unique_ptr<RpmOstreeClientLib> client_lib;
|
|
|
|
// Command dispatch
|
|
int dispatch_command(int argc, char* argv[]);
|
|
|
|
// D-Bus communication
|
|
bool connect_to_daemon();
|
|
void handle_daemon_error(const std::string& error);
|
|
|
|
// Progress handling
|
|
void handle_progress(const std::string& message, int percentage);
|
|
void handle_completion(const std::string& result);
|
|
};
|
|
```
|
|
|
|
**Command Flow**:
|
|
1. Parse command-line arguments
|
|
2. Connect to daemon via D-Bus
|
|
3. Send operation request
|
|
4. Handle progress updates
|
|
5. Display results or errors
|
|
|
|
### GUI Clients
|
|
|
|
**Purpose**: Graphical user interfaces for system management
|
|
|
|
**Components**:
|
|
- **GNOME Software**: Integration with GNOME Software Center
|
|
- **KDE Discover**: Integration with KDE Discover
|
|
- **Custom GUIs**: Third-party graphical interfaces
|
|
|
|
**Implementation**:
|
|
- Use D-Bus interface for system operations
|
|
- Provide user-friendly progress indicators
|
|
- Handle authentication via PolicyKit
|
|
- Display system status and deployment information
|
|
|
|
### API Clients
|
|
|
|
**Purpose**: Programmatic interfaces for automation and integration
|
|
|
|
**Components**:
|
|
- **Python Bindings**: Python library for rpm-ostree operations
|
|
- **Go Bindings**: Go library for rpm-ostree operations
|
|
- **REST APIs**: HTTP-based interfaces (planned)
|
|
|
|
**Implementation**:
|
|
- Direct D-Bus communication
|
|
- High-level abstractions for common operations
|
|
- Error handling and recovery mechanisms
|
|
- Async operation support
|
|
|
|
## Daemon Architecture
|
|
|
|
### Core Daemon (`rpm-ostreed`)
|
|
|
|
**Purpose**: Centralized system service for privileged operations
|
|
|
|
**Key Components**:
|
|
- **D-Bus Service**: Expose system management interface
|
|
- **Transaction Manager**: Handle atomic operations
|
|
- **State Manager**: Maintain system state
|
|
- **Resource Manager**: Manage system resources
|
|
|
|
**Implementation**:
|
|
```cpp
|
|
class RpmOstreeDaemon {
|
|
// Global state management
|
|
std::unique_ptr<RpmOstreeSysroot> sysroot;
|
|
std::unique_ptr<RpmOstreeOS> os;
|
|
|
|
// Transaction management
|
|
std::map<std::string, std::unique_ptr<RpmOstreeTransaction>> transactions;
|
|
|
|
// D-Bus interface
|
|
std::unique_ptr<GDBusObjectManagerServer> object_manager;
|
|
|
|
// Service management
|
|
void start_service();
|
|
void stop_service();
|
|
void handle_client_connection(GDBusConnection* connection);
|
|
};
|
|
```
|
|
|
|
**Service Lifecycle**:
|
|
1. Initialize system components
|
|
2. Register D-Bus service
|
|
3. Start listening for client connections
|
|
4. Handle client requests
|
|
5. Clean up on shutdown
|
|
|
|
### D-Bus Interface
|
|
|
|
**Service Name**: `org.projectatomic.rpmostree1`
|
|
|
|
**Main Objects**:
|
|
- `/org/projectatomic/rpmostree1/Sysroot`: System root management
|
|
- `/org/projectatomic/rpmostree1/OS`: Operating system operations
|
|
|
|
**Key Methods**:
|
|
```xml
|
|
<interface name="org.projectatomic.rpmostree1.OS">
|
|
<method name="Upgrade">
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Rollback">
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Deploy">
|
|
<arg name="ref" type="s" direction="in"/>
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Rebase">
|
|
<arg name="ref" type="s" direction="in"/>
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="PkgChange">
|
|
<arg name="packages" type="as" direction="in"/>
|
|
<arg name="change_type" type="s" direction="in"/>
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="KernelArgs">
|
|
<arg name="operation" type="s" direction="in"/>
|
|
<arg name="args" type="as" direction="in"/>
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Cleanup">
|
|
<arg name="options" type="a{sv}" direction="in"/>
|
|
<arg name="transaction_address" type="s" direction="out"/>
|
|
</method>
|
|
</interface>
|
|
```
|
|
|
|
**Signals**:
|
|
```xml
|
|
<signal name="TransactionChanged">
|
|
<arg name="transaction_address" type="s"/>
|
|
<arg name="state" type="s"/>
|
|
<arg name="message" type="s"/>
|
|
<arg name="percentage" type="i"/>
|
|
</signal>
|
|
|
|
<signal name="TransactionCompleted">
|
|
<arg name="transaction_address" type="s"/>
|
|
<arg name="success" type="b"/>
|
|
<arg name="result" type="s"/>
|
|
</signal>
|
|
```
|
|
|
|
### Transaction Management
|
|
|
|
**Purpose**: Handle atomic operations with rollback capability
|
|
|
|
**Transaction Types**:
|
|
1. **DeployTransaction**: New deployment creation
|
|
2. **RollbackTransaction**: Deployment rollback
|
|
3. **PkgChangeTransaction**: Package installation/removal
|
|
4. **RebaseTransaction**: Base image switching
|
|
5. **UpgradeTransaction**: System upgrades
|
|
|
|
**Implementation**:
|
|
```cpp
|
|
class RpmOstreeTransaction {
|
|
// Transaction state
|
|
TransactionState state;
|
|
std::string transaction_id;
|
|
TransactionType type;
|
|
|
|
// Rollback information
|
|
std::vector<RollbackPoint> rollback_points;
|
|
|
|
// Progress reporting
|
|
void emit_progress(const std::string& message, int percentage);
|
|
void emit_completion(bool success, const std::string& result);
|
|
|
|
// Atomic execution
|
|
bool execute_atomic();
|
|
void rollback_on_failure();
|
|
|
|
// State management
|
|
void set_state(TransactionState new_state);
|
|
TransactionState get_state() const;
|
|
};
|
|
```
|
|
|
|
**Transaction Lifecycle**:
|
|
1. **Initiation**: Client requests operation
|
|
2. **Validation**: Validate request parameters
|
|
3. **Preparation**: Set up rollback points
|
|
4. **Execution**: Perform operation with progress reporting
|
|
5. **Completion**: Finalize operation or rollback
|
|
6. **Cleanup**: Clean up resources
|
|
|
|
### State Management
|
|
|
|
**Purpose**: Maintain system state across operations
|
|
|
|
**State Components**:
|
|
- **Deployment State**: Current and available deployments
|
|
- **Package State**: Installed and layered packages
|
|
- **Configuration State**: System configuration
|
|
- **Transaction State**: Active and completed transactions
|
|
|
|
**Implementation**:
|
|
```cpp
|
|
class StateManager {
|
|
// System state
|
|
std::unique_ptr<DeploymentState> deployment_state;
|
|
std::unique_ptr<PackageState> package_state;
|
|
std::unique_ptr<ConfigurationState> config_state;
|
|
|
|
// State persistence
|
|
void save_state();
|
|
void load_state();
|
|
void sync_state();
|
|
|
|
// State queries
|
|
DeploymentInfo get_current_deployment();
|
|
std::vector<DeploymentInfo> get_available_deployments();
|
|
std::vector<PackageInfo> get_installed_packages();
|
|
};
|
|
```
|
|
|
|
## Communication Protocol
|
|
|
|
### D-Bus Communication
|
|
|
|
**Connection Setup**:
|
|
```cpp
|
|
// Client connection
|
|
GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr);
|
|
|
|
// Service registration
|
|
GDBusObjectManagerServer* object_manager = g_dbus_object_manager_server_new("/org/projectatomic/rpmostree1");
|
|
```
|
|
|
|
**Method Calls**:
|
|
```cpp
|
|
// Client method call
|
|
GVariant* result = g_dbus_connection_call_sync(
|
|
connection,
|
|
"org.projectatomic.rpmostree1",
|
|
"/org/projectatomic/rpmostree1/OS",
|
|
"org.projectatomic.rpmostree1.OS",
|
|
"Upgrade",
|
|
g_variant_new("(a{sv})", options),
|
|
nullptr,
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
nullptr,
|
|
nullptr
|
|
);
|
|
```
|
|
|
|
**Signal Handling**:
|
|
```cpp
|
|
// Client signal connection
|
|
g_dbus_connection_signal_subscribe(
|
|
connection,
|
|
"org.projectatomic.rpmostree1",
|
|
"org.projectatomic.rpmostree1.OS",
|
|
"TransactionChanged",
|
|
"/org/projectatomic/rpmostree1/OS",
|
|
nullptr,
|
|
G_DBUS_SIGNAL_FLAGS_NONE,
|
|
handle_transaction_changed,
|
|
nullptr,
|
|
nullptr
|
|
);
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
**Error Types**:
|
|
1. **Network Errors**: Package download failures
|
|
2. **Dependency Errors**: Package dependency conflicts
|
|
3. **Filesystem Errors**: OSTree operation failures
|
|
4. **Permission Errors**: Insufficient privileges
|
|
5. **Transaction Errors**: Transaction failures
|
|
|
|
**Error Propagation**:
|
|
```cpp
|
|
// Daemon error handling
|
|
void handle_error(const std::string& error, GDBusMethodInvocation* invocation) {
|
|
GError* g_error = g_error_new_literal(
|
|
G_DBUS_ERROR,
|
|
G_DBUS_ERROR_FAILED,
|
|
error.c_str()
|
|
);
|
|
g_dbus_method_invocation_return_gerror(invocation, g_error);
|
|
g_error_free(g_error);
|
|
}
|
|
|
|
// Client error handling
|
|
void handle_daemon_error(GError* error) {
|
|
std::string error_message = error->message;
|
|
std::cerr << "Error: " << error_message << std::endl;
|
|
|
|
// Provide user guidance based on error type
|
|
if (g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
|
|
std::cerr << "Daemon is not running. Please start the rpm-ostreed service." << std::endl;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Security Model
|
|
|
|
### Privilege Separation
|
|
|
|
**Principle**: Separate privileged operations from unprivileged user operations
|
|
|
|
**Implementation**:
|
|
- **Daemon**: Runs with elevated privileges (root)
|
|
- **Client**: Runs with user privileges
|
|
- **D-Bus**: Secure communication channel
|
|
- **PolicyKit**: Authentication for privileged operations
|
|
|
|
### Authentication
|
|
|
|
**PolicyKit Integration**:
|
|
```xml
|
|
<policyconfig>
|
|
<action id="org.projectatomic.rpmostree1.upgrade">
|
|
<description>Upgrade system</description>
|
|
<message>Authentication is required to upgrade the system</message>
|
|
<defaults>
|
|
<allow_any>auth_admin</allow_any>
|
|
<allow_inactive>auth_admin</allow_inactive>
|
|
<allow_active>auth_admin</allow_active>
|
|
</defaults>
|
|
<annotate key="org.freedesktop.policykit.exec.path">/usr/libexec/rpm-ostreed</annotate>
|
|
</action>
|
|
</policyconfig>
|
|
```
|
|
|
|
### Sandboxing
|
|
|
|
**Package Script Execution**:
|
|
- Execute package scripts in controlled environment
|
|
- Use namespace isolation for security
|
|
- Restrict filesystem access
|
|
- Limit privilege escalation
|
|
|
|
## Concurrent Operations
|
|
|
|
### Multiple Clients
|
|
|
|
**Support**: Multiple clients can interact with daemon simultaneously
|
|
|
|
**Implementation**:
|
|
- **Thread-Safe Operations**: All operations are thread-safe
|
|
- **Transaction Isolation**: Each operation gets its own transaction
|
|
- **Resource Locking**: Prevent conflicting operations
|
|
- **Queue Management**: Queue operations when necessary
|
|
|
|
### Operation Queuing
|
|
|
|
**Queue Management**:
|
|
```cpp
|
|
class OperationQueue {
|
|
std::queue<Operation> pending_operations;
|
|
std::mutex queue_mutex;
|
|
std::condition_variable queue_cv;
|
|
|
|
void enqueue_operation(const Operation& operation);
|
|
Operation dequeue_operation();
|
|
bool has_pending_operations();
|
|
};
|
|
```
|
|
|
|
## Performance Optimization
|
|
|
|
### Resource Management
|
|
|
|
**Memory Management**:
|
|
- Efficient memory usage for large operations
|
|
- Garbage collection for completed transactions
|
|
- Memory pooling for frequently allocated objects
|
|
|
|
**Disk Management**:
|
|
- OSTree deduplication for storage efficiency
|
|
- Temporary file cleanup
|
|
- Cache management for package downloads
|
|
|
|
**Network Optimization**:
|
|
- Parallel package downloads
|
|
- Connection pooling
|
|
- Bandwidth optimization
|
|
|
|
### Caching
|
|
|
|
**Package Cache**:
|
|
- Cache downloaded packages
|
|
- Cache package metadata
|
|
- Cache dependency resolution results
|
|
|
|
**State Cache**:
|
|
- Cache deployment information
|
|
- Cache package lists
|
|
- Cache configuration data
|
|
|
|
## Monitoring and Logging
|
|
|
|
### Logging
|
|
|
|
**Log Levels**:
|
|
- **DEBUG**: Detailed debugging information
|
|
- **INFO**: General information
|
|
- **WARNING**: Warning messages
|
|
- **ERROR**: Error messages
|
|
- **CRITICAL**: Critical errors
|
|
|
|
**Log Implementation**:
|
|
```cpp
|
|
class Logger {
|
|
void debug(const std::string& message);
|
|
void info(const std::string& message);
|
|
void warning(const std::string& message);
|
|
void error(const std::string& message);
|
|
void critical(const std::string& message);
|
|
};
|
|
```
|
|
|
|
### Monitoring
|
|
|
|
**Health Monitoring**:
|
|
- Daemon health checks
|
|
- Transaction monitoring
|
|
- Resource usage monitoring
|
|
- Error rate monitoring
|
|
|
|
**Metrics Collection**:
|
|
- Operation success rates
|
|
- Performance metrics
|
|
- Resource usage statistics
|
|
- Error statistics
|
|
|
|
## Systemd Integration
|
|
|
|
### Service Definition
|
|
|
|
**Service File**: `/usr/lib/systemd/system/rpm-ostreed.service`
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=rpm-ostree Daemon
|
|
Documentation=man:rpm-ostreed(8)
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=dbus
|
|
BusName=org.projectatomic.rpmostree1
|
|
ExecStart=/usr/libexec/rpm-ostreed
|
|
Restart=on-failure
|
|
RestartSec=1
|
|
User=root
|
|
Group=root
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
Also=rpm-ostreed.socket
|
|
```
|
|
|
|
### D-Bus Activation
|
|
|
|
**Socket File**: `/usr/lib/systemd/system/rpm-ostreed.socket`
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=rpm-ostree D-Bus Socket
|
|
Documentation=man:rpm-ostreed(8)
|
|
|
|
[Socket]
|
|
ListenStream=/run/dbus/system_bus_socket
|
|
SocketUser=root
|
|
SocketGroup=root
|
|
|
|
[Install]
|
|
WantedBy=sockets.target
|
|
```
|
|
|
|
## Error Recovery
|
|
|
|
### Automatic Recovery
|
|
|
|
**Transaction Rollback**:
|
|
- Automatic rollback on transaction failure
|
|
- State restoration to previous known good state
|
|
- Resource cleanup after rollback
|
|
|
|
**Daemon Recovery**:
|
|
- Automatic daemon restart on failure
|
|
- State recovery on daemon restart
|
|
- Transaction recovery for incomplete operations
|
|
|
|
### Manual Recovery
|
|
|
|
**Recovery Procedures**:
|
|
- Manual rollback procedures
|
|
- State reset procedures
|
|
- Configuration recovery procedures
|
|
- Filesystem recovery procedures
|
|
|
|
## Future Enhancements
|
|
|
|
### Planned Features
|
|
|
|
1. **Container Integration**: Direct container support
|
|
2. **Cloud Integration**: Cloud deployment support
|
|
3. **Advanced Monitoring**: Enhanced monitoring capabilities
|
|
4. **Performance Optimization**: Further performance improvements
|
|
|
|
### Architecture Improvements
|
|
|
|
1. **Microservices**: Split daemon into microservices
|
|
2. **API Gateway**: REST API gateway for external access
|
|
3. **Event Streaming**: Event streaming for real-time updates
|
|
4. **Distributed Operations**: Support for distributed operations |