use crate::{
api::ApiClient,
config::AppConfig,
database::Database,
upgrade_strategy::{UpgradeStrategy, UpgradeStrategyManager},
};
use anyhow::Result;
use std::{path::PathBuf, sync::Arc};
use tracing::{debug, info};
#[derive(Debug, Clone)]
pub struct UpgradeManager {
config: Arc<AppConfig>,
#[allow(dead_code)]
config_path: PathBuf,
api_client: Arc<ApiClient>,
#[allow(dead_code)]
database: Arc<Database>,
}
#[derive(Debug, Clone, Default)]
pub struct UpgradeOptions {
pub skip_backup: bool,
pub force: bool,
pub use_incremental: bool,
pub backup_dir: Option<PathBuf>,
pub download_only: bool,
}
pub type ProgressCallback = Box<dyn Fn(UpgradeStep, &str) + Send + Sync>;
#[derive(Debug, Clone)]
pub enum UpgradeStep {
CheckingUpdates,
CreatingBackup,
StoppingServices,
DownloadingUpdate,
ExtractingUpdate,
LoadingImages,
StartingServices,
VerifyingServices,
CleaningUp,
Completed,
Failed(String),
}
#[derive(Debug)]
pub struct UpgradeResult {
pub success: bool,
pub from_version: String,
pub to_version: String,
pub error: Option<String>,
pub backup_id: Option<i64>,
}
impl UpgradeManager {
pub fn new(
config: Arc<AppConfig>,
config_path: PathBuf,
api_client: Arc<ApiClient>,
database: Arc<Database>,
) -> Self {
Self {
config,
config_path,
api_client,
database,
}
}
pub async fn check_for_updates(&self, force_full: bool) -> Result<UpgradeStrategy> {
info!("Checking for service updates...");
let current_version = &self.config.get_docker_versions();
debug!("Current version: {}", current_version);
let enhanced_service_manifest = self.api_client.get_enhanced_service_manifest().await?;
let upgrade_strategy_manager = UpgradeStrategyManager::new(
current_version.to_string(),
force_full,
enhanced_service_manifest,
);
let upgrade_strategy: UpgradeStrategy = upgrade_strategy_manager.determine_strategy()?;
Ok(upgrade_strategy)
}
}