apt-ostree/docs/apt-ostree-daemon-plan/dbus.md
robojerk 306a68b89a fix: Resolve compilation errors in parallel and cache modules
- 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
2025-08-16 15:10:00 -07:00

17 KiB

🔌 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

<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

<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
<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
<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
<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
<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

<method name="Start">
  <arg type="b" name="started" direction="out"/>
</method>

<method name="Cancel">
  <!-- Cancel active transaction -->
</method>

Progress Monitoring Signals

<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

<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

<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

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

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

<!-- 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

<!-- 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

<!-- 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

[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.