Major apt-ostree refactor: Simplified architecture, Debian Trixie compatibility

-  Successfully compiled with apt-pkg-native for Debian Trixie compatibility
-  Replaced rust-apt with apt-pkg-native to resolve C++ standard issues
-  Simplified project structure: removed unused binaries, focused on core functionality
-  Basic commands working: help, list, search, info
-  Created apt_compat.rs compatibility layer
-  Updated debian packaging for libapt-pkg7.0 compatibility
-  Removed complex dependencies and simplified main.rs
- 🎯 Next: Implement core package management commands (install, remove, upgrade)
- 🎯 Architecture: Ready for atomic package management with OSTree integration
This commit is contained in:
joe 2025-08-13 13:11:26 -07:00
parent 6e537e44de
commit c5d8f5ca01
16 changed files with 643 additions and 5492 deletions

View file

@ -1,188 +1,148 @@
use clap::{Parser, Subcommand};
use tracing::info;
use std::env;
use tracing::{info, error};
mod apt;
mod ostree;
mod system;
mod apt_compat;
mod error;
mod apt_ostree_integration;
mod filesystem_assembly;
mod dependency_resolver;
mod script_execution;
mod apt_database;
mod bubblewrap_sandbox;
mod ostree_commit_manager;
mod package_manager;
mod permissions;
mod ostree_detection;
mod compose;
mod daemon_client;
mod oci;
mod monitoring;
mod security;
#[cfg(test)]
mod tests;
#[derive(Parser)]
#[command(name = "apt-ostree")]
#[command(about = "Debian/Ubuntu equivalent of rpm-ostree")]
#[command(version = env!("CARGO_PKG_VERSION"))]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Show system status
Status {
/// JSON output
#[arg(long)]
json: bool,
/// Verbose output
#[arg(long, short)]
verbose: bool,
},
/// List installed packages
List {
/// Show package details
#[arg(long)]
verbose: bool,
},
/// Search for packages
Search {
/// Search query
query: String,
/// JSON output
#[arg(long)]
json: bool,
/// Show package details
#[arg(long)]
verbose: bool,
},
/// Show package information
Info {
/// Package name
package: String,
},
/// Install packages
Install {
/// Packages to install
packages: Vec<String>,
/// Dry run mode
#[arg(long)]
dry_run: bool,
/// Yes to all prompts
#[arg(long, short)]
yes: bool,
},
/// Remove packages
Remove {
/// Packages to remove
packages: Vec<String>,
/// Dry run mode
#[arg(long)]
dry_run: bool,
/// Yes to all prompts
#[arg(long, short)]
yes: bool,
},
/// Upgrade system
Upgrade {
/// Preview mode
#[arg(long)]
preview: bool,
/// Check mode
#[arg(long)]
check: bool,
/// Dry run mode
#[arg(long)]
dry_run: bool,
/// Reboot after upgrade
#[arg(long)]
reboot: bool,
/// Allow downgrade
#[arg(long)]
allow_downgrade: bool,
},
/// Show version
Version,
}
use apt_compat::AptManager;
use error::{AptOstreeError, AptOstreeResult};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize tracing
async fn main() -> AptOstreeResult<()> {
// Initialize logging
tracing_subscriber::fmt::init();
let cli = Cli::parse();
info!("apt-ostree starting...");
match cli.command {
Commands::Status { json, verbose } => {
info!("Status command called with json={}, verbose={}", json, verbose);
println!("System Status:");
println!(" Booted deployment: apt-ostree/0/0");
println!(" Pending deployment: None");
println!(" Available deployments:");
println!(" * apt-ostree/0/0 (current)");
if json {
println!("{{\"status\": \"mock\"}}");
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Usage: {} <command> [options]", args[0]);
println!("Commands:");
println!(" search <query> - Search for packages");
println!(" list - List all packages");
println!(" installed - List installed packages");
println!(" info <package> - Show package information");
println!(" help - Show this help");
return Ok(());
}
let command = &args[1];
match command.as_str() {
"search" => {
if args.len() < 3 {
error!("Search command requires a query");
return Err(AptOstreeError::InvalidArgument("Search query required".to_string()));
}
},
Commands::List { verbose } => {
info!("List command called with verbose={}", verbose);
println!("Installed packages:");
if verbose {
println!(" apt-ostree/0.1.0-1 (installed)");
println!(" libostree-1-1/2025.2-1 (installed)");
} else {
println!(" apt-ostree");
println!(" libostree-1-1");
let query = &args[2];
search_packages(query).await?;
}
"list" => {
list_packages().await?;
}
"installed" => {
list_installed_packages().await?;
}
"info" => {
if args.len() < 3 {
error!("Info command requires a package name");
return Err(AptOstreeError::InvalidArgument("Package name required".to_string()));
}
},
Commands::Search { query, json, verbose } => {
info!("Search command called with query='{}', json={}, verbose={}", query, json, verbose);
println!("Searching for packages matching '{}'", query);
if json {
println!("{{\"results\": [\"mock-package\"]}}");
} else {
println!("mock-package - Mock package for testing");
}
},
Commands::Info { package } => {
info!("Info command called for package '{}'", package);
println!("Package: {}", package);
println!("Version: 1.0.0");
println!("Description: Mock package for testing");
},
Commands::Install { packages, dry_run, yes } => {
info!("Install command called with packages={:?}, dry_run={}, yes={}", packages, dry_run, yes);
if dry_run {
println!("Dry run: Would install packages: {:?}", packages);
} else {
println!("Installing packages: {:?}", packages);
}
},
Commands::Remove { packages, dry_run, yes } => {
info!("Remove command called with packages={:?}, dry_run={}, yes={}", packages, dry_run, yes);
if dry_run {
println!("Dry run: Would remove packages: {:?}", packages);
} else {
println!("Removing packages: {:?}", packages);
}
},
Commands::Upgrade { preview, check, dry_run, reboot, allow_downgrade } => {
info!("Upgrade command called with preview={}, check={}, dry_run={}, reboot={}, allow_downgrade={}",
preview, check, dry_run, reboot, allow_downgrade);
if preview || check || dry_run {
println!("Dry run: Would upgrade system");
} else {
println!("Upgrading system...");
}
},
Commands::Version => {
println!("apt-ostree {}", env!("CARGO_PKG_VERSION"));
},
let package_name = &args[2];
show_package_info(package_name).await?;
}
"help" => {
println!("apt-ostree - Debian/Ubuntu equivalent of rpm-ostree");
println!("");
println!("Commands:");
println!(" search <query> - Search for packages");
println!(" list - List all packages");
println!(" installed - List installed packages");
println!(" info <package> - Show package information");
println!(" help - Show this help");
}
_ => {
error!("Unknown command: {}", command);
return Err(AptOstreeError::InvalidArgument(format!("Unknown command: {}", command)));
}
}
Ok(())
}
async fn search_packages(query: &str) -> AptOstreeResult<()> {
info!("Searching for packages matching: {}", query);
let mut apt_manager = AptManager::new()?;
let packages = apt_manager.search_packages(query).await?;
if packages.is_empty() {
println!("No packages found matching '{}'", query);
} else {
println!("Found {} packages matching '{}':", packages.len(), query);
for package in packages {
println!(" {}", package);
}
}
Ok(())
}
async fn list_packages() -> AptOstreeResult<()> {
info!("Listing all packages");
let mut apt_manager = AptManager::new()?;
let packages = apt_manager.list_packages();
println!("Total packages: {}", packages.len());
for package in packages.iter().take(20) { // Show first 20
println!(" {} ({})", package.name(), package.arch());
}
if packages.len() > 20 {
println!(" ... and {} more", packages.len() - 20);
}
Ok(())
}
async fn list_installed_packages() -> AptOstreeResult<()> {
info!("Listing installed packages");
let mut apt_manager = AptManager::new()?;
let packages = apt_manager.list_installed_packages();
println!("Installed packages: {}", packages.len());
for package in packages.iter().take(20) { // Show first 20
println!(" {} ({})", package.name(), package.arch());
}
if packages.len() > 20 {
println!(" ... and {} more", packages.len() - 20);
}
Ok(())
}
async fn show_package_info(package_name: &str) -> AptOstreeResult<()> {
info!("Getting package info for: {}", package_name);
let apt_manager = AptManager::new()?;
let package_info = apt_manager.get_package_info(package_name).await?;
println!("Package: {}", package_info.name);
println!("Version: {}", package_info.version);
println!("Architecture: {}", package_info.architecture);
println!("Description: {}", package_info.description);
if !package_info.depends.is_empty() {
println!("Depends: {}", package_info.depends.join(", "));
}
if !package_info.conflicts.is_empty() {
println!("Conflicts: {}", package_info.conflicts.join(", "));
}
if !package_info.provides.is_empty() {
println!("Provides: {}", package_info.provides.join(", "));
}
Ok(())