- Fix compilation errors in src/main.rs and resolve import conflicts - Add debian/compat file and ensure debian/rules is executable - Downgrade Cargo.lock to version 3 for compatibility with system cargo - Create working apt-ostree binary with basic CLI functionality - Build apt-ostree_0.1.0-1_amd64.deb package (1.1MB) - Package installs successfully and binary works correctly - Ensure libostree-1-1 (>= 2025.2) dependency for bootc compatibility - Test package installation and basic commands (status, version)
163 lines
No EOL
6.1 KiB
Rust
163 lines
No EOL
6.1 KiB
Rust
use zbus::{Connection, Proxy};
|
|
use std::error::Error;
|
|
|
|
/// Daemon client for communicating with apt-ostreed
|
|
pub struct DaemonClient {
|
|
connection: Connection,
|
|
proxy: Proxy<'static>,
|
|
}
|
|
|
|
impl DaemonClient {
|
|
/// Create a new daemon client
|
|
pub async fn new() -> Result<Self, Box<dyn Error>> {
|
|
let connection = Connection::system().await?;
|
|
let proxy = Proxy::new(
|
|
&connection,
|
|
"org.aptostree.dev",
|
|
"/org/aptostree/dev/Daemon",
|
|
"org.aptostree.dev.Daemon"
|
|
).await?;
|
|
|
|
Ok(Self { connection, proxy })
|
|
}
|
|
|
|
/// Ping the daemon
|
|
pub async fn ping(&self) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Ping", &()).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Get system status
|
|
pub async fn status(&self) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Status", &()).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Install packages
|
|
pub async fn install_packages(&self, packages: Vec<String>, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("InstallPackages", &(packages, yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Remove packages
|
|
pub async fn remove_packages(&self, packages: Vec<String>, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("RemovePackages", &(packages, yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Upgrade system
|
|
pub async fn upgrade_system(&self, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("UpgradeSystem", &(yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Rollback system
|
|
pub async fn rollback(&self, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Rollback", &(yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// List packages
|
|
pub async fn list_packages(&self) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("ListPackages", &()).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Search packages
|
|
pub async fn search_packages(&self, query: String, verbose: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("SearchPackages", &(query, verbose)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Show package info
|
|
pub async fn show_package_info(&self, package: String) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("ShowPackageInfo", &(package)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Show history
|
|
pub async fn show_history(&self, verbose: bool, limit: u32) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("ShowHistory", &(verbose, limit)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Checkout to different branch/commit
|
|
pub async fn checkout(&self, target: String, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Checkout", &(target, yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Prune deployments
|
|
pub async fn prune_deployments(&self, keep: u32, yes: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("PruneDeployments", &(keep, yes, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Initialize system
|
|
pub async fn initialize(&self, branch: String) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Initialize", &(branch)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Deploy a specific commit
|
|
pub async fn deploy(&self, commit: String, reboot: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Deploy", &(commit, reboot, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Enhanced rollback with OSTree integration
|
|
pub async fn rollback_enhanced(&self, reboot: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("RollbackEnhanced", &(reboot, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Enhanced upgrade with OSTree integration
|
|
pub async fn upgrade_enhanced(&self, reboot: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("UpgradeEnhanced", &(reboot, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Reset to base deployment
|
|
pub async fn reset(&self, reboot: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Reset", &(reboot, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Rebase to different tree
|
|
pub async fn rebase(&self, refspec: String, reboot: bool, allow_downgrade: bool, skip_purge: bool, dry_run: bool) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("Rebase", &(refspec, reboot, allow_downgrade, skip_purge, dry_run)).await?;
|
|
Ok(reply)
|
|
}
|
|
|
|
/// Reload configuration
|
|
pub async fn reload_configuration(&self) -> Result<String, Box<dyn Error>> {
|
|
let reply: String = self.proxy.call("ReloadConfiguration", &()).await?;
|
|
Ok(reply)
|
|
}
|
|
}
|
|
|
|
/// Helper function to call daemon with fallback to client
|
|
pub async fn call_daemon_with_fallback<F, T>(
|
|
daemon_call: F,
|
|
client_fallback: T,
|
|
) -> Result<String, Box<dyn Error>>
|
|
where
|
|
F: FnOnce(&DaemonClient) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<String, Box<dyn Error>>> + Send>>,
|
|
T: FnOnce() -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<String, Box<dyn Error>>> + Send>>,
|
|
{
|
|
match DaemonClient::new().await {
|
|
Ok(client) => {
|
|
match daemon_call(&client).await {
|
|
Ok(result) => Ok(result),
|
|
Err(e) => {
|
|
eprintln!("Warning: Daemon call failed: {}. Falling back to client...", e);
|
|
client_fallback().await
|
|
}
|
|
}
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Warning: Could not connect to daemon: {}. Falling back to client...", e);
|
|
client_fallback().await
|
|
}
|
|
}
|
|
}
|