- Fix parallel execution logic to properly handle JoinHandle<Result<R, E>> types - Use join_all instead of try_join_all for proper Result handling - Fix double question mark (??) issue in parallel execution methods - Clean up unused imports in parallel and cache modules - Ensure all performance optimization modules compile successfully - Fix CI build failures caused by compilation errors
536 lines
17 KiB
Markdown
536 lines
17 KiB
Markdown
# 🔌 **apt-ostree DBus Implementation Analysis**
|
|
|
|
## 📋 **Overview**
|
|
|
|
This document provides a comprehensive analysis of the DBus implementation in rpm-ostree, serving as the foundation for implementing a similar DBus-based daemon for apt-ostree. The analysis covers the complete DBus interface, security model, transaction handling, and architectural patterns.
|
|
|
|
## 🏗️ **DBus Architecture Overview**
|
|
|
|
### **Interface Hierarchy**
|
|
```
|
|
org.projectatomic.rpmostree1.Sysroot (Root Interface)
|
|
├── Properties
|
|
│ ├── Booted (o) - Booted OS object path
|
|
│ ├── Path (s) - System root path
|
|
│ ├── ActiveTransaction (sss) - Active transaction info
|
|
│ ├── ActiveTransactionPath (s) - Active transaction path
|
|
│ ├── Deployments (aa{sv}) - All deployments array
|
|
│ └── AutomaticUpdatePolicy (s) - Update policy
|
|
├── Methods
|
|
│ ├── RegisterClient(a{sv}) - Client registration
|
|
│ ├── UnregisterClient(a{sv}) - Client unregistration
|
|
│ ├── Reload() - Reload sysroot
|
|
│ ├── ReloadConfig() - Reload configuration
|
|
│ └── GetOS(s) -> o - Get OS object
|
|
└── Child Objects
|
|
└── org.projectatomic.rpmostree1.OS (OS Interface)
|
|
├── Properties
|
|
│ ├── BootedDeployment (a{sv})
|
|
│ ├── DefaultDeployment (a{sv})
|
|
│ ├── RollbackDeployment (a{sv})
|
|
│ ├── CachedUpdate (a{sv})
|
|
│ ├── HasCachedUpdateRpmDiff (b)
|
|
│ └── Name (s)
|
|
└── Methods
|
|
├── AutomaticUpdateTrigger(a{sv}) -> (b, s)
|
|
├── GetDeploymentsRpmDiff(ss) -> a(sua{sv})
|
|
├── Deploy(s, a{sv}) -> s
|
|
├── GetCachedDeployRpmDiff(s, as) -> (a(sua{sv}), a{sv})
|
|
├── DownloadDeployRpmDiff(s, as) -> s
|
|
├── Upgrade(a{sv}) -> s
|
|
├── GetCachedUpdateRpmDiff(s) -> (a(sua{sv}), a{sv})
|
|
├── DownloadUpdateRpmDiff() -> s
|
|
├── Rollback(a{sv}) -> s
|
|
├── ClearRollbackTarget(a{sv}) -> s
|
|
├── Rebase(a{sv}, s, as) -> s
|
|
├── GetCachedRebaseRpmDiff(s, as) -> (a(sua{sv}), a{sv})
|
|
├── DownloadRebaseRpmDiff(s, as) -> s
|
|
├── PkgChange(a{sv}, as, as) -> s
|
|
├── SetInitramfsState(b, as, a{sv}) -> s
|
|
├── InitramfsEtc(as, as, b, b, a{sv}) -> s
|
|
├── KernelArgs(s, as, as, as, a{sv}) -> s
|
|
├── GetDeploymentBootConfig(s, b) -> a{sv}
|
|
├── Cleanup(as) -> s
|
|
├── RefreshMd(a{sv}) -> s
|
|
├── ModifyYumRepo(s, a{ss}) -> s
|
|
├── ListRepos() -> aa{sv}
|
|
├── UpdateDeployment(a{sv}, a{sv}) -> s
|
|
├── FinalizeDeployment(a{sv}) -> s
|
|
├── WhatProvides(as) -> aa{sv}
|
|
├── GetPackages(as) -> aa{sv}
|
|
└── Search(as) -> aa{sv}
|
|
|
|
org.projectatomic.rpmostree1.OSExperimental (Experimental Interface)
|
|
├── Methods
|
|
│ ├── Moo(b) -> s - Test method
|
|
│ ├── LiveFs(a{sv}) -> s - Live filesystem operations
|
|
│ └── DownloadPackages(as, s) - Download packages
|
|
|
|
org.projectatomic.rpmostree1.Transaction (Transaction Interface)
|
|
├── Properties
|
|
│ ├── Title (s) - Transaction title
|
|
│ └── InitiatingClientDescription (s) - Client description
|
|
├── Methods
|
|
│ ├── Cancel() - Cancel transaction
|
|
│ └── Start() -> b - Start transaction
|
|
└── Signals
|
|
├── Finished(b, s) - Transaction completion
|
|
├── Message(s) - Status messages
|
|
├── TaskBegin(s) - Task start
|
|
├── TaskEnd(s) - Task completion
|
|
├── PercentProgress(s, u) - Progress percentage
|
|
├── DownloadProgress((tt), (uu), (uuu), (uuut), (uu), (tt)) - Download progress
|
|
├── SignatureProgress(av, s) - Signature verification
|
|
└── ProgressEnd() - Progress completion
|
|
```
|
|
|
|
## 🔍 **Detailed Interface Analysis**
|
|
|
|
### **1. Sysroot Interface (`org.projectatomic.rpmostree1.Sysroot`)**
|
|
|
|
#### **Core Properties**
|
|
- **`Booted` (o)**: Object path to the currently booted OS
|
|
- **`Path` (s)**: Absolute path to the system root (typically `/`)
|
|
- **`ActiveTransaction` (sss)**: Tuple of (method-name, sender-name, object-path) for active transaction
|
|
- **`ActiveTransactionPath` (s)**: DBus path to the active transaction object
|
|
- **`Deployments` (aa{sv})**: Array of deployment dictionaries with metadata
|
|
- **`AutomaticUpdatePolicy` (s)**: Policy string (`none`, `check`, `stage`)
|
|
|
|
#### **Client Management Methods**
|
|
```xml
|
|
<method name="RegisterClient">
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
</method>
|
|
|
|
<method name="UnregisterClient">
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
</method>
|
|
```
|
|
|
|
**Purpose**: Track active clients to prevent daemon from exiting when clients are connected.
|
|
|
|
#### **System Management Methods**
|
|
```xml
|
|
<method name="Reload">
|
|
<!-- Reload sysroot state -->
|
|
</method>
|
|
|
|
<method name="ReloadConfig">
|
|
<!-- Reload configuration files -->
|
|
</method>
|
|
```
|
|
|
|
**Purpose**: Synchronize daemon state with filesystem changes and configuration updates.
|
|
|
|
### **2. OS Interface (`org.projectatomic.rpmostree1.OS`)**
|
|
|
|
#### **Deployment Properties**
|
|
- **`BootedDeployment` (a{sv})**: Currently booted deployment metadata
|
|
- **`DefaultDeployment` (a{sv})**: Default deployment for next boot
|
|
- **`RollbackDeployment` (a{sv})**: Rollback target deployment
|
|
- **`CachedUpdate` (a{sv})**: Cached update information with package diffs
|
|
|
|
#### **Core Operations**
|
|
|
|
##### **Deployment Management**
|
|
```xml
|
|
<method name="Deploy">
|
|
<arg type="s" name="revision" direction="in"/>
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Upgrade">
|
|
<arg type="a{sv" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Rollback">
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
```
|
|
|
|
**Options**:
|
|
- `reboot` (b): Reboot after operation
|
|
- `allow-downgrade` (b): Allow version downgrades
|
|
- `dry-run` (b): Show what would be done
|
|
|
|
##### **Package Management**
|
|
```xml
|
|
<method name="PkgChange">
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="as" name="packages_added" direction="in"/>
|
|
<arg type="as" name="packages_removed" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
```
|
|
|
|
**Purpose**: Install/remove packages as atomic overlays on the base OS.
|
|
|
|
##### **System Configuration**
|
|
```xml
|
|
<method name="KernelArgs">
|
|
<arg type="s" name="existing_kernel_arg_string" direction="in"/>
|
|
<arg type="as" name="kernel_args_added" direction="in"/>
|
|
<arg type="as" name="kernel_args_replaced" direction="in"/>
|
|
<arg type="as" name="kernel_args_removed" direction="in"/>
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
|
|
<method name="SetInitramfsState">
|
|
<arg type="b" name="regenerate" direction="in"/>
|
|
<arg type="as" name="args" direction="in"/>
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
```
|
|
|
|
**Purpose**: Modify boot configuration and initramfs settings.
|
|
|
|
##### **Advanced Operations**
|
|
```xml
|
|
<method name="UpdateDeployment">
|
|
<arg type="a{sv}" name="modifiers" direction="in"/>
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
|
|
<method name="FinalizeDeployment">
|
|
<arg type="a{sv}" name="options" direction="in"/>
|
|
<arg type="s" name="transaction_address" direction="out"/>
|
|
</method>
|
|
```
|
|
|
|
**Modifiers**:
|
|
- `set-refspec` (s): Change base refspec
|
|
- `install-packages` (as): Add packages
|
|
- `uninstall-packages` (as): Remove packages
|
|
- `override-remove-packages` (as): Remove overrides
|
|
- `custom-origin` (ss): Custom origin URL and description
|
|
|
|
### **3. Transaction Interface (`org.projectatomic.rpmostree1.Transaction`)**
|
|
|
|
#### **Transaction Lifecycle**
|
|
```xml
|
|
<method name="Start">
|
|
<arg type="b" name="started" direction="out"/>
|
|
</method>
|
|
|
|
<method name="Cancel">
|
|
<!-- Cancel active transaction -->
|
|
</method>
|
|
```
|
|
|
|
#### **Progress Monitoring Signals**
|
|
```xml
|
|
<signal name="Message">
|
|
<arg name="text" type="s" direction="out"/>
|
|
</signal>
|
|
|
|
<signal name="TaskBegin">
|
|
<arg name="text" type="s" direction="out"/>
|
|
</signal>
|
|
|
|
<signal name="TaskEnd">
|
|
<arg name="text" type="s" direction="out"/>
|
|
</signal>
|
|
|
|
<signal name="PercentProgress">
|
|
<arg name="text" type="s" direction="out"/>
|
|
<arg name="percentage" type="u" direction="out"/>
|
|
</signal>
|
|
```
|
|
|
|
#### **Download Progress Signals**
|
|
```xml
|
|
<signal name="DownloadProgress">
|
|
<arg name="time" type="(tt)" direction="out"/>
|
|
<arg name="outstanding" type="(uu)" direction="out"/>
|
|
<arg name="metadata" type="(uuu)" direction="out"/>
|
|
<arg name="delta" type="(uuut)" direction="out"/>
|
|
<arg name="content" type="(uu)" direction="out"/>
|
|
<arg name="transfer" type="(tt)" direction="out"/>
|
|
</signal>
|
|
```
|
|
|
|
**Data Format**:
|
|
- **Time**: (start_time, elapsed_seconds)
|
|
- **Outstanding**: (outstanding_fetches, outstanding_writes)
|
|
- **Metadata**: (scanned, fetched, outstanding)
|
|
- **Delta**: (total_parts, fetched_parts, total_super_blocks, total_size)
|
|
- **Content**: (fetched, requested)
|
|
- **Transfer**: (bytes_transferred, bytes_per_second)
|
|
|
|
## 🔐 **Security Model Analysis**
|
|
|
|
### **Polkit Integration**
|
|
|
|
#### **Policy Actions**
|
|
```xml
|
|
<action id="org.projectatomic.rpmostree1.install-uninstall-packages">
|
|
<description>Install and remove packages</description>
|
|
<message>Authentication is required to install and remove software</message>
|
|
<defaults>
|
|
<allow_any>auth_admin</allow_any>
|
|
<allow_inactive>auth_admin</allow_inactive>
|
|
<allow_active>auth_admin_keep</allow_active>
|
|
</defaults>
|
|
</action>
|
|
|
|
<action id="org.projectatomic.rpmostree1.deploy">
|
|
<description>Update base OS</description>
|
|
<message>Authentication is required to update software</message>
|
|
<defaults>
|
|
<allow_any>auth_admin</allow_any>
|
|
<allow_inactive>auth_admin</allow_inactive>
|
|
<allow_active>auth_admin_keep</allow_active>
|
|
</defaults>
|
|
</action>
|
|
```
|
|
|
|
#### **Security Levels**
|
|
- **`auth_admin`**: Full authentication required
|
|
- **`auth_admin_keep`**: Keep authentication for active sessions
|
|
- **`auth_inactive`**: Authentication required for inactive sessions
|
|
|
|
### **Privilege Escalation**
|
|
- **Read-only operations**: No privileges required (status, search, info)
|
|
- **Package operations**: `auth_admin` required (install, remove, override)
|
|
- **System operations**: `auth_admin` required (upgrade, rollback, deploy)
|
|
- **Boot configuration**: `auth_admin` required (kargs, initramfs)
|
|
|
|
## 🏗️ **Implementation Architecture**
|
|
|
|
### **Daemon Structure**
|
|
```cpp
|
|
struct _RpmostreedDaemon {
|
|
GObject parent_instance;
|
|
|
|
// Client management
|
|
GHashTable *bus_clients;
|
|
|
|
// System state
|
|
gboolean running;
|
|
gboolean rebooting;
|
|
RpmostreedSysroot *sysroot;
|
|
gchar *sysroot_path;
|
|
|
|
// Configuration
|
|
guint idle_exit_timeout;
|
|
RpmostreedAutomaticUpdatePolicy auto_update_policy;
|
|
gboolean lock_layering;
|
|
gboolean disable_recommends;
|
|
|
|
// DBus infrastructure
|
|
GDBusConnection *connection;
|
|
GDBusObjectManagerServer *object_manager;
|
|
|
|
// Async runtime
|
|
std::optional<rust::Box<rpmostreecxx::TokioHandle>> tokio_handle;
|
|
};
|
|
```
|
|
|
|
### **Transaction Management**
|
|
```cpp
|
|
struct _RpmostreedTransactionPrivate {
|
|
GDBusMethodInvocation *invocation;
|
|
gboolean executed;
|
|
GCancellable *cancellable;
|
|
|
|
// System state
|
|
char *sysroot_path;
|
|
OstreeSysroot *sysroot;
|
|
gboolean sysroot_locked;
|
|
|
|
// Client tracking
|
|
char *client_description;
|
|
char *agent_id;
|
|
char *sd_unit;
|
|
|
|
// Progress tracking
|
|
gint64 last_progress_journal;
|
|
gboolean redirect_output;
|
|
|
|
// Peer connections
|
|
GDBusServer *server;
|
|
GHashTable *peer_connections;
|
|
|
|
// Completion state
|
|
GVariant *finished_params;
|
|
guint watch_id;
|
|
};
|
|
```
|
|
|
|
### **Object Path Structure**
|
|
```
|
|
/org/projectatomic/rpmostree1/Sysroot
|
|
├── /org/projectatomic/rpmostree1/Sysroot/OS/{osname}
|
|
│ ├── Properties: BootedDeployment, DefaultDeployment, etc.
|
|
│ └── Methods: Deploy, Upgrade, Rollback, etc.
|
|
└── /org/projectatomic/rpmostree1/Sysroot/Transaction/{id}
|
|
├── Properties: Title, InitiatingClientDescription
|
|
├── Methods: Start, Cancel
|
|
└── Signals: Progress, Completion, etc.
|
|
```
|
|
|
|
## 🔄 **Transaction Flow**
|
|
|
|
### **1. Transaction Creation**
|
|
```
|
|
Client Request → Daemon → Create Transaction Object → Return Transaction Path
|
|
```
|
|
|
|
### **2. Transaction Execution**
|
|
```
|
|
Transaction.Start() → Lock Sysroot → Execute Operations → Emit Progress Signals
|
|
```
|
|
|
|
### **3. Transaction Completion**
|
|
```
|
|
Operations Complete → Unlock Sysroot → Emit Finished Signal → Cleanup
|
|
```
|
|
|
|
### **4. Error Handling**
|
|
```
|
|
Error Occurs → Rollback Changes → Emit Error Signal → Cleanup Resources
|
|
```
|
|
|
|
## 📊 **Data Types and Structures**
|
|
|
|
### **Deployment Dictionary**
|
|
```xml
|
|
<!-- Deployment dictionary keys -->
|
|
'id' (type 's') - Deployment identifier
|
|
'osname' (type 's') - OS name
|
|
'serial' (type 'i') - Serial number
|
|
'checksum' (type 's') - OSTree commit hash
|
|
'version' (type 's') - Version string
|
|
'timestamp' (type 't') - Creation timestamp
|
|
'origin' (type 's') - Origin reference
|
|
'signatures' (type 'av') - GPG signatures
|
|
'packages' (type 'as') - Installed packages
|
|
'booted' (type 'b') - Currently booted
|
|
```
|
|
|
|
### **Package Information**
|
|
```xml
|
|
<!-- Package properties -->
|
|
"name" (type 's') - Package name
|
|
"epoch" (type 't') - Package epoch
|
|
"version" (type 's') - Package version
|
|
"arch" (type 's') - Package architecture
|
|
"nevra" (type 's') - Full NEVRA string
|
|
"evr" (type 's') - EVR string
|
|
"summary" (type 's') - Package summary
|
|
"reponame" (type 's') - Repository name
|
|
```
|
|
|
|
### **Update Information**
|
|
```xml
|
|
<!-- CachedUpdate dictionary -->
|
|
'osname' (type 's') - OS name
|
|
'checksum' (type 's') - Commit hash
|
|
'version' (type 's') - Version string
|
|
'timestamp' (type 't') - Timestamp
|
|
'origin' (type 's') - Origin reference
|
|
'signatures' (type 'av') - GPG signatures
|
|
'gpg-enabled' (type 'b') - GPG verification enabled
|
|
'ref-has-new-commit' (type 'b') - New commit available
|
|
'rpm-diff' (type 'a{sv}') - Package differences
|
|
'advisories' (type 'a(suuasa{sv})') - Security advisories
|
|
```
|
|
|
|
## 🚀 **apt-ostree Implementation Strategy**
|
|
|
|
### **Phase 1: Core DBus Interface**
|
|
1. **Implement Sysroot Interface**
|
|
- Basic properties (Path, Deployments)
|
|
- Client registration methods
|
|
- Reload methods
|
|
|
|
2. **Implement OS Interface**
|
|
- Deployment properties
|
|
- Basic operations (Deploy, Upgrade, Rollback)
|
|
- Package management (PkgChange)
|
|
|
|
3. **Implement Transaction Interface**
|
|
- Transaction lifecycle methods
|
|
- Progress signals
|
|
- Completion handling
|
|
|
|
### **Phase 2: Advanced Features**
|
|
1. **Package Operations**
|
|
- APT integration for package resolution
|
|
- Dependency handling
|
|
- Conflict resolution
|
|
|
|
2. **System Operations**
|
|
- OSTree integration
|
|
- Bootloader configuration
|
|
- Initramfs management
|
|
|
|
3. **Security Integration**
|
|
- Polkit policy implementation
|
|
- Privilege escalation
|
|
- Client authentication
|
|
|
|
### **Phase 3: Optimization**
|
|
1. **Performance**
|
|
- Async operation handling
|
|
- Progress reporting
|
|
- Resource management
|
|
|
|
2. **Reliability**
|
|
- Error handling
|
|
- Rollback mechanisms
|
|
- Transaction recovery
|
|
|
|
## 🔧 **Implementation Considerations**
|
|
|
|
### **Language Choice**
|
|
- **Rust**: Primary implementation language for type safety and performance
|
|
- **C Bindings**: For OSTree and system library integration
|
|
- **DBus**: Using `zbus` crate for DBus implementation
|
|
|
|
### **Dependencies**
|
|
```toml
|
|
[dependencies]
|
|
zbus = "3.0" # DBus implementation
|
|
tokio = { version = "1.0", features = ["full"] } # Async runtime
|
|
ostree = "0.20" # OSTree bindings
|
|
serde = { version = "1.0", features = ["derive"] } # Serialization
|
|
tracing = "0.1" # Logging and tracing
|
|
```
|
|
|
|
### **System Integration**
|
|
- **systemd**: Service management and socket activation
|
|
- **Polkit**: Authorization and privilege management
|
|
- **OSTree**: Base system management
|
|
- **APT**: Package management and resolution
|
|
|
|
### **Testing Strategy**
|
|
1. **Unit Tests**: Individual interface methods
|
|
2. **Integration Tests**: Full transaction workflows
|
|
3. **System Tests**: Real OSTree environment testing
|
|
4. **Security Tests**: Polkit policy validation
|
|
|
|
## 📚 **Reference Implementation**
|
|
|
|
### **Key Files to Study**
|
|
- `org.projectatomic.rpmostree1.xml` - Complete DBus interface definition
|
|
- `rpmostreed-daemon.cxx` - Main daemon implementation
|
|
- `rpmostreed-sysroot.cxx` - Sysroot interface implementation
|
|
- `rpmostreed-transaction.cxx` - Transaction management
|
|
- `rpmostreed-transaction-types.cxx` - Transaction type implementations
|
|
- `org.projectatomic.rpmostree1.policy` - Polkit security policies
|
|
|
|
### **Architecture Patterns**
|
|
1. **Object-Oriented Design**: Clear separation of concerns
|
|
2. **Signal-Based Communication**: Asynchronous progress reporting
|
|
3. **Transaction-Based Operations**: Atomic operation handling
|
|
4. **Client Registration**: Lifecycle management
|
|
5. **Security Integration**: Polkit-based authorization
|
|
|
|
This analysis provides the foundation for implementing a production-ready DBus daemon for apt-ostree that maintains compatibility with the existing rpm-ostree ecosystem while adapting to the Debian/Ubuntu package management paradigm.
|