Fix YAML linting issues and update system requirements to Debian 13+

- Fix trailing spaces and blank lines in Forgejo workflows
- Update system requirements from Ubuntu Jammy/Bookworm to Debian 13+ (Trixie)
- Update test treefile to use Debian Trixie instead of Ubuntu Jammy
- Update documentation to reflect modern system requirements
- Fix yamllint errors for CI/CD functionality
- Ensure compatibility with modern OSTree and libapt versions
This commit is contained in:
robojerk 2025-08-18 11:39:58 -07:00
parent ec0da91864
commit 3dec23f8f7
85 changed files with 12569 additions and 1088 deletions

View file

@ -3,7 +3,7 @@
use crate::daemon::{DaemonResult, DaemonError};
use std::process::Command;
use std::path::Path;
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
/// Package information
@ -21,6 +21,7 @@ pub struct PackageInfo {
}
/// APT manager for the daemon
#[allow(dead_code)]
pub struct AptManager {
cache_dir: String,
cache_updated: bool,
@ -220,20 +221,20 @@ impl AptManager {
};
for line in output.lines() {
if line.starts_with("Version: ") {
info.version = line[9..].trim().to_string();
} else if line.starts_with("Description: ") {
info.description = line[13..].trim().to_string();
} else if line.starts_with("Depends: ") {
info.depends = line[9..].split(", ").map(|s| s.trim().to_string()).collect();
} else if line.starts_with("Conflicts: ") {
info.conflicts = line[11..].split(", ").map(|s| s.trim().to_string()).collect();
} else if line.starts_with("Provides: ") {
info.provides = line[10..].split(", ").map(|s| s.trim().to_string()).collect();
} else if line.starts_with("Priority: ") {
info.priority = line[10..].trim().to_string();
} else if line.starts_with("Section: ") {
info.section = line[9..].trim().to_string();
if let Some(version) = line.strip_prefix("Version: ") {
info.version = version.trim().to_string();
} else if let Some(description) = line.strip_prefix("Description: ") {
info.description = description.trim().to_string();
} else if let Some(depends) = line.strip_prefix("Depends: ") {
info.depends = depends.split(", ").map(|s| s.trim().to_string()).collect();
} else if let Some(conflicts) = line.strip_prefix("Conflicts: ") {
info.conflicts = conflicts.split(", ").map(|s| s.trim().to_string()).collect();
} else if let Some(provides) = line.strip_prefix("Provides: ") {
info.provides = provides.split(", ").map(|s| s.trim().to_string()).collect();
} else if let Some(priority) = line.strip_prefix("Priority: ") {
info.priority = priority.trim().to_string();
} else if let Some(section) = line.strip_prefix("Section: ") {
info.section = section.trim().to_string();
}
}
@ -279,8 +280,8 @@ impl AptManager {
let mut deps = Vec::new();
for line in output_str.lines() {
if line.starts_with(" Depends: ") {
let dep = line[11..].trim().to_string();
if let Some(dep) = line.strip_prefix(" Depends: ") {
let dep = dep.trim().to_string();
if let Some(clean_dep) = dep.split_whitespace().next() {
deps.push(clean_dep.to_string());
}

View file

@ -1,16 +1,18 @@
//! DBus interface implementation for apt-ostree daemon
use zbus::{dbus_interface, fdo};
use zbus::{fdo, interface};
use crate::daemon::{
DaemonConfig, DaemonResult, DaemonError,
TransactionManager, TransactionType, TransactionState,
TransactionManager, TransactionType,
OstreeManager, AptManager, SecurityManager, SysrootManager, OsManager,
};
use std::sync::Arc;
use tokio::sync::RwLock;
use std::collections::HashMap;
/// DBus interface for apt-ostree daemon
#[allow(dead_code, clippy::new_without_default)]
pub struct DaemonDBus {
config: DaemonConfig,
transaction_manager: Arc<RwLock<TransactionManager>>,
@ -42,7 +44,9 @@ impl DaemonDBus {
}
}
#[dbus_interface(name = "org.projectatomic.aptostree1")]
#[interface(name = "org.projectatomic.aptostree1")]
impl DaemonDBus {
/// Get daemon version
async fn get_version(&self) -> fdo::Result<String> {

363
src/daemon/dbus_new.rs Normal file
View file

@ -0,0 +1,363 @@
//! DBus interface implementation for apt-ostree daemon
//! Following the rpm-ostree DBus interface specification
use zbus::{dbus_interface, fdo};
use crate::daemon::{
DaemonConfig, DaemonResult, DaemonError,
TransactionManager, TransactionType, TransactionState,
OstreeManager, AptManager, SecurityManager, SysrootManager, OsManager,
};
use std::sync::Arc;
use tokio::sync::RwLock;
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
/// DBus interface for apt-ostree daemon
pub struct DaemonDBus {
config: DaemonConfig,
transaction_manager: Arc<RwLock<TransactionManager>>,
ostree_manager: Arc<RwLock<OstreeManager>>,
apt_manager: Arc<RwLock<AptManager>>,
security_manager: Arc<RwLock<SecurityManager>>,
sysroot_manager: Arc<RwLock<SysrootManager>>,
os_manager: Arc<RwLock<OsManager>>,
}
impl DaemonDBus {
pub fn new(config: DaemonConfig) -> DaemonResult<Self> {
let transaction_manager = Arc::new(RwLock::new(TransactionManager::new()));
let ostree_manager = Arc::new(RwLock::new(OstreeManager::new(&config.ostree_sysroot)?));
let apt_manager = Arc::new(RwLock::new(AptManager::new(&config.apt_cache_dir)?));
let security_manager = Arc::new(RwLock::new(SecurityManager::new()));
let sysroot_manager = Arc::new(RwLock::new(SysrootManager::new(&config.ostree_sysroot)?));
let os_manager = Arc::new(RwLock::new(OsManager::new()?));
Ok(Self {
config,
transaction_manager,
ostree_manager,
apt_manager,
security_manager,
sysroot_manager,
os_manager,
})
}
}
/// Deployment metadata structure
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeploymentMetadata {
pub id: String,
pub commit: String,
pub timestamp: String,
pub origin: String,
pub booted: bool,
pub staged: bool,
pub pending: bool,
pub rollback: bool,
}
/// Transaction options structure
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransactionOptions {
pub reboot: Option<bool>,
pub allow_downgrade: Option<bool>,
pub dry_run: Option<bool>,
pub lock_finalization: Option<bool>,
}
/// Sysroot Interface - Root interface for system operations
#[dbus_interface(name = "org.projectatomic.aptostree1.Sysroot")]
impl DaemonDBus {
/// Get currently booted OS object path
#[dbus_interface(property)]
async fn booted(&self) -> fdo::Result<String> {
// TODO: Implement real booted OS detection
Ok("/org/projectatomic/aptostree1/OS/default".to_string())
}
/// Get system root path
#[dbus_interface(property)]
async fn path(&self) -> fdo::Result<String> {
Ok("/".to_string())
}
/// Get active transaction information
#[dbus_interface(property)]
async fn active_transaction(&self) -> fdo::Result<(String, String, String)> {
// TODO: Implement real active transaction tracking
Ok(("none".to_string(), "none".to_string(), "none".to_string()))
}
/// Get active transaction path
#[dbus_interface(property)]
async fn active_transaction_path(&self) -> fdo::Result<String> {
// TODO: Implement real active transaction path
Ok("/".to_string())
}
/// Get all deployments
#[dbus_interface(property)]
async fn deployments(&self) -> fdo::Result<Vec<HashMap<String, zbus::zvariant::Value>>> {
// TODO: Implement real deployment listing
let mut deployments = Vec::new();
let mut deployment = HashMap::new();
deployment.insert("id".to_string(), zbus::zvariant::Value::Str("default".to_string()));
deployment.insert("commit".to_string(), zbus::zvariant::Value::Str("unknown".to_string()));
deployment.insert("booted".to_string(), zbus::zvariant::Value::Bool(true));
deployments.push(deployment);
Ok(deployments)
}
/// Get automatic update policy
#[dbus_interface(property)]
async fn automatic_update_policy(&self) -> fdo::Result<String> {
Ok("none".to_string())
}
/// Register a client
async fn register_client(&self, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<()> {
// TODO: Implement real client registration
tracing::info!("Client registered with options: {:?}", options);
Ok(())
}
/// Unregister a client
async fn unregister_client(&self, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<()> {
// TODO: Implement real client unregistration
tracing::info!("Client unregistered with options: {:?}", options);
Ok(())
}
/// Reload sysroot
async fn reload(&self) -> fdo::Result<()> {
// TODO: Implement real sysroot reload
tracing::info!("Reloading sysroot");
Ok(())
}
/// Reload configuration
async fn reload_config(&self) -> fdo::Result<()> {
// TODO: Implement real configuration reload
tracing::info!("Reloading configuration");
Ok(())
}
/// Get OS object by name
async fn get_os(&self, name: String) -> fdo::Result<String> {
// TODO: Implement real OS object retrieval
Ok("/org/projectatomic/aptostree1/OS/default".to_string())
}
}
/// OS Interface - Operating system operations
#[dbus_interface(name = "org.projectatomic.aptostree1.OS")]
impl DaemonDBus {
/// Get booted deployment
#[dbus_interface(property)]
async fn booted_deployment(&self) -> fdo::Result<HashMap<String, zbus::zvariant::Value>> {
// TODO: Implement real booted deployment detection
let mut deployment = HashMap::new();
deployment.insert("id".to_string(), zbus::zvariant::Value::Str("default".to_string()));
deployment.insert("commit".to_string(), zbus::zvariant::Value::Str("unknown".to_string()));
deployment.insert("booted".to_string(), zbus::zvariant::Value::Bool(true));
Ok(deployment)
}
/// Get default deployment
#[dbus_interface(property)]
async fn default_deployment(&self) -> fdo::Result<HashMap<String, zbus::zvariant::Value>> {
// TODO: Implement real default deployment detection
let mut deployment = HashMap::new();
deployment.insert("id".to_string(), zbus::zvariant::Value::Str("default".to_string()));
deployment.insert("commit".to_string(), zbus::zvariant::Value::Str("unknown".to_string()));
Ok(deployment)
}
/// Get rollback deployment
#[dbus_interface(property)]
async fn rollback_deployment(&self) -> fdo::Result<HashMap<String, zbus::zvariant::Value>> {
// TODO: Implement real rollback deployment detection
Ok(HashMap::new())
}
/// Get cached update information
#[dbus_interface(property)]
async fn cached_update(&self) -> fdo::Result<HashMap<String, zbus::zvariant::Value>> {
// TODO: Implement real cached update detection
Ok(HashMap::new())
}
/// Check if cached update has RPM diff
#[dbus_interface(property)]
async fn has_cached_update_rpm_diff(&self) -> fdo::Result<bool> {
// TODO: Implement real cached update RPM diff detection
Ok(false)
}
/// Get OS name
#[dbus_interface(property)]
async fn name(&self) -> fdo::Result<String> {
Ok("default".to_string())
}
/// Deploy a specific revision
async fn deploy(&self, revision: String, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real deployment logic
tracing::info!("Deploying revision: {} with options: {:?}", revision, options);
Ok("transaction_123".to_string())
}
/// Upgrade the system
async fn upgrade(&self, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real upgrade logic
tracing::info!("Upgrading system with options: {:?}", options);
Ok("transaction_456".to_string())
}
/// Rollback the system
async fn rollback(&self, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real rollback logic
tracing::info!("Rolling back system with options: {:?}", options);
Ok("transaction_789".to_string())
}
/// Rebase to a different reference
async fn rebase(&self, refspec: String, packages: Vec<String>, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real rebase logic
tracing::info!("Rebasing to refspec: {} with packages: {:?} and options: {:?}", refspec, packages, options);
Ok("transaction_rebase".to_string())
}
/// Change packages (install/remove)
async fn pkg_change(&self, options: HashMap<String, zbus::zvariant::Value>, packages_added: Vec<String>, packages_removed: Vec<String>) -> fdo::Result<String> {
// TODO: Implement real package change logic
tracing::info!("Changing packages - added: {:?}, removed: {:?}, options: {:?}", packages_added, packages_removed, options);
Ok("transaction_pkg_change".to_string())
}
/// Set initramfs state
async fn set_initramfs_state(&self, regenerate: bool, args: Vec<String>, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real initramfs state setting
tracing::info!("Setting initramfs state - regenerate: {}, args: {:?}, options: {:?}", regenerate, args, options);
Ok("transaction_initramfs".to_string())
}
/// Modify kernel arguments
async fn kernel_args(&self, existing_args: String, args_added: Vec<String>, args_replaced: Vec<String>, args_removed: Vec<String>, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real kernel argument modification
tracing::info!("Modifying kernel args - existing: {}, added: {:?}, replaced: {:?}, removed: {:?}, options: {:?}",
existing_args, args_added, args_replaced, args_removed, options);
Ok("transaction_kargs".to_string())
}
/// Cleanup operations
async fn cleanup(&self, operations: Vec<String>) -> fdo::Result<String> {
// TODO: Implement real cleanup logic
tracing::info!("Cleaning up operations: {:?}", operations);
Ok("transaction_cleanup".to_string())
}
/// Refresh metadata
async fn refresh_md(&self, options: HashMap<String, zbus::zvariant::Value>) -> fdo::Result<String> {
// TODO: Implement real metadata refresh
tracing::info!("Refreshing metadata with options: {:?}", options);
Ok("transaction_refresh_md".to_string())
}
/// Get packages information
async fn get_packages(&self, packages: Vec<String>) -> fdo::Result<Vec<HashMap<String, zbus::zvariant::Value>>> {
// TODO: Implement real package information retrieval
tracing::info!("Getting packages information: {:?}", packages);
let mut result = Vec::new();
for package in packages {
let mut pkg_info = HashMap::new();
pkg_info.insert("name".to_string(), zbus::zvariant::Value::Str(package));
pkg_info.insert("version".to_string(), zbus::zvariant::Value::Str("unknown".to_string()));
result.push(pkg_info);
}
Ok(result)
}
/// Search packages
async fn search(&self, query: Vec<String>) -> fdo::Result<Vec<HashMap<String, zbus::zvariant::Value>>> {
// TODO: Implement real package search
tracing::info!("Searching packages with query: {:?}", query);
let mut result = Vec::new();
let mut pkg_info = HashMap::new();
pkg_info.insert("name".to_string(), zbus::zvariant::Value::Str("example-package".to_string()));
pkg_info.insert("description".to_string(), zbus::zvariant::Value::Str("Example package".to_string()));
result.push(pkg_info);
Ok(result)
}
}
/// Transaction Interface - Transaction management
#[dbus_interface(name = "org.projectatomic.aptostree1.Transaction")]
impl DaemonDBus {
/// Get transaction title
#[dbus_interface(property)]
async fn title(&self) -> fdo::Result<String> {
// TODO: Implement real transaction title retrieval
Ok("Transaction".to_string())
}
/// Get initiating client description
#[dbus_interface(property)]
async fn initiating_client_description(&self) -> fdo::Result<String> {
// TODO: Implement real client description retrieval
Ok("apt-ostree client".to_string())
}
/// Cancel the transaction
async fn cancel(&self) -> fdo::Result<bool> {
// TODO: Implement real transaction cancellation
tracing::info!("Cancelling transaction");
Ok(true)
}
/// Start the transaction
async fn start(&self) -> fdo::Result<bool> {
// TODO: Implement real transaction start
tracing::info!("Starting transaction");
Ok(true)
}
/// Signal: Transaction finished
#[dbus_interface(signal)]
async fn finished(&self, success: bool, message: String) -> zbus::Result<()>;
/// Signal: Transaction message
#[dbus_interface(signal)]
async fn message(&self, message: String) -> zbus::Result<()>;
/// Signal: Task begin
#[dbus_interface(signal)]
async fn task_begin(&self, task_name: String) -> zbus::Result<()>;
/// Signal: Task end
#[dbus_interface(signal)]
async fn task_end(&self, task_name: String) -> zbus::Result<()>;
/// Signal: Progress percentage
#[dbus_interface(signal)]
async fn percent_progress(&self, task_name: String, percentage: u32) -> zbus::Result<()>;
/// Signal: Progress end
#[dbus_interface(signal)]
async fn progress_end(&self) -> zbus::Result<()>;
}
impl TransactionType {
fn from_str(s: &str) -> Result<Self, DaemonError> {
match s {
"install" => Ok(TransactionType::Install),
"remove" => Ok(TransactionType::Remove),
"upgrade" => Ok(TransactionType::Upgrade),
"rollback" => Ok(TransactionType::Rollback),
"deploy" => Ok(TransactionType::Deploy),
"rebase" => Ok(TransactionType::Rebase),
_ => Err(DaemonError::Configuration(format!("Unknown transaction type: {}", s))),
}
}
}

View file

@ -1,8 +1,9 @@
//! OS interface for apt-ostree daemon
use crate::daemon::{DaemonResult, DaemonError};
use crate::daemon::DaemonResult;
/// OS manager for the daemon
#[allow(dead_code, clippy::new_without_default)]
pub struct OsManager {
// TODO: Add OS-related fields
}
@ -28,3 +29,5 @@ impl OsManager {
Ok("x86_64".to_string())
}
}

View file

@ -397,14 +397,14 @@ impl OstreeManager {
let mut commit_info = HashMap::new();
for line in output.lines() {
if line.starts_with("commit ") {
commit_info.insert("hash".to_string(), line[7..].trim().to_string());
} else if line.starts_with("Author: ") {
commit_info.insert("author".to_string(), line[8..].trim().to_string());
} else if line.starts_with("Date: ") {
commit_info.insert("date".to_string(), line[6..].trim().to_string());
} else if line.starts_with("Subject: ") {
commit_info.insert("subject".to_string(), line[9..].trim().to_string());
if let Some(hash) = line.strip_prefix("commit ") {
commit_info.insert("hash".to_string(), hash.trim().to_string());
} else if let Some(author) = line.strip_prefix("Author: ") {
commit_info.insert("author".to_string(), author.trim().to_string());
} else if let Some(date) = line.strip_prefix("Date: ") {
commit_info.insert("date".to_string(), date.trim().to_string());
} else if let Some(subject) = line.strip_prefix("Subject: ") {
commit_info.insert("subject".to_string(), subject.trim().to_string());
}
}

View file

@ -3,13 +3,14 @@
use crate::daemon::{DaemonResult, DaemonError};
/// Security manager for the daemon
#[derive(Default)]
pub struct SecurityManager {
// TODO: Add security-related fields
}
impl SecurityManager {
pub fn new() -> Self {
Self {}
Self::default()
}
pub fn check_authorization(&self, action: &str) -> DaemonResult<bool> {

View file

@ -1,8 +1,9 @@
//! Sysroot management for apt-ostree daemon
use crate::daemon::{DaemonResult, DaemonError};
use crate::daemon::DaemonResult;
/// Sysroot manager for the daemon
#[allow(dead_code, clippy::new_without_default)]
pub struct SysrootManager {
sysroot_path: String,
}
@ -35,3 +36,5 @@ impl SysrootManager {
Ok(())
}
}

View file

@ -125,7 +125,7 @@ impl Transaction {
}
pub fn update_progress(&mut self, progress: f64) -> DaemonResult<()> {
if progress < 0.0 || progress > 1.0 {
if !(0.0..=1.0).contains(&progress) {
return Err(DaemonError::Transaction("Progress must be between 0.0 and 1.0".to_string()));
}
self.progress = progress;
@ -138,6 +138,7 @@ impl Transaction {
}
/// Transaction manager
#[allow(dead_code, clippy::new_without_default)]
pub struct TransactionManager {
transactions: HashMap<String, Transaction>,
next_transaction_id: u64,