diff --git a/.gitignore b/.gitignore index 59f2e84..4a2df44 100644 --- a/.gitignore +++ b/.gitignore @@ -369,4 +369,5 @@ setup-guest-storage.sh query-guest-commands.sh query-guest-state.sh output.resp -.test \ No newline at end of file +.test +.test_handle_config \ No newline at end of file diff --git a/lib/debian/acr-mirror.postinst b/lib/debian/acr-mirror.postinst index c1d350d..911cf28 100644 --- a/lib/debian/acr-mirror.postinst +++ b/lib/debian/acr-mirror.postinst @@ -2,7 +2,7 @@ set -e cd /opt/acr/bin -./acr init +./acr init --min_init #DEBHELPER# diff --git a/src/bin/shared/cli.rs b/src/bin/shared/cli.rs index 949abbd..e5de01c 100644 --- a/src/bin/shared/cli.rs +++ b/src/bin/shared/cli.rs @@ -100,10 +100,10 @@ pub struct MirrorSettings { /// #[clap(long, default_value_t = String::from("azurecr.io"))] pub registry_host: String, - /// If initializing settings, only initialize the hosts.toml file - /// + /// Minimum initialization, + /// #[clap(long, action)] - pub init_hosts_config_only: bool, + pub min_init: bool, /// Root of the current filesystem, /// /// This is usually just `/` however when testing it's useful to specify since root is a privelaged folder. diff --git a/src/bin/shared/commands.rs b/src/bin/shared/commands.rs index 3a9c272..eda20b6 100644 --- a/src/bin/shared/commands.rs +++ b/src/bin/shared/commands.rs @@ -1,14 +1,13 @@ use clap::Subcommand; use lifec::host::HostSettings; use lifec::prelude::*; -use lifec_registry::ContainerdConfig; use lifec_registry::hosts_config::DefaultHost; use lifec_registry::hosts_config::MirrorHost; use lifec_registry::RegistryProxy; -use tracing::error; -use tracing::info; use std::path::PathBuf; use tracing::event; +use tracing::warn; +use tracing::info; use tracing::Level; use super::default_mirror_engine; @@ -114,69 +113,38 @@ impl Commands { teleport_format, registry_host, fs_root, - init_hosts_config_only: hosts_config_only, + min_init, .. }) => { if mirror_runmd.exists() { - event!(Level::WARN, "Overwriting existing file {:?}", mirror_runmd); + warn!("Overwriting existing file {:?}", mirror_runmd); } - - let ctr_config = match ContainerdConfig::try_load(None).await { - Ok(config) => { - config - }, - Err(_) => { - ContainerdConfig::new() - } - }; - - let mut updated = ctr_config.enable_overlaybd_snapshotter().enable_hosts_config(); - updated.format(); - - match updated.try_save().await { - Ok(saved) => { - info!("Wrote containerd config at {:?}", saved) - }, - Err(err) => { - error!("Could not save containerd config, {err}"); - } - } - - let hosts_configs = if let Some(registry) = registry.as_ref() { - vec![MirrorHost::get_hosts_config( - format!("{registry}.{registry_host}"), - mirror_address.to_string(), - true, - Some(teleport_format.to_string()), - )] - } else { - vec![ - DefaultHost::get_hosts_config( - format!("http://{}", mirror_address), + + if !min_init { + lifec_registry::enable_containerd_config().await; + + let host_config = if let Some(registry) = registry.as_ref() { + MirrorHost::get_hosts_config( + format!("{registry}.{registry_host}"), + mirror_address.to_string(), true, - Some(registry_host.to_string()), Some(teleport_format.to_string()), - ), - DefaultHost::get_legacy_supported_hosts_config( - ®istry_host, + ) + } else { + DefaultHost::get_hosts_config( format!("http://{}", mirror_address), true, Some(registry_host.to_string()), Some(teleport_format.to_string()), - ), - ] - }; - - for host_config in hosts_configs { + ) + }; + match host_config.install(fs_root.to_owned()) { Ok(path) => event!(Level::INFO, "Wrote hosts.toml for host, {:?}", path), Err(err) => panic!("Could not write hosts.toml {err}"), } - } - - if hosts_config_only { - event!(Level::INFO, "Skipping .runmd initialization"); - return; + } else { + info!("Minimum initialization enabled. Skipping hosts config & containerd config.") } tokio::fs::write( diff --git a/src/config/containerd_config.rs b/src/config/containerd_config.rs index 80ecacf..f2e4bb5 100644 --- a/src/config/containerd_config.rs +++ b/src/config/containerd_config.rs @@ -1,11 +1,39 @@ use std::{fmt::Display, path::PathBuf}; use toml_edit::{table, value, Document}; +use tracing::{info, error}; use crate::Error; const DEFAULT_CONTAINERD_CONFIG_DIR: &'static str = "etc/containerd/"; +/// Enable containerd config, +/// +/// The containerd config is stored at /etc/containerd/config.toml. To enable a definition is installed for the proxy snapshotter, +/// the hosts config directory is specified, and then the default snapshotter is set. +/// +pub async fn enable_containerd_config() { + // Configure containerd + let ctr_config = match ContainerdConfig::try_load(None).await { + Ok(config) => config, + Err(_) => ContainerdConfig::new(), + }; + + let mut updated = ctr_config + .enable_overlaybd_snapshotter() + .enable_hosts_config(); + updated.format(); + + match updated.try_save().await { + Ok(saved) => { + info!("Wrote containerd config at {:?}", saved) + } + Err(err) => { + error!("Could not save containerd config, {err}"); + } + } +} + /// Pointer struct for handling /etc/containerd/config.toml /// pub struct ContainerdConfig { diff --git a/src/config/mod.rs b/src/config/mod.rs index 7671a8c..ec1a983 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -17,4 +17,5 @@ pub use hosts_config::HostsConfig; pub use hosts_config::Host; mod containerd_config; -pub use containerd_config::ContainerdConfig; \ No newline at end of file +pub use containerd_config::ContainerdConfig; +pub use containerd_config::enable_containerd_config; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index eee76d4..0217ece 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,6 +44,7 @@ pub use config::HostsConfig; pub use config::OAuthConfig; pub use config::BearerChallengeConfig; pub use config::ContainerdConfig; +pub use config::enable_containerd_config; pub mod azure { pub use crate::config::AzureAKSConfig; diff --git a/src/proxy/config.rs b/src/proxy/config.rs index cbc17d8..90ab653 100644 --- a/src/proxy/config.rs +++ b/src/proxy/config.rs @@ -1,19 +1,20 @@ // Imports +use crate::hosts_config::DefaultHost; +use crate::hosts_config::MirrorHost; +use crate::Error; use hyper::Method; -use lifec::state::AttributeIndex; use lifec::prelude::ThunkContext; -use poem::IntoResponse; -use poem::web::Query; -use poem::web::Data; -use poem::handler; +use lifec::state::AttributeIndex; use poem::error::IntoResult; -use serde::Serialize; +use poem::handler; +use poem::web::Data; +use poem::web::Query; +use poem::IntoResponse; use serde::Deserialize; -use tracing::info; -use tracing::error; +use serde::Serialize; use tracing::debug; -use crate::Error; -use crate::hosts_config::MirrorHost; +use tracing::error; +use tracing::info; // Exports mod config_response; @@ -29,10 +30,16 @@ pub struct ConfigRequest { /// Stream format to configure, /// stream_format: Option, + /// Suffix to enable, + /// + enable_suffix: Option, + /// Enable containerd config, + /// + enable_containerd: Option, } /// Handler for /config requests -/// +/// #[handler] pub async fn handle_config( method: Method, @@ -43,10 +50,15 @@ pub async fn handle_config( } /// Handler impl, seperated to test -/// +/// async fn _handle_config( method: Method, - Query(ConfigRequest { ns, stream_format }): Query, + Query(ConfigRequest { + ns, + stream_format, + enable_suffix, + enable_containerd, + }): Query, context: Data<&ThunkContext>, ) -> Result { let app_host = context @@ -54,11 +66,16 @@ async fn _handle_config( .find_symbol("app_host") .unwrap_or("http://localhost:8578".to_string()); - let mirror_hosts_config = MirrorHost::get_hosts_config(&ns, app_host, true, stream_format); + let hosts_config = if ns != "_default" { + MirrorHost::get_hosts_config(&ns, app_host, true, stream_format) + } else { + let suffix = enable_suffix.unwrap_or(String::from("azurecr.io")); + DefaultHost::get_hosts_config(app_host, true, Some(suffix), stream_format) + }; match method { Method::GET => { - if mirror_hosts_config.installed(context.search().find_symbol("sysroot")) { + if hosts_config.installed(context.search().find_symbol("sysroot")) { Ok(ConfigResponse::ok()) } else { Err(Error::recoverable_error("config is not installed")) @@ -67,7 +84,11 @@ async fn _handle_config( Method::PUT => { info!("Configuring namespace {ns}"); - if let Err(err) = mirror_hosts_config.install(context.search().find_symbol("sysroot")) { + if let Some(true) = enable_containerd { + crate::enable_containerd_config().await; + } + + if let Err(err) = hosts_config.install(context.search().find_symbol("sysroot")) { error!("Unable to enable mirror host config for, {}, {:?}", ns, err); Err(Error::system_environment()) } else { @@ -77,7 +98,8 @@ async fn _handle_config( } Method::DELETE => { info!("Deleting config for namespace {ns}"); - if let Err(err) = mirror_hosts_config.uninstall(context.search().find_symbol("sysroot")) { + if let Err(err) = hosts_config.uninstall(context.search().find_symbol("sysroot")) + { error!("Unable to enable mirror host config for, {}, {:?}", ns, err); Err(Error::system_environment()) } else { @@ -121,6 +143,8 @@ mod tests { Query(ConfigRequest { ns: String::from("test.azurecr.io"), stream_format: None, + enable_suffix: None, + enable_containerd: None, }), Data( &ThunkContext::default() @@ -136,6 +160,8 @@ mod tests { Query(ConfigRequest { ns: String::from("test.azurecr.io"), stream_format: None, + enable_suffix: None, + enable_containerd: None, }), Data( &ThunkContext::default() @@ -151,6 +177,8 @@ mod tests { Query(ConfigRequest { ns: String::from("test.azurecr.io"), stream_format: None, + enable_suffix: None, + enable_containerd: None, }), Data( &ThunkContext::default()