diff --git a/packages/containerd-2.1/containerd-config-toml_k8s_containerd_sock b/packages/containerd-2.1/containerd-config-toml_k8s_containerd_sock index 1e2a34bff..5c848093d 100644 --- a/packages/containerd-2.1/containerd-config-toml_k8s_containerd_sock +++ b/packages/containerd-2.1/containerd-config-toml_k8s_containerd_sock @@ -2,7 +2,7 @@ container-registry = "v1" container-runtime = "v1" kubernetes = "v1" -std = { version = "v1", helpers = ["join_array", "default"]} +std = { version = "v1", helpers = ["join_array", "default", "is_cgroup_v2"]} +++ version = 3 root = "/var/lib/containerd" @@ -62,6 +62,11 @@ platform = "linux/amd64" [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options] SystemdCgroup = true diff --git a/packages/containerd-2.1/containerd-config-toml_k8s_nvidia_containerd_sock b/packages/containerd-2.1/containerd-config-toml_k8s_nvidia_containerd_sock index 04bb9a94e..a0c605bd5 100644 --- a/packages/containerd-2.1/containerd-config-toml_k8s_nvidia_containerd_sock +++ b/packages/containerd-2.1/containerd-config-toml_k8s_nvidia_containerd_sock @@ -2,7 +2,7 @@ container-registry = "v1" container-runtime = "v1" kubernetes = "v1" -std = { version = "v1", helpers = ["join_array", "default"]} +std = { version = "v1", helpers = ["join_array", "default", "is_cgroup_v2"]} +++ version = 3 root = "/var/lib/containerd" @@ -65,16 +65,31 @@ default_runtime_name = "nvidia" [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} # CDI only nvidia container runtime [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia-cdi] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} # legacy only nvidia container runtime [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia-legacy] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia.options] SystemdCgroup = true diff --git a/packages/containerd-2.2/containerd-config-toml_k8s_containerd_sock b/packages/containerd-2.2/containerd-config-toml_k8s_containerd_sock index 1e2a34bff..5c848093d 100644 --- a/packages/containerd-2.2/containerd-config-toml_k8s_containerd_sock +++ b/packages/containerd-2.2/containerd-config-toml_k8s_containerd_sock @@ -2,7 +2,7 @@ container-registry = "v1" container-runtime = "v1" kubernetes = "v1" -std = { version = "v1", helpers = ["join_array", "default"]} +std = { version = "v1", helpers = ["join_array", "default", "is_cgroup_v2"]} +++ version = 3 root = "/var/lib/containerd" @@ -62,6 +62,11 @@ platform = "linux/amd64" [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.runc.options] SystemdCgroup = true diff --git a/packages/containerd-2.2/containerd-config-toml_k8s_nvidia_containerd_sock b/packages/containerd-2.2/containerd-config-toml_k8s_nvidia_containerd_sock index 04bb9a94e..a0c605bd5 100644 --- a/packages/containerd-2.2/containerd-config-toml_k8s_nvidia_containerd_sock +++ b/packages/containerd-2.2/containerd-config-toml_k8s_nvidia_containerd_sock @@ -2,7 +2,7 @@ container-registry = "v1" container-runtime = "v1" kubernetes = "v1" -std = { version = "v1", helpers = ["join_array", "default"]} +std = { version = "v1", helpers = ["join_array", "default", "is_cgroup_v2"]} +++ version = 3 root = "/var/lib/containerd" @@ -65,16 +65,31 @@ default_runtime_name = "nvidia" [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} # CDI only nvidia container runtime [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia-cdi] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} # legacy only nvidia container runtime [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia-legacy] runtime_type = "io.containerd.runc.v2" base_runtime_spec = "/etc/containerd/cri-base.json" +{{#if (is_cgroup_v2)}} +{{#if settings.container-runtime.cgroup-writable}} +cgroup_writable = {{settings.container-runtime.cgroup-writable}} +{{/if}} +{{/if}} [plugins."io.containerd.cri.v1.runtime".containerd.runtimes.nvidia.options] SystemdCgroup = true diff --git a/sources/api/schnauzer/src/helpers/mod.rs b/sources/api/schnauzer/src/helpers/mod.rs index f59088bdc..21440f605 100644 --- a/sources/api/schnauzer/src/helpers/mod.rs +++ b/sources/api/schnauzer/src/helpers/mod.rs @@ -27,7 +27,7 @@ pub mod stdlib; pub use stdlib::{ any_enabled, base64_decode, default, goarch, join_array, join_map, negate_or_else, toml_encode, - IfNotNullHelper, IsArray, IsBool, IsNull, IsNumber, IsObject, IsString, + IfNotNullHelper, IsArray, IsBool, IsCgroupV2, IsNull, IsNumber, IsObject, IsString, }; lazy_static! { diff --git a/sources/api/schnauzer/src/helpers/stdlib/mod.rs b/sources/api/schnauzer/src/helpers/stdlib/mod.rs index e50fc56f7..7ccdb9896 100644 --- a/sources/api/schnauzer/src/helpers/stdlib/mod.rs +++ b/sources/api/schnauzer/src/helpers/stdlib/mod.rs @@ -9,7 +9,9 @@ use serde_json::value::Value; use snafu::{OptionExt, ResultExt}; pub mod reflective; +pub mod system; pub use reflective::{IsArray, IsBool, IsNull, IsNumber, IsObject, IsString}; +pub use system::IsCgroupV2; // This helper checks if any objects have '"enabled": true' in their properties. // diff --git a/sources/api/schnauzer/src/helpers/stdlib/system.rs b/sources/api/schnauzer/src/helpers/stdlib/system.rs new file mode 100644 index 000000000..c0e21e8e5 --- /dev/null +++ b/sources/api/schnauzer/src/helpers/stdlib/system.rs @@ -0,0 +1,55 @@ +//! This module contains schnauzer helpers for inspecting system properties. +use handlebars::{Handlebars, Helper, HelperDef, RenderContext, RenderError, ScopedJson}; + +/// Path to the cgroup v2 controllers file, which only exists on systems using cgroup v2. +const CGROUP_V2_CONTROLLERS_PATH: &str = "/sys/fs/cgroup/cgroup.controllers"; + +/// A helper that returns true if the system is using cgroup v2. +/// +/// Detection is based on the existence of `/sys/fs/cgroup/cgroup.controllers`, +/// which is a cgroup v2-specific interface file present only when cgroup v2 is +/// mounted in unified mode. +pub struct IsCgroupV2; + +impl HelperDef for IsCgroupV2 { + fn call_inner<'reg: 'rc, 'rc>( + &self, + _helper: &Helper<'reg, 'rc>, + _r: &'reg Handlebars<'reg>, + _ctx: &'rc handlebars::Context, + _renderctx: &mut RenderContext<'reg, 'rc>, + ) -> Result, RenderError> { + let is_v2 = std::path::Path::new(CGROUP_V2_CONTROLLERS_PATH).exists(); + Ok(ScopedJson::Derived(serde_json::Value::Bool(is_v2))) + } +} + +#[cfg(test)] +mod test { + use super::*; + use handlebars::Handlebars; + use serde_json::json; + + fn setup_and_render_template(tmpl: &str) -> Result { + let mut registry = Handlebars::new(); + registry.register_helper("is_cgroup_v2", Box::new(IsCgroupV2)); + registry.render_template(tmpl, &json!({})) + } + + #[test] + fn test_is_cgroup_v2_returns_bool() { + // We can't control the host cgroup version, but we can verify the helper + // renders without error and produces a valid conditional result. + let result = + setup_and_render_template(r#"{{#if (is_cgroup_v2)}}v2{{else}}v1{{/if}}"#).unwrap(); + assert!(result == "v2" || result == "v1"); + } + + #[test] + fn test_is_cgroup_v2_composes_with_not() { + let result = + setup_and_render_template(r#"{{#if (not (is_cgroup_v2))}}not-v2{{else}}is-v2{{/if}}"#) + .unwrap(); + assert!(result == "not-v2" || result == "is-v2"); + } +} diff --git a/sources/api/schnauzer/src/v2/import/helpers.rs b/sources/api/schnauzer/src/v2/import/helpers.rs index 204232d86..caca905a0 100644 --- a/sources/api/schnauzer/src/v2/import/helpers.rs +++ b/sources/api/schnauzer/src/v2/import/helpers.rs @@ -83,6 +83,7 @@ fn all_helpers() -> HashMap helper!(handlebars_helpers::stdlib::reflective::IsObject), "is_ipv4" => helper!(handlebars_helpers::is_ipv4), "is_ipv6" => helper!(handlebars_helpers::is_ipv6), + "is_cgroup_v2" => helper!(handlebars_helpers::IsCgroupV2), "cidr_to_ipaddr" => helper!(handlebars_helpers::cidr_to_ipaddr), "replace_ipv4_octet" => helper!(handlebars_helpers::replace_ipv4_octet), },