diff --git a/core/locales/i18n.yaml b/core/locales/i18n.yaml index f1ba7dbe4..c26e0c5fe 100644 --- a/core/locales/i18n.yaml +++ b/core/locales/i18n.yaml @@ -1721,6 +1721,14 @@ lxc.mod.cleaned-up-containers: fr_FR: "Conteneurs LXC orphelins nettoyés avec succès" pl_PL: "Pomyślnie wyczyszczono wiszące kontenery LXC" +# version/v0_3_6_alpha_0.rs +migration.migrating-package: + en_US: "Migrating package %{package}..." + de_DE: "Paket %{package} wird migriert..." + es_ES: "Migrando paquete %{package}..." + fr_FR: "Migration du paquet %{package}..." + pl_PL: "Migracja pakietu %{package}..." + # registry/admin.rs registry.admin.unknown-signer: en_US: "Unknown signer" diff --git a/core/src/version/v0_3_6_alpha_0.rs b/core/src/version/v0_3_6_alpha_0.rs index c924a50a0..221ba249e 100644 --- a/core/src/version/v0_3_6_alpha_0.rs +++ b/core/src/version/v0_3_6_alpha_0.rs @@ -27,6 +27,7 @@ use crate::net::keys::KeyStore; use crate::notifications::Notifications; use crate::prelude::*; use crate::s9pk::merkle_archive::source::multi_cursor_file::MultiCursorFile; +use crate::s9pk::v2::pack::CONTAINER_TOOL; use crate::ssh::{SshKeys, SshPubKey}; use crate::util::Invoke; use crate::util::serde::Pem; @@ -326,7 +327,41 @@ impl VersionT for Version { .await?; } + // Load bundled migration images (start9/compat, start9/utils, + // tonistiigi/binfmt) so the v1->v2 s9pk conversion doesn't need + // internet access. + let migration_images_dir = Path::new("/usr/lib/startos/migration-images"); + if let Ok(mut entries) = tokio::fs::read_dir(migration_images_dir).await { + while let Some(entry) = entries.next_entry().await? { + let path = entry.path(); + if path.extension() == Some(OsStr::new("tar")) { + tracing::info!("Loading migration image: {}", path.display()); + Command::new(*CONTAINER_TOOL) + .arg("load") + .arg("-i") + .arg(&path) + .invoke(crate::ErrorKind::Docker) + .await?; + } + } + } + // Should be the name of the package + let current_package: std::sync::Arc>> = + std::sync::Arc::new(tokio::sync::watch::channel(None).0); + let progress_logger = { + let current_package = current_package.clone(); + tokio::spawn(async move { + let mut interval = tokio::time::interval(std::time::Duration::from_secs(30)); + interval.tick().await; // skip immediate first tick + loop { + interval.tick().await; + if let Some(ref id) = *current_package.borrow() { + tracing::info!("{}", t!("migration.migrating-package", package = id.to_string())); + } + } + }) + }; let mut paths = tokio::fs::read_dir(path).await?; while let Some(path) = paths.next_entry().await? { let Ok(id) = path.file_name().to_string_lossy().parse::() else { @@ -367,6 +402,9 @@ impl VersionT for Version { false }; + tracing::info!("{}", t!("migration.migrating-package", package = id.to_string())); + current_package.send_replace(Some(id.clone())); + if let Err(e) = async { let package_s9pk = tokio::fs::File::open(path).await?; let file = MultiCursorFile::open(&package_s9pk).await?; @@ -411,6 +449,7 @@ impl VersionT for Version { } } } + progress_logger.abort(); Ok(()) } }