# D-Bus Infrastructure Documentation **Created**: August 21, 2024 **Last Updated**: August 21, 2024 **Status**: 🔄 In Progress - Client Infrastructure Complete ## Overview The apt-ostree project includes a D-Bus infrastructure for communication between the CLI client and the system daemon (apt-ostreed). This infrastructure enables system management, transaction handling, and privileged operations. ## Architecture ### Service Information - **Service Name**: `org.projectatomic.aptostree1` - **Object Path**: `/org/projectatomic/aptostree1` - **Interface**: `org.projectatomic.aptostree1` - **Bus Type**: System bus (privileged operations) ### Component Structure ``` ┌─────────────────┐ D-Bus ┌─────────────────┐ │ CLI Client │ ←────────→ │ apt-ostreed │ │ (apt-ostree) │ │ Daemon │ └─────────────────┘ └─────────────────┘ │ │ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ D-Bus Client │ │ D-Bus Server │ │ (zbus) │ │ (zbus) │ └─────────────────┘ └─────────────────┘ ``` ## Client Implementation ### AptOstreeClient Trait The core client interface is defined by the `AptOstreeClient` trait: ```rust #[async_trait::async_trait] pub trait AptOstreeClient: Send + Sync { /// Start a new transaction async fn start_transaction(&mut self, transaction_type: &str) -> ClientResult; /// Get transaction status async fn get_transaction_status(&self, transaction_id: &str) -> ClientResult; /// Install packages async fn install_packages(&mut self, transaction_id: &str, packages: &[&str]) -> ClientResult; /// Remove packages async fn remove_packages(&mut self, transaction_id: &str, packages: &[&str]) -> ClientResult; /// Upgrade system async fn upgrade(&mut self, transaction_id: &str) -> ClientResult; /// Rollback system async fn rollback(&mut self, transaction_id: &str) -> ClientResult; /// Deploy new deployment async fn deploy(&mut self, transaction_id: &str, refspec: &str) -> ClientResult; /// Rebase system async fn rebase(&mut self, transaction_id: &str, refspec: &str) -> ClientResult; /// Get deployments async fn get_deployments(&self) -> ClientResult>; /// Reload daemon async fn reload(&mut self) -> ClientResult; /// Shutdown daemon async fn shutdown(&mut self) -> ClientResult; } ``` ### ClientDBus Implementation The `ClientDBus` struct provides the concrete implementation: ```rust pub struct ClientDBus { config: ClientConfig, connection: Option, proxy: Option>, } ``` #### Key Features - **Connection management**: Handles D-Bus connection lifecycle - **Error handling**: Error types and conversion - **Async support**: Async/await compatibility - **Type safety**: Strong typing for operations ## Data Structures ### DeploymentInfo ```rust #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct DeploymentInfo { pub id: String, pub commit: String, pub booted: bool, pub timestamp: String, pub version: String, } ``` ### ClientConfig ```rust #[derive(Debug, Clone)] pub struct ClientConfig { pub dbus_name: String, pub dbus_path: String, pub dbus_interface: String, pub timeout: std::time::Duration, } ``` ## Error Handling ### ClientError Types ```rust #[derive(Debug, thiserror::Error)] pub enum ClientError { #[error("DBus error: {0}")] DBus(#[from] zbus::Error), #[error("Connection error: {0}")] Connection(String), #[error("Timeout error: {0}")] Timeout(String), #[error("Authentication error: {0}")] Authentication(String), } ``` ### Error Conversion - Conversion from zbus errors - Error messages for connection issues - Timeout handling for operations - Authentication error handling ## Usage Examples ### Basic Client Setup ```rust use apt_ostree::client::{AptOstreeClient, ClientDBus, ClientConfig}; async fn setup_client() -> Result, Box> { let config = ClientConfig::default(); let mut client = ClientDBus::new(config); // Connect to the daemon client.connect().await?; Ok(Box::new(client)) } ``` ### Transaction Management ```rust async fn perform_upgrade() -> Result<(), Box> { let mut client = setup_client().await?; // Start upgrade transaction let transaction_id = client.start_transaction("upgrade").await?; println!("Upgrade transaction started: {}", transaction_id); // Perform upgrade let success = client.upgrade(&transaction_id).await?; if success { println!("Upgrade completed successfully!"); } Ok(()) } ``` ### Deployment Operations ```rust async fn manage_deployments() -> Result<(), Box> { let mut client = setup_client().await?; // Get current deployments let deployments = client.get_deployments().await?; for deployment in &deployments { println!("Deployment: {} (commit: {})", deployment.id, deployment.commit); } // Deploy new reference let transaction_id = client.start_transaction("deploy").await?; let success = client.deploy(&transaction_id, "debian/13/x86_64").await?; Ok(()) } ``` ## Daemon Integration ### Service Configuration The daemon runs as a systemd service with D-Bus activation: ```ini [Unit] Description=apt-ostree System Management Daemon Type=dbus BusName=org.projectatomic.aptostree1 [Service] ExecStart=+apt-ostree start-daemon User=apt-ostree DynamicUser=yes ``` ### D-Bus Interface Implementation The daemon implements the same interface that clients connect to: ```rust #[interface(name = "org.projectatomic.aptostree1")] impl DaemonDBus { fn start_transaction(&self, transaction_type: &str) -> zbus::fdo::Result; fn upgrade(&self, transaction_id: &str) -> zbus::fdo::Result; // ... other methods } ``` ## Security Model ### Authentication - **Polkit integration**: Privileged operations require authentication - **User isolation**: Daemon runs as dedicated user - **Capability management**: Limited system access ### Authorization - **Transaction validation**: All operations go through transaction system - **Resource limits**: Prevents resource exhaustion - **Audit logging**: Operation logging ## Testing ### Unit Tests ```rust #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_client_connection() { let config = ClientConfig::default(); let mut client = ClientDBus::new(config); // Test connection assert!(client.connect().await.is_ok()); } } ``` ### Integration Tests ```bash # Test D-Bus communication ./scripts/simple-dbus-test.sh # Python-based testing ./scripts/test-dbus-python.py ``` ## Configuration ### Environment Variables - `DBUS_SESSION_BUS_ADDRESS`: D-Bus session bus address - `DBUS_SYSTEM_BUS_ADDRESS`: D-Bus system bus address - `RUST_LOG`: Logging level for debugging ### Configuration Files ```toml # apt-ostreed.conf [Daemon] DbusName = "org.projectatomic.aptostree1" DbusPath = "/org/projectatomic/aptostree1" TransactionTimeout = 300 MaxConcurrentTransactions = 1 ``` ## Performance Considerations ### Connection Pooling - **Persistent connections**: Reuse D-Bus connections - **Connection limits**: Prevent connection exhaustion - **Timeout management**: Handle slow operations gracefully ### Transaction Optimization - **Batch operations**: Group related operations - **Async processing**: Non-blocking operation handling - **Resource cleanup**: Cleanup of completed transactions ## Troubleshooting ### Common Issues #### 1. Connection Failures ```bash # Check daemon status systemctl status apt-ostreed # Verify D-Bus service registration busctl --system list | grep aptostree ``` #### 2. Permission Errors ```bash # Check Polkit policies ls -la /usr/share/polkit-1/actions/org.projectatomic.aptostree1.policy # Verify user permissions id apt-ostree ``` #### 3. Transaction Failures ```bash # Check transaction logs journalctl -u apt-ostreed -f # Verify transaction state apt-ostree transaction status ``` ### Debug Mode Enable detailed logging: ```bash RUST_LOG=debug apt-ostree start-daemon ``` ## Future Enhancements ### Planned Features - **Real-time notifications**: Signal-based status updates - **Transaction queuing**: Multiple concurrent transactions - **Performance monitoring**: Metrics and profiling - **Plugin system**: Extensible daemon capabilities ### Integration Goals - **Systemd integration**: Native systemd support - **Container support**: Kubernetes and Docker integration - **Monitoring**: Prometheus metrics export - **Security**: Enhanced authentication and authorization ## Conclusion The D-Bus infrastructure in apt-ostree provides a foundation for client-daemon communication. With error handling, async support, and strong typing, it enables system management operations while maintaining security and performance. The infrastructure is designed to be extensible, allowing for future enhancements while maintaining backward compatibility and stability.