mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-05-11 06:05:04 +00:00
kata-deploy: Fix noisy caused by unformatted code
When do cargo fmt --all, some files changes as unformatted with
`cargo fmt`. This commit is just to address it.
Just use this as an example:
```
// Generate the common drop-in files (shared with standard
// runtimes)
- write_common_drop_ins(config, &runtime.base_config,
&config_d_dir, container_runtime)?;
+ write_common_drop_ins(
+ config,
+ &runtime.base_config,
+ &config_d_dir,
+ container_runtime,
+ )?;
```
Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
@@ -76,8 +76,12 @@ pub async fn install_artifacts(config: &Config, container_runtime: &str) -> Resu
|
||||
|
||||
// Create the installation directory if it doesn't exist
|
||||
// fs::create_dir_all handles existing directories gracefully (returns Ok if already exists)
|
||||
fs::create_dir_all(&config.host_install_dir)
|
||||
.with_context(|| format!("Failed to create installation directory: {}", config.host_install_dir))?;
|
||||
fs::create_dir_all(&config.host_install_dir).with_context(|| {
|
||||
format!(
|
||||
"Failed to create installation directory: {}",
|
||||
config.host_install_dir
|
||||
)
|
||||
})?;
|
||||
|
||||
// Verify the path exists and is a directory (not a file)
|
||||
let install_path = Path::new(&config.host_install_dir);
|
||||
@@ -182,7 +186,11 @@ fn write_common_drop_ins(
|
||||
let kernel_params_content = generate_kernel_params_drop_in(config, shim)?;
|
||||
if !kernel_params_content.is_empty() {
|
||||
info!(" - Kernel parameters: configured");
|
||||
write_drop_in_file(config_d_dir, "30-kernel-params.toml", &kernel_params_content)?;
|
||||
write_drop_in_file(
|
||||
config_d_dir,
|
||||
"30-kernel-params.toml",
|
||||
&kernel_params_content,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -239,7 +247,12 @@ fn install_custom_runtime_configs(config: &Config, container_runtime: &str) -> R
|
||||
}
|
||||
|
||||
// Generate the common drop-in files (shared with standard runtimes)
|
||||
write_common_drop_ins(config, &runtime.base_config, &config_d_dir, container_runtime)?;
|
||||
write_common_drop_ins(
|
||||
config,
|
||||
&runtime.base_config,
|
||||
&config_d_dir,
|
||||
container_runtime,
|
||||
)?;
|
||||
|
||||
// Copy user-provided drop-in file if provided (at 50-overrides.toml)
|
||||
if let Some(ref drop_in_src) = runtime.drop_in_file {
|
||||
@@ -342,8 +355,12 @@ fn copy_artifacts(src: &str, dst: &str) -> Result<()> {
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
|
||||
Err(e) => return Err(e.into()),
|
||||
}
|
||||
std::os::unix::fs::symlink(&new_target, &dst_path)
|
||||
.with_context(|| format!("Failed to create symlink {:?} -> {:?}", dst_path, new_target))?;
|
||||
std::os::unix::fs::symlink(&new_target, &dst_path).with_context(|| {
|
||||
format!(
|
||||
"Failed to create symlink {:?} -> {:?}",
|
||||
dst_path, new_target
|
||||
)
|
||||
})?;
|
||||
} else {
|
||||
if let Some(parent) = dst_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
@@ -459,13 +476,18 @@ fn setup_runtime_directory(config: &Config, shim: &str) -> Result<()> {
|
||||
// fs::copy follows symlinks and would write to the wrong location
|
||||
let dest_path = Path::new(&dest_config_file);
|
||||
if dest_path.exists() || dest_path.is_symlink() {
|
||||
fs::remove_file(&dest_config_file)
|
||||
.with_context(|| format!("Failed to remove existing config: {}", dest_config_file))?;
|
||||
fs::remove_file(&dest_config_file).with_context(|| {
|
||||
format!("Failed to remove existing config: {}", dest_config_file)
|
||||
})?;
|
||||
}
|
||||
|
||||
// Copy the base config file
|
||||
fs::copy(&original_config_file, &dest_config_file)
|
||||
.with_context(|| format!("Failed to copy config: {} -> {}", original_config_file, dest_config_file))?;
|
||||
fs::copy(&original_config_file, &dest_config_file).with_context(|| {
|
||||
format!(
|
||||
"Failed to copy config: {} -> {}",
|
||||
original_config_file, dest_config_file
|
||||
)
|
||||
})?;
|
||||
|
||||
// Add warning comment to inform users about drop-in files
|
||||
add_kata_deploy_warning(Path::new(&dest_config_file))?;
|
||||
@@ -484,8 +506,9 @@ fn remove_runtime_directory(config: &Config, shim: &str) -> Result<()> {
|
||||
);
|
||||
|
||||
if Path::new(&runtime_config_dir).exists() {
|
||||
fs::remove_dir_all(&runtime_config_dir)
|
||||
.with_context(|| format!("Failed to remove runtime directory: {}", runtime_config_dir))?;
|
||||
fs::remove_dir_all(&runtime_config_dir).with_context(|| {
|
||||
format!("Failed to remove runtime directory: {}", runtime_config_dir)
|
||||
})?;
|
||||
log::debug!("Removed runtime directory: {}", runtime_config_dir);
|
||||
}
|
||||
|
||||
@@ -514,7 +537,8 @@ async fn configure_shim_config(config: &Config, shim: &str, container_runtime: &
|
||||
);
|
||||
let config_d_dir = format!("{}/config.d", runtime_config_dir);
|
||||
|
||||
let kata_config_file = Path::new(&runtime_config_dir).join(format!("configuration-{shim}.toml"));
|
||||
let kata_config_file =
|
||||
Path::new(&runtime_config_dir).join(format!("configuration-{shim}.toml"));
|
||||
|
||||
// The configuration file (symlink) should exist after setup_runtime_directory()
|
||||
if !kata_config_file.exists() {
|
||||
@@ -545,8 +569,8 @@ async fn configure_shim_config(config: &Config, shim: &str, container_runtime: &
|
||||
/// Reads the current value (defaulting to "false" if not found), and if it's not "true",
|
||||
/// logs the update and sets it to "true".
|
||||
fn set_toml_bool_to_true(config_file: &Path, path: &str) -> Result<()> {
|
||||
let current_value = toml_utils::get_toml_value(config_file, path)
|
||||
.unwrap_or_else(|_| "false".to_string());
|
||||
let current_value =
|
||||
toml_utils::get_toml_value(config_file, path).unwrap_or_else(|_| "false".to_string());
|
||||
if current_value != "true" {
|
||||
log::debug!(
|
||||
"Updating {} in {}: old=\"{}\" new=\"true\"",
|
||||
@@ -636,8 +660,9 @@ fn get_hypervisor_path(config: &Config, shim: &str) -> Result<String> {
|
||||
if is_qemu_shim(shim) {
|
||||
// For QEMU shims, use the wrapper script that adds firmware paths
|
||||
// create_qemu_wrapper_script always returns Some for QEMU shims
|
||||
create_qemu_wrapper_script(config, shim)?
|
||||
.ok_or_else(|| anyhow::anyhow!("QEMU wrapper script should always be created for QEMU shims"))
|
||||
create_qemu_wrapper_script(config, shim)?.ok_or_else(|| {
|
||||
anyhow::anyhow!("QEMU wrapper script should always be created for QEMU shims")
|
||||
})
|
||||
} else {
|
||||
// For non-QEMU shims, use the appropriate hypervisor binary
|
||||
let binary = match shim {
|
||||
@@ -673,20 +698,41 @@ fn generate_installation_prefix_drop_in(config: &Config, shim: &str) -> Result<S
|
||||
}
|
||||
|
||||
// Common paths for all hypervisors
|
||||
content.push_str(&format!("kernel = \"{}/share/kata-containers/vmlinux.container\"\n", config.dest_dir));
|
||||
content.push_str(&format!("image = \"{}/share/kata-containers/kata-containers.img\"\n", config.dest_dir));
|
||||
content.push_str(&format!("initrd = \"{}/share/kata-containers/kata-containers-initrd.img\"\n", config.dest_dir));
|
||||
content.push_str(&format!(
|
||||
"kernel = \"{}/share/kata-containers/vmlinux.container\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
content.push_str(&format!(
|
||||
"image = \"{}/share/kata-containers/kata-containers.img\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
content.push_str(&format!(
|
||||
"initrd = \"{}/share/kata-containers/kata-containers-initrd.img\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
|
||||
// QEMU-specific paths (firmware is only relevant for QEMU)
|
||||
if is_qemu_shim(shim) {
|
||||
content.push_str(&format!("firmware = \"{}/share/kata-containers/firmware/\"\n", config.dest_dir));
|
||||
content.push_str(&format!("firmware_volume = \"{}/share/kata-containers/firmware/\"\n", config.dest_dir));
|
||||
content.push_str(&format!(
|
||||
"firmware = \"{}/share/kata-containers/firmware/\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
content.push_str(&format!(
|
||||
"firmware_volume = \"{}/share/kata-containers/firmware/\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
}
|
||||
|
||||
// Firecracker-specific paths (jailer is only for Firecracker)
|
||||
if shim == "fc" || shim == "firecracker" {
|
||||
content.push_str(&format!("jailer_path = \"{}/bin/jailer\"\n", config.dest_dir));
|
||||
content.push_str(&format!("valid_jailer_paths = [\"{}/bin/jailer\"]\n", config.dest_dir));
|
||||
content.push_str(&format!(
|
||||
"jailer_path = \"{}/bin/jailer\"\n",
|
||||
config.dest_dir
|
||||
));
|
||||
content.push_str(&format!(
|
||||
"valid_jailer_paths = [\"{}/bin/jailer\"]\n",
|
||||
config.dest_dir
|
||||
));
|
||||
}
|
||||
|
||||
Ok(content)
|
||||
@@ -738,16 +784,14 @@ fn get_proxy_value_for_shim(proxy_var: &Option<String>, shim: &str) -> Option<St
|
||||
match proxy_var {
|
||||
Some(proxy) if !proxy.is_empty() && proxy.contains('=') => {
|
||||
// Per-shim format: "qemu-tdx=http://proxy:8080;qemu-snp=http://proxy2:8080"
|
||||
proxy
|
||||
.split(';')
|
||||
.find_map(|m| {
|
||||
let parts: Vec<&str> = m.splitn(2, '=').collect();
|
||||
if parts.len() == 2 && parts[0] == shim {
|
||||
Some(parts[1].to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
proxy.split(';').find_map(|m| {
|
||||
let parts: Vec<&str> = m.splitn(2, '=').collect();
|
||||
if parts.len() == 2 && parts[0] == shim {
|
||||
Some(parts[1].to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
Some(proxy) if !proxy.is_empty() => Some(proxy.clone()),
|
||||
_ => None,
|
||||
@@ -770,8 +814,8 @@ fn read_base_kernel_params(config: &Config, shim: &str) -> Result<String> {
|
||||
}
|
||||
|
||||
let kernel_params_path = format!("hypervisor.{}.kernel_params", hypervisor_name);
|
||||
let base_params = toml_utils::get_toml_value(config_path, &kernel_params_path)
|
||||
.unwrap_or_default();
|
||||
let base_params =
|
||||
toml_utils::get_toml_value(config_path, &kernel_params_path).unwrap_or_default();
|
||||
|
||||
// Remove surrounding quotes if present
|
||||
Ok(base_params.trim_matches('"').to_string())
|
||||
@@ -1100,5 +1144,4 @@ mod tests {
|
||||
"following the symlink should yield the real content"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@ pub async fn configure_snapshotter(
|
||||
Some(id) => id.as_str(),
|
||||
None => containerd::get_containerd_pluginid(&paths.config_file)?,
|
||||
};
|
||||
let pluginid = containerd::pluginid_for_snapshotter_annotations(runtime_plugin_id, &paths.config_file)?;
|
||||
let pluginid =
|
||||
containerd::pluginid_for_snapshotter_annotations(runtime_plugin_id, &paths.config_file)?;
|
||||
|
||||
let configuration_file: std::path::PathBuf = if paths.use_drop_in {
|
||||
// Only add /host prefix if path is not in /etc/containerd (which is mounted from host)
|
||||
|
||||
@@ -189,14 +189,11 @@ impl Config {
|
||||
let default_shim_for_arch = get_arch_var("DEFAULT_SHIM", "qemu", &arch);
|
||||
|
||||
// Only use arch-specific variable for allowed hypervisor annotations
|
||||
let allowed_hypervisor_annotations_for_arch = get_arch_var(
|
||||
"ALLOWED_HYPERVISOR_ANNOTATIONS",
|
||||
"",
|
||||
&arch,
|
||||
)
|
||||
.split_whitespace()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
let allowed_hypervisor_annotations_for_arch =
|
||||
get_arch_var("ALLOWED_HYPERVISOR_ANNOTATIONS", "", &arch)
|
||||
.split_whitespace()
|
||||
.map(|s| s.to_string())
|
||||
.collect();
|
||||
|
||||
// Only use arch-specific variable for snapshotter handler mapping
|
||||
let snapshotter_handler_mapping_for_arch =
|
||||
@@ -208,7 +205,9 @@ impl Config {
|
||||
|
||||
let pull_type_mapping_for_arch = get_arch_var_or_base("PULL_TYPE_MAPPING", &arch);
|
||||
|
||||
let installation_prefix = env::var("INSTALLATION_PREFIX").ok().filter(|s| !s.is_empty());
|
||||
let installation_prefix = env::var("INSTALLATION_PREFIX")
|
||||
.ok()
|
||||
.filter(|s| !s.is_empty());
|
||||
let dest_dir = match installation_prefix {
|
||||
Some(ref prefix) => {
|
||||
if !prefix.starts_with('/') {
|
||||
@@ -258,15 +257,12 @@ impl Config {
|
||||
.map(|s| s.split(',').map(|s| s.trim().to_string()).collect());
|
||||
|
||||
// Only use arch-specific variable for experimental force guest pull
|
||||
let experimental_force_guest_pull_for_arch = get_arch_var(
|
||||
"EXPERIMENTAL_FORCE_GUEST_PULL",
|
||||
"",
|
||||
&arch,
|
||||
)
|
||||
.split(',')
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| s.trim().to_string())
|
||||
.collect();
|
||||
let experimental_force_guest_pull_for_arch =
|
||||
get_arch_var("EXPERIMENTAL_FORCE_GUEST_PULL", "", &arch)
|
||||
.split(',')
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| s.trim().to_string())
|
||||
.collect();
|
||||
|
||||
// Parse custom runtimes from ConfigMap
|
||||
let custom_runtimes_enabled =
|
||||
@@ -531,7 +527,8 @@ impl Config {
|
||||
use crate::runtime::manager;
|
||||
|
||||
// Check if drop-in files can be used based on containerd version
|
||||
let use_drop_in = manager::is_containerd_capable_of_using_drop_in_files(self, runtime).await?;
|
||||
let use_drop_in =
|
||||
manager::is_containerd_capable_of_using_drop_in_files(self, runtime).await?;
|
||||
|
||||
let paths = match runtime {
|
||||
"k0s-worker" | "k0s-controller" => ContainerdPaths {
|
||||
@@ -556,12 +553,10 @@ impl Config {
|
||||
// versioned drop-in dir (config.toml.d or config-v3.toml.d). If the import is
|
||||
// missing we bail; the cluster must configure the template with the import
|
||||
// (e.g. in tests or via a custom k3s/RKE2 setup). Refs: docs.k3s.io/advanced#configuring-containerd
|
||||
let container_runtime_version = k8s::get_node_field(
|
||||
self,
|
||||
".status.nodeInfo.containerRuntimeVersion",
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
let container_runtime_version =
|
||||
k8s::get_node_field(self, ".status.nodeInfo.containerRuntimeVersion")
|
||||
.await
|
||||
.ok();
|
||||
let use_v3 = k3s_rke2_resolve_use_v3(
|
||||
&self.containerd_conf_file,
|
||||
container_runtime_version.as_deref(),
|
||||
@@ -894,14 +889,17 @@ mod tests {
|
||||
#[serial]
|
||||
#[test]
|
||||
fn test_k3s_rke2_rendered_config_path() {
|
||||
assert_eq!(k3s_rke2_rendered_config_path(), "/etc/containerd/config.toml");
|
||||
assert_eq!(
|
||||
k3s_rke2_rendered_config_path(),
|
||||
"/etc/containerd/config.toml"
|
||||
);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(
|
||||
"imports = [\"/var/lib/rancher/k3s/agent/etc/containerd/config.toml.d/*.toml\"]\n",
|
||||
false,
|
||||
true,
|
||||
true
|
||||
)]
|
||||
#[case("version = 2\n", false, false)]
|
||||
#[case("imports = [\"/path/config-v3.toml.d/*.toml\"]", true, true)]
|
||||
|
||||
@@ -69,7 +69,10 @@ async fn main() -> Result<()> {
|
||||
let mut sigterm = match signal(SignalKind::terminate()) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to register SIGTERM handler: {}, sleeping forever", e);
|
||||
log::warn!(
|
||||
"Failed to register SIGTERM handler: {}, sleeping forever",
|
||||
e
|
||||
);
|
||||
std::future::pending::<()>().await;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -144,8 +144,7 @@ fn write_containerd_runtime_config(
|
||||
config_file,
|
||||
&format!(
|
||||
".plugins.{}.runtime_platforms.\"{}\".snapshotter",
|
||||
CONTAINERD_CRI_IMAGES_PLUGIN_ID,
|
||||
params.runtime_name
|
||||
CONTAINERD_CRI_IMAGES_PLUGIN_ID, params.runtime_name
|
||||
),
|
||||
snapshotter,
|
||||
)?;
|
||||
@@ -280,9 +279,7 @@ pub async fn configure_custom_containerd_runtime(
|
||||
),
|
||||
config_path: format!(
|
||||
"\"{}/share/defaults/kata-containers/custom-runtimes/{}/configuration-{}.toml\"",
|
||||
config.dest_dir,
|
||||
custom_runtime.handler,
|
||||
custom_runtime.base_config
|
||||
config.dest_dir, custom_runtime.handler, custom_runtime.base_config
|
||||
),
|
||||
pod_annotations,
|
||||
snapshotter,
|
||||
@@ -339,11 +336,7 @@ pub async fn configure_containerd(config: &Config, runtime: &str) -> Result<()>
|
||||
let imports_path = ".imports";
|
||||
let drop_in_path = format!("\"{}\"", paths.drop_in_file);
|
||||
|
||||
toml_utils::append_to_toml_array(
|
||||
Path::new(imports_file),
|
||||
imports_path,
|
||||
&drop_in_path,
|
||||
)?;
|
||||
toml_utils::append_to_toml_array(Path::new(imports_file), imports_path, &drop_in_path)?;
|
||||
log::info!("Successfully added drop-in to imports array");
|
||||
} else {
|
||||
log::info!("Runtime auto-loads drop-in files, skipping imports");
|
||||
@@ -369,10 +362,7 @@ pub async fn configure_containerd(config: &Config, runtime: &str) -> Result<()>
|
||||
config.custom_runtimes.len()
|
||||
);
|
||||
for custom_runtime in &config.custom_runtimes {
|
||||
log::info!(
|
||||
"Configuring custom runtime: {}",
|
||||
custom_runtime.handler
|
||||
);
|
||||
log::info!("Configuring custom runtime: {}", custom_runtime.handler);
|
||||
configure_custom_containerd_runtime(config, runtime, custom_runtime).await?;
|
||||
log::info!(
|
||||
"Successfully configured custom runtime: {}",
|
||||
@@ -436,12 +426,14 @@ pub async fn setup_containerd_config_files(runtime: &str, config: &Config) -> Re
|
||||
Path::new("/host").join(paths.drop_in_file.trim_start_matches('/'))
|
||||
};
|
||||
if let Some(parent) = drop_in_path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.with_context(|| format!("Failed to create K3s/RKE2 drop-in dir: {parent:?}"))?;
|
||||
fs::create_dir_all(parent).with_context(|| {
|
||||
format!("Failed to create K3s/RKE2 drop-in dir: {parent:?}")
|
||||
})?;
|
||||
}
|
||||
if !drop_in_path.exists() {
|
||||
fs::write(&drop_in_path, "")
|
||||
.with_context(|| format!("Failed to create K3s/RKE2 drop-in file: {drop_in_path:?}"))?;
|
||||
fs::write(&drop_in_path, "").with_context(|| {
|
||||
format!("Failed to create K3s/RKE2 drop-in file: {drop_in_path:?}")
|
||||
})?;
|
||||
}
|
||||
}
|
||||
"k0s-worker" | "k0s-controller" => {
|
||||
@@ -501,7 +493,10 @@ pub async fn containerd_snapshotter_version_check(config: &Config) -> Result<()>
|
||||
.map(|s| !s.is_empty())
|
||||
.unwrap_or(false);
|
||||
|
||||
check_containerd_snapshotter_version_support(&container_runtime_version, has_snapshotter_mapping)
|
||||
check_containerd_snapshotter_version_support(
|
||||
&container_runtime_version,
|
||||
has_snapshotter_mapping,
|
||||
)
|
||||
}
|
||||
|
||||
fn check_containerd_erofs_version_support(container_runtime_version: &str) -> Result<()> {
|
||||
@@ -609,10 +604,7 @@ mod tests {
|
||||
use std::path::Path;
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
fn make_params(
|
||||
runtime_name: &str,
|
||||
snapshotter: Option<&str>,
|
||||
) -> ContainerdRuntimeParams {
|
||||
fn make_params(runtime_name: &str, snapshotter: Option<&str>) -> ContainerdRuntimeParams {
|
||||
ContainerdRuntimeParams {
|
||||
runtime_name: runtime_name.to_string(),
|
||||
runtime_path: "\"/opt/kata/bin/kata-runtime\"".to_string(),
|
||||
@@ -673,7 +665,11 @@ mod tests {
|
||||
|
||||
/// pluginid_for_snapshotter_annotations maps runtime plugin id to the table where disable_snapshot_annotations lives.
|
||||
#[rstest]
|
||||
#[case(CONTAINERD_V3_RUNTIME_PLUGIN_ID, CONTAINERD_CRI_IMAGES_PLUGIN_ID, false)]
|
||||
#[case(
|
||||
CONTAINERD_V3_RUNTIME_PLUGIN_ID,
|
||||
CONTAINERD_CRI_IMAGES_PLUGIN_ID,
|
||||
false
|
||||
)]
|
||||
#[case(CONTAINERD_V2_CRI_PLUGIN_ID, CONTAINERD_CRI_CONTAINERD_TABLE_V2, false)]
|
||||
#[case(CONTAINERD_LEGACY_CRI_PLUGIN_ID, "", true)]
|
||||
fn test_pluginid_for_snapshotter_annotations(
|
||||
@@ -709,9 +705,7 @@ mod tests {
|
||||
#[rstest]
|
||||
#[case(CONTAINERD_V3_RUNTIME_PLUGIN_ID)]
|
||||
#[case(CONTAINERD_V2_CRI_PLUGIN_ID)]
|
||||
fn test_write_containerd_runtime_config_empty_file_no_leading_newlines(
|
||||
#[case] pluginid: &str,
|
||||
) {
|
||||
fn test_write_containerd_runtime_config_empty_file_no_leading_newlines(#[case] pluginid: &str) {
|
||||
let file = NamedTempFile::new().unwrap();
|
||||
let path = file.path();
|
||||
std::fs::write(path, "").unwrap();
|
||||
@@ -733,7 +727,12 @@ mod tests {
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case("containerd://1.6.28", true, false, Some("kata-deploy only supports snapshotter configuration with containerd 1.7 or newer"))]
|
||||
#[case(
|
||||
"containerd://1.6.28",
|
||||
true,
|
||||
false,
|
||||
Some("kata-deploy only supports snapshotter configuration with containerd 1.7 or newer")
|
||||
)]
|
||||
#[case("containerd://1.6.28", false, true, None)]
|
||||
#[case("containerd://1.6.0", true, false, None)]
|
||||
#[case("containerd://1.6.999", true, false, None)]
|
||||
@@ -750,9 +749,19 @@ mod tests {
|
||||
) {
|
||||
let result = check_containerd_snapshotter_version_support(version, has_mapping);
|
||||
if expect_ok {
|
||||
assert!(result.is_ok(), "expected ok for version={} has_mapping={}", version, has_mapping);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"expected ok for version={} has_mapping={}",
|
||||
version,
|
||||
has_mapping
|
||||
);
|
||||
} else {
|
||||
assert!(result.is_err(), "expected err for version={} has_mapping={}", version, has_mapping);
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"expected err for version={} has_mapping={}",
|
||||
version,
|
||||
has_mapping
|
||||
);
|
||||
if let Some(sub) = expected_error_substring {
|
||||
assert!(
|
||||
result.unwrap_err().to_string().contains(sub),
|
||||
|
||||
@@ -101,26 +101,65 @@ mod tests {
|
||||
#[case("qemu-tdx", "/opt/kata", "/opt/kata/share/defaults/kata-containers")]
|
||||
#[case("fc", "/opt/kata", "/opt/kata/share/defaults/kata-containers")]
|
||||
#[case("clh", "/opt/kata", "/opt/kata/share/defaults/kata-containers")]
|
||||
#[case("cloud-hypervisor", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtime-rs")]
|
||||
#[case("qemu-runtime-rs", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtime-rs")]
|
||||
#[case(
|
||||
"cloud-hypervisor",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtime-rs"
|
||||
)]
|
||||
#[case(
|
||||
"qemu-runtime-rs",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtime-rs"
|
||||
)]
|
||||
#[case("qemu", "/custom/path", "/custom/path/share/defaults/kata-containers")]
|
||||
#[case("cloud-hypervisor", "/custom/path", "/custom/path/share/defaults/kata-containers/runtime-rs")]
|
||||
#[case(
|
||||
"cloud-hypervisor",
|
||||
"/custom/path",
|
||||
"/custom/path/share/defaults/kata-containers/runtime-rs"
|
||||
)]
|
||||
fn test_get_kata_containers_original_config_path(
|
||||
#[case] shim: &str,
|
||||
#[case] base_dir: &str,
|
||||
#[case] expected: &str,
|
||||
) {
|
||||
assert_eq!(get_kata_containers_original_config_path(shim, base_dir), expected);
|
||||
assert_eq!(
|
||||
get_kata_containers_original_config_path(shim, base_dir),
|
||||
expected
|
||||
);
|
||||
}
|
||||
|
||||
// Tests for get_kata_containers_config_path (per-shim runtime directories)
|
||||
#[rstest]
|
||||
#[case("qemu", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtimes/qemu")]
|
||||
#[case("qemu-tdx", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtimes/qemu-tdx")]
|
||||
#[case("fc", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtimes/fc")]
|
||||
#[case("cloud-hypervisor", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtime-rs/runtimes/cloud-hypervisor")]
|
||||
#[case("qemu-runtime-rs", "/opt/kata", "/opt/kata/share/defaults/kata-containers/runtime-rs/runtimes/qemu-runtime-rs")]
|
||||
#[case("qemu", "/custom/path", "/custom/path/share/defaults/kata-containers/runtimes/qemu")]
|
||||
#[case(
|
||||
"qemu",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtimes/qemu"
|
||||
)]
|
||||
#[case(
|
||||
"qemu-tdx",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtimes/qemu-tdx"
|
||||
)]
|
||||
#[case(
|
||||
"fc",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtimes/fc"
|
||||
)]
|
||||
#[case(
|
||||
"cloud-hypervisor",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtime-rs/runtimes/cloud-hypervisor"
|
||||
)]
|
||||
#[case(
|
||||
"qemu-runtime-rs",
|
||||
"/opt/kata",
|
||||
"/opt/kata/share/defaults/kata-containers/runtime-rs/runtimes/qemu-runtime-rs"
|
||||
)]
|
||||
#[case(
|
||||
"qemu",
|
||||
"/custom/path",
|
||||
"/custom/path/share/defaults/kata-containers/runtimes/qemu"
|
||||
)]
|
||||
fn test_get_kata_containers_config_path(
|
||||
#[case] shim: &str,
|
||||
#[case] base_dir: &str,
|
||||
@@ -207,7 +246,10 @@ mod tests {
|
||||
let runtime_path = get_kata_containers_runtime_path(shim, dest_dir);
|
||||
|
||||
// Expected paths for Go runtime with per-shim directory
|
||||
assert_eq!(config_path, "/opt/kata/share/defaults/kata-containers/runtimes/qemu-tdx");
|
||||
assert_eq!(
|
||||
config_path,
|
||||
"/opt/kata/share/defaults/kata-containers/runtimes/qemu-tdx"
|
||||
);
|
||||
assert_eq!(original_path, "/opt/kata/share/defaults/kata-containers");
|
||||
assert_eq!(runtime_path, "/opt/kata/bin/containerd-shim-kata-v2");
|
||||
|
||||
|
||||
@@ -67,11 +67,7 @@ fn split_non_toml_header(content: &str) -> (&str, &str) {
|
||||
/// Ensures the header ends with a newline before the TOML body.
|
||||
/// Trims leading newlines from the serialized document to avoid many blank lines
|
||||
/// when the file was initially empty (e.g. containerd drop-in).
|
||||
fn write_toml_with_header(
|
||||
file_path: &Path,
|
||||
header: &str,
|
||||
doc: &DocumentMut,
|
||||
) -> Result<()> {
|
||||
fn write_toml_with_header(file_path: &Path, header: &str, doc: &DocumentMut) -> Result<()> {
|
||||
let normalized_header = if header.is_empty() {
|
||||
String::new()
|
||||
} else if header.ends_with('\n') {
|
||||
@@ -214,7 +210,10 @@ pub fn append_to_toml_array(file_path: &Path, path: &str, value: &str) -> Result
|
||||
// This is the array itself - use .get() to avoid panic on missing key
|
||||
let key_exists = current.get(part.as_str()).is_some();
|
||||
if !key_exists {
|
||||
current.insert(part.as_str(), Item::Value(Value::Array(toml_edit::Array::new())));
|
||||
current.insert(
|
||||
part.as_str(),
|
||||
Item::Value(Value::Array(toml_edit::Array::new())),
|
||||
);
|
||||
}
|
||||
if let Some(Item::Value(Value::Array(arr))) = current.get_mut(part.as_str()) {
|
||||
let value_item = parse_toml_value(value);
|
||||
@@ -441,11 +440,7 @@ mod tests {
|
||||
#[case("", "", "")]
|
||||
#[case("key = \"value\"\n", "", "key = \"value\"\n")]
|
||||
#[case("[plugins]\nfoo = 1\n", "", "[plugins]\nfoo = 1\n")]
|
||||
#[case(
|
||||
"{{ template \"base\" . }}\n",
|
||||
"{{ template \"base\" . }}\n",
|
||||
""
|
||||
)]
|
||||
#[case("{{ template \"base\" . }}\n", "{{ template \"base\" . }}\n", "")]
|
||||
#[case(
|
||||
"{{ template \"base\" . }}\n[plugins]\nfoo = 1\n",
|
||||
"{{ template \"base\" . }}\n",
|
||||
@@ -464,7 +459,11 @@ mod tests {
|
||||
#[case] expected_toml: &str,
|
||||
) {
|
||||
let (header, toml) = split_non_toml_header(input);
|
||||
assert_eq!(header, expected_header, "header mismatch for input: {:?}", input);
|
||||
assert_eq!(
|
||||
header, expected_header,
|
||||
"header mismatch for input: {:?}",
|
||||
input
|
||||
);
|
||||
assert_eq!(toml, expected_toml, "toml mismatch for input: {:?}", input);
|
||||
}
|
||||
|
||||
@@ -484,7 +483,10 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
assert!(content.starts_with("{{ template \"base\" . }}\n"), "header must be preserved");
|
||||
assert!(
|
||||
content.starts_with("{{ template \"base\" . }}\n"),
|
||||
"header must be preserved"
|
||||
);
|
||||
assert!(content.contains("runtime_type"), "value must be written");
|
||||
|
||||
let value = get_toml_value(
|
||||
@@ -580,8 +582,12 @@ mod tests {
|
||||
&format!("\"io.containerd.{shim}.v2\""),
|
||||
)
|
||||
.unwrap();
|
||||
set_toml_value(path, &format!("{table}.privileged_without_host_devices"), "true")
|
||||
.unwrap();
|
||||
set_toml_value(
|
||||
path,
|
||||
&format!("{table}.privileged_without_host_devices"),
|
||||
"true",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
@@ -633,7 +639,10 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
assert!(content.starts_with(expected_prefix), "header/prefix must be preserved");
|
||||
assert!(
|
||||
content.starts_with(expected_prefix),
|
||||
"header/prefix must be preserved"
|
||||
);
|
||||
let body_start = content.strip_prefix(expected_prefix).unwrap();
|
||||
assert!(
|
||||
!body_start.starts_with('\n'),
|
||||
@@ -782,11 +791,7 @@ mod tests {
|
||||
#[case("test.string_value", "test_string", "test_string")]
|
||||
#[case("test.bool_value", "true", "true")]
|
||||
#[case("test.int_value", "42", "42")]
|
||||
fn test_toml_value_types(
|
||||
#[case] path: &str,
|
||||
#[case] value: &str,
|
||||
#[case] expected: &str,
|
||||
) {
|
||||
fn test_toml_value_types(#[case] path: &str, #[case] value: &str, #[case] expected: &str) {
|
||||
let file = NamedTempFile::new().unwrap();
|
||||
let file_path = file.path();
|
||||
std::fs::write(file_path, "").unwrap();
|
||||
@@ -827,8 +832,8 @@ mod tests {
|
||||
);
|
||||
|
||||
// Test modifying kernel_params on real config
|
||||
let current = get_toml_value(temp_path, "hypervisor.qemu.kernel_params")
|
||||
.unwrap_or_default();
|
||||
let current =
|
||||
get_toml_value(temp_path, "hypervisor.qemu.kernel_params").unwrap_or_default();
|
||||
let new_value = format!("{} agent.log=debug", current.trim_matches('"'));
|
||||
let result = set_toml_value(
|
||||
temp_path,
|
||||
@@ -1318,7 +1323,11 @@ kernel_params = "console=hvc0"
|
||||
"set" => set_toml_value(temp_path, "some.path", "\"value\""),
|
||||
_ => panic!("unknown op"),
|
||||
};
|
||||
assert!(result.is_err(), "Should fail parsing invalid TOML (op={})", op);
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"Should fail parsing invalid TOML (op={})",
|
||||
op
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user