diff --git a/Cargo.lock b/Cargo.lock index beab69145..4f40c839a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ dependencies = [ "dbus", "log", "nix", - "oci_spec", + "oci-spec", "procfs", "serde", "systemd", @@ -577,17 +577,15 @@ dependencies = [ ] [[package]] -name = "oci_spec" -version = "0.1.0" -source = "git+https://github.com/containers/oci-spec-rs?rev=e0de21b89dc1e65f69a5f45a08bbe426787c7fa1#e0de21b89dc1e65f69a5f45a08bbe426787c7fa1" +name = "oci-spec" +version = "0.4.0" +source = "git+https://github.com/utam0k/oci-spec-rs/?tag=v0.4.0-with-bugfix#73540d3183136d0188b9c3a40f24b08295bbc92e" dependencies = [ - "anyhow", - "caps", - "nix", + "cfg-if 1.0.0", "quickcheck", "serde", "serde_json", - "tempfile", + "thiserror", ] [[package]] @@ -645,12 +643,6 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "prctl" version = "1.0.0" @@ -747,19 +739,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", "rand_core", ] @@ -772,15 +751,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" version = "0.2.9" @@ -807,15 +777,6 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ryu" version = "1.0.5" @@ -830,18 +791,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -850,9 +811,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" dependencies = [ "itoa", "ryu", @@ -934,20 +895,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "textwrap" version = "0.14.2" @@ -956,18 +903,18 @@ checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" dependencies = [ "proc-macro2", "quote", @@ -1065,7 +1012,7 @@ dependencies = [ "log", "mio", "nix", - "oci_spec", + "oci-spec", "once_cell", "prctl", "procfs", diff --git a/Cargo.toml b/Cargo.toml index f98ceddcb..7a5dd689f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ mio = { version = "0.7.13", features = ["os-ext", "os-poll"] } chrono = { version="0.4", features = ["serde"] } once_cell = "1.6.0" futures = { version = "0.3", features = ["thread-pool"] } -oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"} +oci-spec = { git="https://github.com/utam0k/oci-spec-rs/", tag = "v0.4.0-with-bugfix"} cgroups = { version = "0.1.0", path = "./cgroups" } systemd = { version = "0.8", default-features = false, optional = true } dbus = "0.9.2" @@ -38,9 +38,9 @@ fastrand = "1.4.1" crossbeam-channel = "0.5" [dev-dependencies] -oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1", features = ["proptests"]} +oci-spec = { git = "https://github.com/utam0k/oci-spec-rs/", tag = "v0.4.0-with-bugfix", features = ["proptests"] } quickcheck = "1" serial_test = "0.5.1" [profile.release] -lto = true \ No newline at end of file +lto = true diff --git a/cgroups/Cargo.lock b/cgroups/Cargo.lock index 68b066505..5ff77873d 100644 --- a/cgroups/Cargo.lock +++ b/cgroups/Cargo.lock @@ -73,17 +73,6 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" -[[package]] -name = "caps" -version = "0.5.3-alpha.0" -source = "git+https://github.com/lucab/caps-rs?rev=cb54844#cb54844125d9dd6de51d6c8c8a951aefbd0d3904" -dependencies = [ - "errno", - "libc", - "serde", - "thiserror", -] - [[package]] name = "cc" version = "1.0.69" @@ -115,7 +104,7 @@ dependencies = [ "libc", "log", "nix", - "oci_spec", + "oci-spec", "procfs", "quickcheck", "rbpf", @@ -428,17 +417,15 @@ dependencies = [ ] [[package]] -name = "oci_spec" -version = "0.1.0" -source = "git+https://github.com/containers/oci-spec-rs?rev=e0de21b89dc1e65f69a5f45a08bbe426787c7fa1#e0de21b89dc1e65f69a5f45a08bbe426787c7fa1" +name = "oci-spec" +version = "0.4.0" +source = "git+https://github.com/utam0k/oci-spec-rs/?tag=v0.4.0-with-bugfix#73540d3183136d0188b9c3a40f24b08295bbc92e" dependencies = [ - "anyhow", - "caps", - "nix", + "cfg-if 1.0.0", "quickcheck", "serde", "serde_json", - "tempfile", + "thiserror", ] [[package]] @@ -447,12 +434,6 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro2" version = "1.0.28" @@ -503,19 +484,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", "rand_core", ] @@ -528,15 +496,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "rbpf" version = "0.1.0" @@ -549,15 +508,6 @@ dependencies = [ "time", ] -[[package]] -name = "redox_syscall" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.5.4" @@ -575,15 +525,6 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "ryu" version = "1.0.5" @@ -592,18 +533,18 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.127" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -653,20 +594,6 @@ dependencies = [ "utf8-cstr", ] -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "termcolor" version = "1.1.2" diff --git a/cgroups/Cargo.toml b/cgroups/Cargo.toml index ae20fe31c..a3e3a5f03 100644 --- a/cgroups/Cargo.toml +++ b/cgroups/Cargo.toml @@ -14,7 +14,7 @@ nix = "0.22.0" procfs = "0.10.1" log = "0.4" anyhow = "1.0" -oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1"} +oci-spec = { git="https://github.com/utam0k/oci-spec-rs/", tag = "v0.4.0-with-bugfix"} systemd = { version = "0.8", default-features = false, optional = true } dbus = "0.9.2" serde = { version = "1.0", features = ["derive"] } @@ -24,7 +24,7 @@ errno = { version = "0.2.7", optional = true } libc = { version = "0.2.84", optional = true } [dev-dependencies] -oci_spec = { git = "https://github.com/containers/oci-spec-rs", rev = "e0de21b89dc1e65f69a5f45a08bbe426787c7fa1", features = ["proptests"]} +oci-spec = { git = "https://github.com/utam0k/oci-spec-rs/", tag = "v0.4.0-with-bugfix", features = ["proptests"] } quickcheck = "1" clap = "2" serde = { version = "1.0", features = ["derive"] } diff --git a/cgroups/src/common.rs b/cgroups/src/common.rs index c4c1b0607..b228c1c4a 100644 --- a/cgroups/src/common.rs +++ b/cgroups/src/common.rs @@ -10,7 +10,7 @@ use nix::{ sys::statfs::{statfs, CGROUP2_SUPER_MAGIC, TMPFS_MAGIC}, unistd::Pid, }; -use oci_spec::{FreezerState, LinuxDevice, LinuxDeviceCgroup, LinuxDeviceType, LinuxResources}; +use oci_spec::runtime::{LinuxDevice, LinuxDeviceCgroup, LinuxDeviceType, LinuxResources}; #[cfg(feature = "systemd_cgroups")] use systemd::daemon::booted; #[cfg(not(feature = "systemd_cgroups"))] @@ -30,7 +30,7 @@ pub trait CgroupManager { /// Adds a task specified by its pid to the cgroup fn add_task(&self, pid: Pid) -> Result<()>; /// Applies resource restrictions to the cgroup - fn apply(&self, linux_resources: &LinuxResources) -> Result<()>; + fn apply(&self, controller_opt: &ControllerOpt) -> Result<()>; /// Removes the cgroup fn remove(&self) -> Result<()>; // Sets the freezer cgroup to the specified state @@ -60,6 +60,30 @@ impl Display for CgroupSetup { } } +/// FreezerState is given freezer contoller +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum FreezerState { + /// Tasks in cgroup are undefined + Undefined, + /// Tasks in cgroup are suspended. + Frozen, + /// Tasks in cgroup are resuming. + Thawed, +} + +/// ControllerOpt is given all cgroup controller for applying cgroup configuration. +#[derive(Clone, Debug, Default)] +pub struct ControllerOpt { + /// Resources contain cgroup information for handling resource constraints for the container. + pub resources: LinuxResources, + /// Disables the OOM killer for out of memory conditions. + pub disable_oom_killer: bool, + /// Specify an oom_score_adj for container. + pub oom_score_adj: Option, + /// FreezerState is given to freezer contoller for suspending process. + pub freezer_state: Option, +} + #[inline] pub fn write_cgroup_file_str>(path: P, data: &str) -> Result<()> { fs::OpenOptions::new() diff --git a/cgroups/src/test.rs b/cgroups/src/test.rs index b84bbd4ed..0547702ae 100644 --- a/cgroups/src/test.rs +++ b/cgroups/src/test.rs @@ -8,7 +8,7 @@ use std::{ path::{Path, PathBuf}, }; -use oci_spec::LinuxCpu; +use oci_spec::runtime::LinuxCpu; pub struct TempDir { path: Option, diff --git a/cgroups/src/v1/blkio.rs b/cgroups/src/v1/blkio.rs index 6a3119be5..2cda43d16 100644 --- a/cgroups/src/v1/blkio.rs +++ b/cgroups/src/v1/blkio.rs @@ -1,13 +1,13 @@ use std::path::Path; use crate::{ - common, + common::{self, ControllerOpt}, stats::{self, BlkioDeviceStat, BlkioStats, StatsProvider}, v1::Controller, }; use anyhow::{Context, Result}; -use oci_spec::{LinuxBlockIo, LinuxResources}; +use oci_spec::runtime::LinuxBlockIo; // Throttling/upper limit policy // --------------------------------------- @@ -74,18 +74,18 @@ pub struct Blkio {} impl Controller for Blkio { type Resource = LinuxBlockIo; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply blkio cgroup config"); - if let Some(blkio) = Self::needs_to_handle(linux_resources) { + if let Some(blkio) = Self::needs_to_handle(controller_opt) { Self::apply(cgroup_root, blkio)?; } Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(blkio) = &linux_resources.block_io { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(blkio) = &controller_opt.resources.block_io { return Some(blkio); } @@ -228,7 +228,7 @@ mod tests { use crate::test::{create_temp_dir, set_fixture, setup}; use anyhow::Result; - use oci_spec::{LinuxBlockIo, LinuxThrottleDevice}; + use oci_spec::runtime::{LinuxBlockIo, LinuxThrottleDevice}; struct BlockIoBuilder { block_io: LinuxBlockIo, diff --git a/cgroups/src/v1/controller.rs b/cgroups/src/v1/controller.rs index a9a15a661..259f29757 100644 --- a/cgroups/src/v1/controller.rs +++ b/cgroups/src/v1/controller.rs @@ -3,9 +3,7 @@ use std::{fs, path::Path}; use anyhow::Result; use nix::unistd::Pid; -use oci_spec::LinuxResources; - -use crate::common::{self, CGROUP_PROCS}; +use crate::common::{self, ControllerOpt, CGROUP_PROCS}; pub trait Controller { type Resource; @@ -18,8 +16,8 @@ pub trait Controller { } /// Applies resource restrictions to the cgroup - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()>; + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()>; /// Checks if the controller needs to handle this request - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource>; + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource>; } diff --git a/cgroups/src/v1/cpu.rs b/cgroups/src/v1/cpu.rs index f5673cacd..dc7356c42 100644 --- a/cgroups/src/v1/cpu.rs +++ b/cgroups/src/v1/cpu.rs @@ -1,10 +1,10 @@ use std::path::Path; use anyhow::{bail, Context, Result}; -use oci_spec::{LinuxCpu, LinuxResources}; +use oci_spec::runtime::LinuxCpu; use crate::{ - common, + common::{self, ControllerOpt}, stats::{CpuThrottling, StatsProvider}, }; @@ -22,18 +22,18 @@ pub struct Cpu {} impl Controller for Cpu { type Resource = LinuxCpu; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply Cpu cgroup config"); - if let Some(cpu) = Self::needs_to_handle(linux_resources) { + if let Some(cpu) = Self::needs_to_handle(controller_opt) { Self::apply(cgroup_root, cpu).context("failed to apply cpu resource restrictions")?; } Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(cpu) = &linux_resources.cpu { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(cpu) = &controller_opt.resources.cpu { if cpu.shares.is_some() || cpu.period.is_some() || cpu.quota.is_some() diff --git a/cgroups/src/v1/cpuacct.rs b/cgroups/src/v1/cpuacct.rs index 9ca07dfe8..0633b1d89 100644 --- a/cgroups/src/v1/cpuacct.rs +++ b/cgroups/src/v1/cpuacct.rs @@ -1,10 +1,9 @@ use std::path::Path; use anyhow::{bail, Context, Result}; -use oci_spec::LinuxResources; use crate::{ - common, + common::{self, ControllerOpt}, stats::{CpuUsage, StatsProvider}, }; @@ -24,11 +23,11 @@ pub struct CpuAcct {} impl Controller for CpuAcct { type Resource = (); - fn apply(_linux_resources: &LinuxResources, _cgroup_path: &Path) -> Result<()> { + fn apply(_controller_opt: &ControllerOpt, _cgroup_path: &Path) -> Result<()> { Ok(()) } - fn needs_to_handle(_linux_resources: &LinuxResources) -> Option<&Self::Resource> { + fn needs_to_handle(_controller_opt: &ControllerOpt) -> Option<&Self::Resource> { None } } diff --git a/cgroups/src/v1/cpuset.rs b/cgroups/src/v1/cpuset.rs index d8161e8c1..df374efd5 100644 --- a/cgroups/src/v1/cpuset.rs +++ b/cgroups/src/v1/cpuset.rs @@ -2,10 +2,10 @@ use std::{fs, path::Path}; use anyhow::{bail, Context, Result}; use nix::unistd; -use oci_spec::{LinuxCpu, LinuxResources}; +use oci_spec::runtime::LinuxCpu; use unistd::Pid; -use crate::common::{self, CGROUP_PROCS}; +use crate::common::{self, ControllerOpt, CGROUP_PROCS}; use super::{util, Controller, ControllerType}; @@ -27,10 +27,10 @@ impl Controller for CpuSet { Ok(()) } - fn apply(linux_resources: &LinuxResources, cgroup_path: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_path: &Path) -> Result<()> { log::debug!("Apply CpuSet cgroup config"); - if let Some(cpuset) = Self::needs_to_handle(linux_resources) { + if let Some(cpuset) = Self::needs_to_handle(controller_opt) { Self::apply(cgroup_path, cpuset) .context("failed to apply cpuset resource restrictions")?; } @@ -38,8 +38,8 @@ impl Controller for CpuSet { Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(cpuset) = &linux_resources.cpu { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(cpuset) = &controller_opt.resources.cpu { if cpuset.cpus.is_some() || cpuset.mems.is_some() { return Some(cpuset); } diff --git a/cgroups/src/v1/devices.rs b/cgroups/src/v1/devices.rs index f07f090b2..b1541c0a9 100644 --- a/cgroups/src/v1/devices.rs +++ b/cgroups/src/v1/devices.rs @@ -3,18 +3,18 @@ use std::path::Path; use anyhow::Result; use super::controller::Controller; -use crate::common::{self, default_allow_devices, default_devices}; -use oci_spec::{LinuxDeviceCgroup, LinuxResources}; +use crate::common::{self, default_allow_devices, default_devices, ControllerOpt}; +use oci_spec::runtime::LinuxDeviceCgroup; pub struct Devices {} impl Controller for Devices { type Resource = (); - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply Devices cgroup config"); - if let Some(devices) = linux_resources.devices.as_ref() { + if let Some(devices) = controller_opt.resources.devices.as_ref() { for d in devices { Self::apply_device(d, cgroup_root)?; } @@ -33,7 +33,7 @@ impl Controller for Devices { } // always needs to be called due to default devices - fn needs_to_handle(_linux_resources: &LinuxResources) -> Option<&Self::Resource> { + fn needs_to_handle(_controller_opt: &ControllerOpt) -> Option<&Self::Resource> { Some(&()) } } @@ -56,7 +56,7 @@ mod tests { use super::*; use crate::test::create_temp_dir; use crate::test::set_fixture; - use oci_spec::{LinuxDeviceCgroup, LinuxDeviceType}; + use oci_spec::runtime::{LinuxDeviceCgroup, LinuxDeviceType}; use std::fs::read_to_string; #[test] diff --git a/cgroups/src/v1/freezer.rs b/cgroups/src/v1/freezer.rs index 631ddcf34..686aa74bb 100644 --- a/cgroups/src/v1/freezer.rs +++ b/cgroups/src/v1/freezer.rs @@ -9,7 +9,7 @@ use anyhow::{Result, *}; use super::Controller; use crate::common; -use oci_spec::{FreezerState, LinuxResources}; +use crate::common::{ControllerOpt, FreezerState}; const CGROUP_FREEZER_STATE: &str = "freezer.state"; const FREEZER_STATE_THAWED: &str = "THAWED"; @@ -21,19 +21,19 @@ pub struct Freezer {} impl Controller for Freezer { type Resource = FreezerState; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply Freezer cgroup config"); create_dir_all(&cgroup_root)?; - if let Some(freezer_state) = Self::needs_to_handle(linux_resources) { + if let Some(freezer_state) = Self::needs_to_handle(controller_opt) { Self::apply(freezer_state, cgroup_root).context("failed to appyl freezer")?; } Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(freezer_state) = &linux_resources.freezer { + fn needs_to_handle(controller: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(freezer_state) = &controller.freezer_state { return Some(freezer_state); } @@ -124,10 +124,10 @@ impl Freezer { #[cfg(test)] mod tests { use super::*; - use crate::common::CGROUP_PROCS; + use crate::common::{FreezerState, CGROUP_PROCS}; use crate::test::{create_temp_dir, set_fixture}; use nix::unistd::Pid; - use oci_spec::FreezerState; + use oci_spec::runtime::LinuxResources; #[test] fn test_set_freezer_state() { @@ -178,22 +178,26 @@ mod tests { { let linux_resources = LinuxResources { devices: Some(vec![]), - disable_oom_killer: false, - oom_score_adj: None, memory: None, cpu: None, pids: None, block_io: None, hugepage_limits: Some(vec![]), network: None, - freezer: Some(FreezerState::Thawed), rdma: None, unified: None, }; + let state = FreezerState::Thawed; + + let controller_opt = ControllerOpt { + resources: linux_resources, + freezer_state: Some(state), + ..Default::default() + }; let pid = Pid::from_raw(1000); Freezer::add_task(pid, &tmp).expect("freezer add task"); - ::apply(&linux_resources, &tmp).expect("freezer apply"); + ::apply(&controller_opt, &tmp).expect("freezer apply"); let state_content = std::fs::read_to_string(tmp.join(CGROUP_FREEZER_STATE)).expect("read to string"); assert_eq!(FREEZER_STATE_THAWED, state_content); @@ -206,22 +210,27 @@ mod tests { { let linux_resources = LinuxResources { devices: Some(vec![]), - disable_oom_killer: false, - oom_score_adj: None, memory: None, cpu: None, pids: None, block_io: None, hugepage_limits: Some(vec![]), network: None, - freezer: Some(FreezerState::Frozen), rdma: None, unified: None, }; + let state = FreezerState::Frozen; + + let controller_opt = ControllerOpt { + resources: linux_resources, + freezer_state: Some(state), + ..Default::default() + }; + let pid = Pid::from_raw(1001); Freezer::add_task(pid, &tmp).expect("freezer add task"); - ::apply(&linux_resources, &tmp).expect("freezer apply"); + ::apply(&controller_opt, &tmp).expect("freezer apply"); let state_content = std::fs::read_to_string(tmp.join(CGROUP_FREEZER_STATE)).expect("read to string"); assert_eq!(FREEZER_STATE_FROZEN, state_content); @@ -234,24 +243,29 @@ mod tests { { let linux_resources = LinuxResources { devices: Some(vec![]), - disable_oom_killer: false, - oom_score_adj: None, memory: None, cpu: None, pids: None, block_io: None, hugepage_limits: Some(vec![]), network: None, - freezer: Some(FreezerState::Undefined), rdma: None, unified: None, }; + let state = FreezerState::Undefined; + + let controller_opt = ControllerOpt { + resources: linux_resources, + freezer_state: Some(state), + ..Default::default() + }; + let pid = Pid::from_raw(1002); let old_state_content = std::fs::read_to_string(tmp.join(CGROUP_FREEZER_STATE)).expect("read to string"); Freezer::add_task(pid, &tmp).expect("freezer add task"); - ::apply(&linux_resources, &tmp).expect("freezer apply"); + ::apply(&controller_opt, &tmp).expect("freezer apply"); let state_content = std::fs::read_to_string(tmp.join(CGROUP_FREEZER_STATE)).expect("read to string"); assert_eq!(old_state_content, state_content); diff --git a/cgroups/src/v1/hugetlb.rs b/cgroups/src/v1/hugetlb.rs index 994227dfe..cc0bc02c0 100644 --- a/cgroups/src/v1/hugetlb.rs +++ b/cgroups/src/v1/hugetlb.rs @@ -3,22 +3,22 @@ use std::{collections::HashMap, path::Path}; use anyhow::{bail, Context, Result}; use crate::{ - common, + common::{self, ControllerOpt}, stats::{supported_page_sizes, HugeTlbStats, StatsProvider}, }; use super::Controller; -use oci_spec::{LinuxHugepageLimit, LinuxResources}; +use oci_spec::runtime::LinuxHugepageLimit; pub struct HugeTlb {} impl Controller for HugeTlb { type Resource = Vec; - fn apply(linux_resources: &LinuxResources, cgroup_root: &std::path::Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &std::path::Path) -> Result<()> { log::debug!("Apply Hugetlb cgroup config"); - if let Some(hugepage_limits) = Self::needs_to_handle(linux_resources) { + if let Some(hugepage_limits) = Self::needs_to_handle(controller_opt) { for hugetlb in hugepage_limits { Self::apply(cgroup_root, hugetlb) .context("failed to apply hugetlb resource restrictions")? @@ -28,10 +28,10 @@ impl Controller for HugeTlb { Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(hugepage_limits) = linux_resources.hugepage_limits.as_ref() { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(hugepage_limits) = controller_opt.resources.hugepage_limits.as_ref() { if !hugepage_limits.is_empty() { - return linux_resources.hugepage_limits.as_ref(); + return controller_opt.resources.hugepage_limits.as_ref(); } } @@ -101,7 +101,7 @@ impl HugeTlb { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxHugepageLimit; + use oci_spec::runtime::LinuxHugepageLimit; use std::fs::read_to_string; #[test] diff --git a/cgroups/src/v1/manager.rs b/cgroups/src/v1/manager.rs index 546e6beae..c52de07b1 100644 --- a/cgroups/src/v1/manager.rs +++ b/cgroups/src/v1/manager.rs @@ -16,9 +16,9 @@ use super::{ perf_event::PerfEvent, pids::Pids, util, Controller, }; -use crate::common::{self, CgroupManager, PathBufExt, CGROUP_PROCS}; +use crate::common::{self, CgroupManager, ControllerOpt, FreezerState, PathBufExt, CGROUP_PROCS}; use crate::stats::{Stats, StatsProvider}; -use oci_spec::{FreezerState, LinuxResources}; + pub struct Manager { subsystems: HashMap, } @@ -61,28 +61,28 @@ impl Manager { fn get_required_controllers( &self, - linux_resources: &LinuxResources, + controller_opt: &ControllerOpt, ) -> Result> { let mut required_controllers = HashMap::new(); for controller in CONTROLLERS { let required = match controller { - CtrlType::Cpu => Cpu::needs_to_handle(linux_resources).is_some(), - CtrlType::CpuAcct => CpuAcct::needs_to_handle(linux_resources).is_some(), - CtrlType::CpuSet => CpuSet::needs_to_handle(linux_resources).is_some(), - CtrlType::Devices => Devices::needs_to_handle(linux_resources).is_some(), - CtrlType::HugeTlb => HugeTlb::needs_to_handle(linux_resources).is_some(), - CtrlType::Memory => Memory::needs_to_handle(linux_resources).is_some(), - CtrlType::Pids => Pids::needs_to_handle(linux_resources).is_some(), - CtrlType::PerfEvent => PerfEvent::needs_to_handle(linux_resources).is_some(), - CtrlType::Blkio => Blkio::needs_to_handle(linux_resources).is_some(), + CtrlType::Cpu => Cpu::needs_to_handle(controller_opt).is_some(), + CtrlType::CpuAcct => CpuAcct::needs_to_handle(controller_opt).is_some(), + CtrlType::CpuSet => CpuSet::needs_to_handle(controller_opt).is_some(), + CtrlType::Devices => Devices::needs_to_handle(controller_opt).is_some(), + CtrlType::HugeTlb => HugeTlb::needs_to_handle(controller_opt).is_some(), + CtrlType::Memory => Memory::needs_to_handle(controller_opt).is_some(), + CtrlType::Pids => Pids::needs_to_handle(controller_opt).is_some(), + CtrlType::PerfEvent => PerfEvent::needs_to_handle(controller_opt).is_some(), + CtrlType::Blkio => Blkio::needs_to_handle(controller_opt).is_some(), CtrlType::NetworkPriority => { - NetworkPriority::needs_to_handle(linux_resources).is_some() + NetworkPriority::needs_to_handle(controller_opt).is_some() } CtrlType::NetworkClassifier => { - NetworkClassifier::needs_to_handle(linux_resources).is_some() + NetworkClassifier::needs_to_handle(controller_opt).is_some() } - CtrlType::Freezer => Freezer::needs_to_handle(linux_resources).is_some(), + CtrlType::Freezer => Freezer::needs_to_handle(controller_opt).is_some(), }; if required { @@ -128,21 +128,21 @@ impl CgroupManager for Manager { Ok(()) } - fn apply(&self, linux_resources: &LinuxResources) -> Result<()> { - for subsys in self.get_required_controllers(linux_resources)? { + fn apply(&self, controller_opt: &ControllerOpt) -> Result<()> { + for subsys in self.get_required_controllers(controller_opt)? { match subsys.0 { - CtrlType::Cpu => Cpu::apply(linux_resources, subsys.1)?, - CtrlType::CpuAcct => CpuAcct::apply(linux_resources, subsys.1)?, - CtrlType::CpuSet => CpuSet::apply(linux_resources, subsys.1)?, - CtrlType::Devices => Devices::apply(linux_resources, subsys.1)?, - CtrlType::HugeTlb => HugeTlb::apply(linux_resources, subsys.1)?, - CtrlType::Memory => Memory::apply(linux_resources, subsys.1)?, - CtrlType::Pids => Pids::apply(linux_resources, subsys.1)?, - CtrlType::PerfEvent => PerfEvent::apply(linux_resources, subsys.1)?, - CtrlType::Blkio => Blkio::apply(linux_resources, subsys.1)?, - CtrlType::NetworkPriority => NetworkPriority::apply(linux_resources, subsys.1)?, - CtrlType::NetworkClassifier => NetworkClassifier::apply(linux_resources, subsys.1)?, - CtrlType::Freezer => Freezer::apply(linux_resources, subsys.1)?, + CtrlType::Cpu => Cpu::apply(controller_opt, subsys.1)?, + CtrlType::CpuAcct => CpuAcct::apply(controller_opt, subsys.1)?, + CtrlType::CpuSet => CpuSet::apply(controller_opt, subsys.1)?, + CtrlType::Devices => Devices::apply(controller_opt, subsys.1)?, + CtrlType::HugeTlb => HugeTlb::apply(controller_opt, subsys.1)?, + CtrlType::Memory => Memory::apply(controller_opt, subsys.1)?, + CtrlType::Pids => Pids::apply(controller_opt, subsys.1)?, + CtrlType::PerfEvent => PerfEvent::apply(controller_opt, subsys.1)?, + CtrlType::Blkio => Blkio::apply(controller_opt, subsys.1)?, + CtrlType::NetworkPriority => NetworkPriority::apply(controller_opt, subsys.1)?, + CtrlType::NetworkClassifier => NetworkClassifier::apply(controller_opt, subsys.1)?, + CtrlType::Freezer => Freezer::apply(controller_opt, subsys.1)?, } } @@ -169,12 +169,13 @@ impl CgroupManager for Manager { } fn freeze(&self, state: FreezerState) -> Result<()> { - let linux_resources = LinuxResources { - freezer: Some(state), + let controller_opt = ControllerOpt { + resources: Default::default(), + freezer_state: Some(state), ..Default::default() }; Freezer::apply( - &linux_resources, + &controller_opt, self.subsystems.get(&CtrlType::Freezer).unwrap(), ) } diff --git a/cgroups/src/v1/memory.rs b/cgroups/src/v1/memory.rs index 3acddfb73..d941f6039 100644 --- a/cgroups/src/v1/memory.rs +++ b/cgroups/src/v1/memory.rs @@ -6,10 +6,10 @@ use anyhow::{anyhow, bail, Result}; use nix::errno::Errno; use super::Controller; -use crate::common::{self}; +use crate::common::{self, ControllerOpt}; use crate::stats::{self, parse_single_value, MemoryData, MemoryStats, StatsProvider}; -use oci_spec::{LinuxMemory, LinuxResources}; +use oci_spec::runtime::LinuxMemory; const CGROUP_MEMORY_SWAP_LIMIT: &str = "memory.memsw.limit_in_bytes"; const CGROUP_MEMORY_LIMIT: &str = "memory.limit_in_bytes"; @@ -48,10 +48,10 @@ pub struct Memory {} impl Controller for Memory { type Resource = LinuxMemory; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply Memory cgroup config"); - if let Some(memory) = Self::needs_to_handle(linux_resources) { + if let Some(memory) = Self::needs_to_handle(controller_opt) { let reservation = memory.reservation.unwrap_or(0); Self::apply(memory, cgroup_root)?; @@ -63,7 +63,7 @@ impl Controller for Memory { )?; } - if linux_resources.disable_oom_killer { + if controller_opt.disable_oom_killer { common::write_cgroup_file(cgroup_root.join(CGROUP_MEMORY_OOM_CONTROL), 0)?; } else { common::write_cgroup_file(cgroup_root.join(CGROUP_MEMORY_OOM_CONTROL), 1)?; @@ -101,8 +101,8 @@ impl Controller for Memory { Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(memory) = &linux_resources.memory { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(memory) = &controller_opt.resources.memory { return Some(memory); } @@ -324,7 +324,7 @@ mod tests { use super::*; use crate::common::CGROUP_PROCS; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxMemory; + use oci_spec::runtime::{LinuxMemory, LinuxResources}; #[test] fn test_set_memory() { @@ -440,24 +440,28 @@ mod tests { // clone to avoid use of moved value later on - let memory_limits = linux_memory.clone(); + let memory_limits = linux_memory; let linux_resources = LinuxResources { devices: Some(vec![]), - disable_oom_killer, - oom_score_adj: None, // current unused memory: Some(linux_memory), cpu: None, pids: None, block_io: None, hugepage_limits: Some(vec![]), network: None, - freezer: None, rdma: None, unified: None, }; - let result = ::apply(&linux_resources, &tmp); + let controller_opt = ControllerOpt { + resources: linux_resources, + disable_oom_killer, + ..Default::default() + }; + + let result = ::apply(&controller_opt, &tmp); + if result.is_err() { if let Some(swappiness) = memory_limits.swappiness { diff --git a/cgroups/src/v1/network_classifier.rs b/cgroups/src/v1/network_classifier.rs index 63f398029..f1b10be6e 100644 --- a/cgroups/src/v1/network_classifier.rs +++ b/cgroups/src/v1/network_classifier.rs @@ -3,18 +3,18 @@ use std::path::Path; use anyhow::{Context, Result}; use super::Controller; -use crate::common; -use oci_spec::{LinuxNetwork, LinuxResources}; +use crate::common::{self, ControllerOpt}; +use oci_spec::runtime::LinuxNetwork; pub struct NetworkClassifier {} impl Controller for NetworkClassifier { type Resource = LinuxNetwork; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply NetworkClassifier cgroup config"); - if let Some(network) = Self::needs_to_handle(linux_resources) { + if let Some(network) = Self::needs_to_handle(controller_opt) { Self::apply(cgroup_root, network) .context("failed to apply network classifier resource restrictions")?; } @@ -22,8 +22,8 @@ impl Controller for NetworkClassifier { Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(network) = linux_resources.network.as_ref() { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(network) = controller_opt.resources.network.as_ref() { return Some(network); } diff --git a/cgroups/src/v1/network_priority.rs b/cgroups/src/v1/network_priority.rs index 90d83c69c..1a6976f14 100644 --- a/cgroups/src/v1/network_priority.rs +++ b/cgroups/src/v1/network_priority.rs @@ -3,18 +3,18 @@ use std::path::Path; use anyhow::{Context, Result}; use super::Controller; -use crate::common; -use oci_spec::{LinuxNetwork, LinuxResources}; +use crate::common::{self, ControllerOpt}; +use oci_spec::runtime::LinuxNetwork; pub struct NetworkPriority {} impl Controller for NetworkPriority { type Resource = LinuxNetwork; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply NetworkPriority cgroup config"); - if let Some(network) = Self::needs_to_handle(linux_resources) { + if let Some(network) = Self::needs_to_handle(controller_opt) { Self::apply(cgroup_root, network) .context("failed to apply network priority resource restrictions")?; } @@ -22,8 +22,8 @@ impl Controller for NetworkPriority { Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(network) = &linux_resources.network { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(network) = &controller_opt.resources.network { return Some(network); } @@ -46,7 +46,7 @@ impl NetworkPriority { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxInterfacePriority; + use oci_spec::runtime::LinuxInterfacePriority; #[test] fn test_apply_network_priorites() { diff --git a/cgroups/src/v1/perf_event.rs b/cgroups/src/v1/perf_event.rs index ed53c46b7..d3b6f104d 100644 --- a/cgroups/src/v1/perf_event.rs +++ b/cgroups/src/v1/perf_event.rs @@ -1,6 +1,6 @@ use super::Controller; +use crate::common::ControllerOpt; use anyhow::Result; -use oci_spec::LinuxResources; use std::path::Path; pub struct PerfEvent {} @@ -8,11 +8,11 @@ pub struct PerfEvent {} impl Controller for PerfEvent { type Resource = (); - fn apply(_linux_resources: &LinuxResources, _cgroup_root: &Path) -> Result<()> { + fn apply(_controller_opt: &ControllerOpt, _cgroup_root: &Path) -> Result<()> { Ok(()) } //no need to handle any case - fn needs_to_handle(_linux_resources: &LinuxResources) -> Option<&Self::Resource> { + fn needs_to_handle(_controller_opt: &ControllerOpt) -> Option<&Self::Resource> { None } } diff --git a/cgroups/src/v1/pids.rs b/cgroups/src/v1/pids.rs index 04ed4cd4f..f774c2902 100644 --- a/cgroups/src/v1/pids.rs +++ b/cgroups/src/v1/pids.rs @@ -4,10 +4,10 @@ use anyhow::{Context, Result}; use super::Controller; use crate::{ - common, + common::{self, ControllerOpt}, stats::{self, PidStats, StatsProvider}, }; -use oci_spec::{LinuxPids, LinuxResources}; +use oci_spec::runtime::LinuxPids; // Contains the maximum allowed number of active pids const CGROUP_PIDS_MAX: &str = "pids.max"; @@ -17,18 +17,18 @@ pub struct Pids {} impl Controller for Pids { type Resource = LinuxPids; - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply pids cgroup config"); - if let Some(pids) = &linux_resources.pids { + if let Some(pids) = &controller_opt.resources.pids { Self::apply(cgroup_root, pids).context("failed to apply pids resource restrictions")?; } Ok(()) } - fn needs_to_handle(linux_resources: &LinuxResources) -> Option<&Self::Resource> { - if let Some(pids) = &linux_resources.pids { + fn needs_to_handle(controller_opt: &ControllerOpt) -> Option<&Self::Resource> { + if let Some(pids) = &controller_opt.resources.pids { return Some(pids); } @@ -61,7 +61,7 @@ impl Pids { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxPids; + use oci_spec::runtime::LinuxPids; // Contains the current number of active pids const CGROUP_PIDS_CURRENT: &str = "pids.current"; diff --git a/cgroups/src/v2/controller.rs b/cgroups/src/v2/controller.rs index e8751f92e..7287c1eb3 100644 --- a/cgroups/src/v2/controller.rs +++ b/cgroups/src/v2/controller.rs @@ -1,8 +1,8 @@ use anyhow::Result; use std::path::Path; -use oci_spec::LinuxResources; +use crate::common::ControllerOpt; pub trait Controller { - fn apply(linux_resources: &LinuxResources, cgroup_path: &Path) -> Result<()>; + fn apply(controller_opt: &ControllerOpt, cgroup_path: &Path) -> Result<()>; } diff --git a/cgroups/src/v2/cpu.rs b/cgroups/src/v2/cpu.rs index ae02724a7..277d5cfb3 100644 --- a/cgroups/src/v2/cpu.rs +++ b/cgroups/src/v2/cpu.rs @@ -2,11 +2,11 @@ use anyhow::{bail, Context, Result}; use std::path::Path; use crate::{ - common, + common::{self, ControllerOpt}, stats::{CpuUsage, StatsProvider}, }; -use oci_spec::{LinuxCpu, LinuxResources}; +use oci_spec::runtime::LinuxCpu; use super::controller::Controller; @@ -20,8 +20,8 @@ const CPU_STAT: &str = "cpu.stat"; pub struct Cpu {} impl Controller for Cpu { - fn apply(linux_resources: &LinuxResources, path: &Path) -> Result<()> { - if let Some(cpu) = &linux_resources.cpu { + fn apply(controller_opt: &ControllerOpt, path: &Path) -> Result<()> { + if let Some(cpu) = &controller_opt.resources.cpu { Self::apply(path, cpu).context("failed to apply cpu resource restrictions")?; } diff --git a/cgroups/src/v2/cpuset.rs b/cgroups/src/v2/cpuset.rs index fa5d50422..80797cd60 100644 --- a/cgroups/src/v2/cpuset.rs +++ b/cgroups/src/v2/cpuset.rs @@ -1,8 +1,8 @@ use anyhow::{Context, Result}; use std::path::Path; -use crate::common; -use oci_spec::{LinuxCpu, LinuxResources}; +use crate::common::{self, ControllerOpt}; +use oci_spec::runtime::LinuxCpu; use super::controller::Controller; @@ -12,8 +12,8 @@ const CGROUP_CPUSET_MEMS: &str = "cpuset.mems"; pub struct CpuSet {} impl Controller for CpuSet { - fn apply(linux_resources: &LinuxResources, cgroup_path: &Path) -> Result<()> { - if let Some(cpuset) = &linux_resources.cpu { + fn apply(controller_opt: &ControllerOpt, cgroup_path: &Path) -> Result<()> { + if let Some(cpuset) = &controller_opt.resources.cpu { Self::apply(cgroup_path, cpuset) .context("failed to apply cpuset resource restrictions")?; } diff --git a/cgroups/src/v2/devices/controller.rs b/cgroups/src/v2/devices/controller.rs index 6dfdd9c8b..306a008e0 100644 --- a/cgroups/src/v2/devices/controller.rs +++ b/cgroups/src/v2/devices/controller.rs @@ -6,9 +6,9 @@ use anyhow::Result; use super::*; use nix::fcntl::OFlag; use nix::sys::stat::Mode; -use oci_spec::{LinuxDeviceCgroup, LinuxResources}; +use oci_spec::runtime::LinuxDeviceCgroup; -use crate::common::{default_allow_devices, default_devices}; +use crate::common::{default_allow_devices, default_devices, ControllerOpt}; use crate::v2::controller::Controller; const LICENSE: &str = "Apache"; @@ -16,12 +16,12 @@ const LICENSE: &str = "Apache"; pub struct Devices {} impl Controller for Devices { - fn apply(linux_resources: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { #[cfg(not(feature = "cgroupsv2_devices"))] return Ok(()); #[cfg(feature = "cgroupsv2_devices")] - return Self::apply_devices(cgroup_root, &linux_resources.devices); + return Self::apply_devices(cgroup_root, &controller_opt.resources.devices); } } diff --git a/cgroups/src/v2/devices/emulator.rs b/cgroups/src/v2/devices/emulator.rs index 960fa5ebc..1bd58ab0a 100644 --- a/cgroups/src/v2/devices/emulator.rs +++ b/cgroups/src/v2/devices/emulator.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use oci_spec::*; +use oci_spec::runtime::{LinuxDeviceCgroup, LinuxDeviceType}; // For cgroup v1 compatiblity, runc implements a device emulator to caculate the final rules given // a list of user-defined rules. @@ -28,17 +28,17 @@ impl Emulator { } } - pub fn add_rules(&mut self, rules: &[oci_spec::LinuxDeviceCgroup]) -> Result<()> { + pub fn add_rules(&mut self, rules: &[LinuxDeviceCgroup]) -> Result<()> { for rule in rules { self.add_rule(rule)?; } Ok(()) } - pub fn add_rule(&mut self, rule: &oci_spec::LinuxDeviceCgroup) -> Result<()> { + pub fn add_rule(&mut self, rule: &LinuxDeviceCgroup) -> Result<()> { // special case, switch to blacklist or whitelist and clear all existing rules // NOTE: we ignore other fields when type='a', this is same as cgroup v1 and runc - if rule.typ.unwrap_or_default() == oci_spec::LinuxDeviceType::A { + if rule.typ.unwrap_or_default() == LinuxDeviceType::A { self.default_allow = rule.allow; self.rules.clear(); return Ok(()); diff --git a/cgroups/src/v2/devices/program.rs b/cgroups/src/v2/devices/program.rs index e30be5d61..bc17801ae 100644 --- a/cgroups/src/v2/devices/program.rs +++ b/cgroups/src/v2/devices/program.rs @@ -1,5 +1,5 @@ use anyhow::{bail, Result}; -use oci_spec::*; +use oci_spec::runtime::*; use rbpf::disassembler::disassemble; use rbpf::insn_builder::Arch as RbpfArch; @@ -249,7 +249,7 @@ fn bpf_cgroup_dev_ctx( mod tests { use super::*; - fn build_bpf_program(rules: &Option>) -> Result { + fn build_bpf_program(rules: &Option>) -> Result { let mut em = crate::v2::devices::emulator::Emulator::with_default_allow(false); if let Some(rules) = rules { em.add_rules(rules)?; diff --git a/cgroups/src/v2/freezer.rs b/cgroups/src/v2/freezer.rs index 825053025..a5a464291 100644 --- a/cgroups/src/v2/freezer.rs +++ b/cgroups/src/v2/freezer.rs @@ -7,7 +7,7 @@ use std::{ time::Duration, }; -use oci_spec::{FreezerState, LinuxResources}; +use crate::common::{ControllerOpt, FreezerState}; use super::controller::Controller; @@ -17,8 +17,8 @@ const CGROUP_EVENTS: &str = "cgroup.events"; pub struct Freezer {} impl Controller for Freezer { - fn apply(linux_resources: &LinuxResources, cgroup_path: &Path) -> Result<()> { - if let Some(freezer_state) = linux_resources.freezer { + fn apply(controller_opt: &ControllerOpt, cgroup_path: &Path) -> Result<()> { + if let Some(freezer_state) = controller_opt.freezer_state { Self::apply(freezer_state, cgroup_path).context("failed to apply freezer")?; } @@ -122,8 +122,8 @@ impl Freezer { #[cfg(test)] mod tests { use super::*; + use crate::common::FreezerState; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::FreezerState; use std::sync::Arc; #[test] diff --git a/cgroups/src/v2/hugetlb.rs b/cgroups/src/v2/hugetlb.rs index 9b675ba4e..9ac0c7d1d 100644 --- a/cgroups/src/v2/hugetlb.rs +++ b/cgroups/src/v2/hugetlb.rs @@ -3,18 +3,18 @@ use std::{collections::HashMap, path::Path}; use super::controller::Controller; use crate::{ - common, + common::{self, ControllerOpt}, stats::{parse_single_value, supported_page_sizes, HugeTlbStats, StatsProvider}, }; -use oci_spec::{LinuxHugepageLimit, LinuxResources}; +use oci_spec::runtime::LinuxHugepageLimit; pub struct HugeTlb {} impl Controller for HugeTlb { - fn apply(linux_resources: &LinuxResources, cgroup_root: &std::path::Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &std::path::Path) -> Result<()> { log::debug!("Apply hugetlb cgroup v2 config"); - if let Some(hugepage_limits) = linux_resources.hugepage_limits.as_ref() { + if let Some(hugepage_limits) = controller_opt.resources.hugepage_limits.as_ref() { for hugetlb in hugepage_limits { Self::apply(cgroup_root, hugetlb) .context("failed to apply hugetlb resource restrictions")? @@ -88,7 +88,7 @@ impl HugeTlb { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxHugepageLimit; + use oci_spec::runtime::LinuxHugepageLimit; use std::fs::read_to_string; #[test] diff --git a/cgroups/src/v2/io.rs b/cgroups/src/v2/io.rs index ea28e7851..c714f29d4 100644 --- a/cgroups/src/v2/io.rs +++ b/cgroups/src/v2/io.rs @@ -3,12 +3,12 @@ use std::path::{Path, PathBuf}; use anyhow::{bail, Context, Result}; use crate::{ - common, + common::{self, ControllerOpt}, stats::{self, BlkioDeviceStat, BlkioStats, StatsProvider}, }; use super::controller::Controller; -use oci_spec::{LinuxBlockIo, LinuxResources}; +use oci_spec::runtime::LinuxBlockIo; const CGROUP_BFQ_IO_WEIGHT: &str = "io.bfq.weight"; const CGROUP_IO_WEIGHT: &str = "io.weight"; @@ -17,9 +17,9 @@ const CGROUP_IO_STAT: &str = "io.stat"; pub struct Io {} impl Controller for Io { - fn apply(linux_resource: &LinuxResources, cgroup_root: &Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &Path) -> Result<()> { log::debug!("Apply io cgroup v2 config"); - if let Some(io) = &linux_resource.block_io { + if let Some(io) = &controller_opt.resources.block_io { Self::apply(cgroup_root, io).context("failed to apply io resource restrictions")?; } Ok(()) @@ -151,7 +151,7 @@ mod test { use super::*; use crate::test::{create_temp_dir, set_fixture, setup}; - use oci_spec::{LinuxBlockIo, LinuxThrottleDevice, LinuxWeightDevice}; + use oci_spec::runtime::{LinuxBlockIo, LinuxThrottleDevice, LinuxWeightDevice}; use std::fs; struct BlockIoBuilder { block_io: LinuxBlockIo, diff --git a/cgroups/src/v2/manager.rs b/cgroups/src/v2/manager.rs index b20588c3b..ad20ee838 100644 --- a/cgroups/src/v2/manager.rs +++ b/cgroups/src/v2/manager.rs @@ -7,7 +7,6 @@ use std::{ use anyhow::{bail, Result}; use nix::unistd::Pid; -use oci_spec::{FreezerState, LinuxResources}; #[cfg(feature = "cgroupsv2_devices")] use super::devices::Devices; @@ -26,7 +25,7 @@ use super::{ unified::Unified, }; use crate::{ - common::{self, CgroupManager, PathBufExt, CGROUP_PROCS}, + common::{self, CgroupManager, ControllerOpt, FreezerState, PathBufExt, CGROUP_PROCS}, stats::{Stats, StatsProvider}, }; @@ -122,26 +121,26 @@ impl CgroupManager for Manager { Ok(()) } - fn apply(&self, linux_resources: &LinuxResources) -> Result<()> { + fn apply(&self, controller_opt: &ControllerOpt) -> Result<()> { for controller in CONTROLLER_TYPES { match controller { - ControllerType::Cpu => Cpu::apply(linux_resources, &self.full_path)?, - ControllerType::CpuSet => CpuSet::apply(linux_resources, &self.full_path)?, - ControllerType::HugeTlb => HugeTlb::apply(linux_resources, &self.full_path)?, - ControllerType::Io => Io::apply(linux_resources, &self.full_path)?, - ControllerType::Memory => Memory::apply(linux_resources, &self.full_path)?, - ControllerType::Pids => Pids::apply(linux_resources, &self.full_path)?, - ControllerType::Freezer => Freezer::apply(linux_resources, &self.full_path)?, + ControllerType::Cpu => Cpu::apply(controller_opt, &self.full_path)?, + ControllerType::CpuSet => CpuSet::apply(controller_opt, &self.full_path)?, + ControllerType::HugeTlb => HugeTlb::apply(controller_opt, &self.full_path)?, + ControllerType::Io => Io::apply(controller_opt, &self.full_path)?, + ControllerType::Memory => Memory::apply(controller_opt, &self.full_path)?, + ControllerType::Pids => Pids::apply(controller_opt, &self.full_path)?, + ControllerType::Freezer => Freezer::apply(controller_opt, &self.full_path)?, } } #[cfg(feature = "cgroupsv2_devices")] - Devices::apply(linux_resources, &self.cgroup_path)?; + Devices::apply(controller_opt, &self.cgroup_path)?; for pseudoctlr in PSEUDO_CONTROLLER_TYPES { if let PseudoControllerType::Unified = pseudoctlr { Unified::apply( - linux_resources, + controller_opt, &self.cgroup_path, self.get_available_controllers()?, )? @@ -159,11 +158,12 @@ impl CgroupManager for Manager { } fn freeze(&self, state: FreezerState) -> Result<()> { - let linux_resources = LinuxResources { - freezer: Some(state), + let controller_opt = ControllerOpt { + resources: Default::default(), + freezer_state: Some(state), ..Default::default() }; - Freezer::apply(&linux_resources, &self.full_path) + Freezer::apply(&controller_opt, &self.full_path) } fn stats(&self) -> Result { diff --git a/cgroups/src/v2/memory.rs b/cgroups/src/v2/memory.rs index 909a5e616..f4dde1ca9 100644 --- a/cgroups/src/v2/memory.rs +++ b/cgroups/src/v2/memory.rs @@ -1,10 +1,10 @@ use anyhow::{bail, Context, Result}; use std::path::Path; -use oci_spec::{LinuxMemory, LinuxResources}; +use oci_spec::runtime::LinuxMemory; use crate::{ - common, + common::{self, ControllerOpt}, stats::{self, MemoryData, MemoryStats, StatsProvider}, }; @@ -18,8 +18,8 @@ const MEMORY_STAT: &str = "memory.stat"; pub struct Memory {} impl Controller for Memory { - fn apply(linux_resources: &LinuxResources, cgroup_path: &Path) -> Result<()> { - if let Some(memory) = &linux_resources.memory { + fn apply(controller_opt: &ControllerOpt, cgroup_path: &Path) -> Result<()> { + if let Some(memory) = &controller_opt.resources.memory { Self::apply(cgroup_path, memory) .context("failed to apply memory resource restrictions")?; } @@ -129,7 +129,7 @@ impl Memory { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxMemory; + use oci_spec::runtime::LinuxMemory; use std::fs::read_to_string; #[test] diff --git a/cgroups/src/v2/pids.rs b/cgroups/src/v2/pids.rs index e6dfb3c78..57449446e 100644 --- a/cgroups/src/v2/pids.rs +++ b/cgroups/src/v2/pids.rs @@ -3,19 +3,19 @@ use std::path::Path; use anyhow::{Context, Result}; use crate::{ - common, + common::{self, ControllerOpt}, stats::{self, PidStats, StatsProvider}, }; use super::controller::Controller; -use oci_spec::{LinuxPids, LinuxResources}; +use oci_spec::runtime::LinuxPids; pub struct Pids {} impl Controller for Pids { - fn apply(linux_resource: &LinuxResources, cgroup_root: &std::path::Path) -> Result<()> { + fn apply(controller_opt: &ControllerOpt, cgroup_root: &std::path::Path) -> Result<()> { log::debug!("Apply pids cgroup v2 config"); - if let Some(pids) = &linux_resource.pids { + if let Some(pids) = &controller_opt.resources.pids { Self::apply(cgroup_root, pids).context("failed to apply pids resource restrictions")?; } Ok(()) @@ -45,7 +45,7 @@ impl Pids { mod tests { use super::*; use crate::test::{create_temp_dir, set_fixture}; - use oci_spec::LinuxPids; + use oci_spec::runtime::LinuxPids; #[test] fn test_set_pids() { diff --git a/cgroups/src/v2/systemd_manager.rs b/cgroups/src/v2/systemd_manager.rs index 339189d56..f50ed38da 100644 --- a/cgroups/src/v2/systemd_manager.rs +++ b/cgroups/src/v2/systemd_manager.rs @@ -5,7 +5,6 @@ use std::{ use anyhow::{anyhow, bail, Result}; use nix::unistd::Pid; -use oci_spec::{FreezerState, LinuxResources}; use std::path::{Path, PathBuf}; #[cfg(feature = "cgroupsv2_devices")] @@ -14,7 +13,7 @@ use super::{ controller::Controller, controller_type::ControllerType, cpu::Cpu, cpuset::CpuSet, freezer::Freezer, hugetlb::HugeTlb, io::Io, memory::Memory, pids::Pids, }; -use crate::common::{self, CgroupManager, PathBufExt}; +use crate::common::{self, CgroupManager, ControllerOpt, FreezerState, PathBufExt}; use crate::stats::Stats; const CGROUP_PROCS: &str = "cgroup.procs"; @@ -227,21 +226,21 @@ impl CgroupManager for SystemDCGroupManager { Ok(()) } - fn apply(&self, linux_resources: &LinuxResources) -> Result<()> { + fn apply(&self, controller_opt: &ControllerOpt) -> Result<()> { for controller in CONTROLLER_TYPES { match controller { - ControllerType::Cpu => Cpu::apply(linux_resources, &self.full_path)?, - ControllerType::CpuSet => CpuSet::apply(linux_resources, &self.full_path)?, - ControllerType::HugeTlb => HugeTlb::apply(linux_resources, &self.full_path)?, - ControllerType::Io => Io::apply(linux_resources, &self.full_path)?, - ControllerType::Memory => Memory::apply(linux_resources, &self.full_path)?, - ControllerType::Pids => Pids::apply(linux_resources, &self.full_path)?, - ControllerType::Freezer => Freezer::apply(linux_resources, &self.full_path)?, + ControllerType::Cpu => Cpu::apply(controller_opt, &self.full_path)?, + ControllerType::CpuSet => CpuSet::apply(controller_opt, &self.full_path)?, + ControllerType::HugeTlb => HugeTlb::apply(controller_opt, &self.full_path)?, + ControllerType::Io => Io::apply(controller_opt, &self.full_path)?, + ControllerType::Memory => Memory::apply(controller_opt, &self.full_path)?, + ControllerType::Pids => Pids::apply(controller_opt, &self.full_path)?, + ControllerType::Freezer => Freezer::apply(controller_opt, &self.full_path)?, } } #[cfg(feature = "cgroupsv2_devices")] - Devices::apply(linux_resources, &self.full_path)?; + Devices::apply(controller_opt, &self.full_path)?; Ok(()) } @@ -250,11 +249,12 @@ impl CgroupManager for SystemDCGroupManager { } fn freeze(&self, state: FreezerState) -> Result<()> { - let linux_resources = LinuxResources { - freezer: Some(state), + let controller_opt = ControllerOpt { + resources: Default::default(), + freezer_state: Some(state), ..Default::default() }; - Freezer::apply(&linux_resources, &self.full_path) + Freezer::apply(&controller_opt, &self.full_path) } fn stats(&self) -> Result { diff --git a/cgroups/src/v2/unified.rs b/cgroups/src/v2/unified.rs index cdb648146..e35e53eb5 100644 --- a/cgroups/src/v2/unified.rs +++ b/cgroups/src/v2/unified.rs @@ -1,20 +1,19 @@ use std::path::Path; use anyhow::{Context, Result}; -use oci_spec::LinuxResources; use super::controller_type::ControllerType; -use crate::common; +use crate::common::{self, ControllerOpt}; pub struct Unified {} impl Unified { pub fn apply( - linux_resources: &LinuxResources, + controller_opt: &ControllerOpt, cgroup_path: &Path, controllers: Vec, ) -> Result<()> { - if let Some(unified) = &linux_resources.unified { + if let Some(unified) = &controller_opt.resources.unified { log::debug!("Apply unified cgroup config"); for (cgroup_file, value) in unified { common::write_cgroup_file_str(cgroup_path.join(cgroup_file), value).map_err( @@ -49,6 +48,8 @@ mod tests { use std::array::IntoIter; use std::fs; + use oci_spec::runtime::LinuxResources; + use crate::test::{create_temp_dir, set_fixture}; use crate::v2::controller_type::ControllerType; @@ -75,8 +76,13 @@ mod tests { ..Default::default() }; + let controller_opt = ControllerOpt { + resources, + ..Default::default() + }; + // act - Unified::apply(&resources, &tmp, vec![]).expect("apply unified"); + Unified::apply(&controller_opt, &tmp, vec![]).expect("apply unified"); // assert let hugetlb_limit = fs::read_to_string(hugetlb_limit_path).expect("read hugetlb limit"); @@ -105,8 +111,13 @@ mod tests { ..Default::default() }; + let controller_opt = ControllerOpt { + resources, + ..Default::default() + }; + // act - let result = Unified::apply(&resources, &tmp, vec![]); + let result = Unified::apply(&controller_opt, &tmp, vec![]); // assert assert!(result.is_err()); @@ -131,9 +142,14 @@ mod tests { ..Default::default() }; + let controller_opt = ControllerOpt { + resources, + ..Default::default() + }; + // act let result = Unified::apply( - &resources, + &controller_opt, &tmp, vec![ControllerType::HugeTlb, ControllerType::Cpu], ); diff --git a/src/capabilities.rs b/src/capabilities.rs index 6f1e6ace0..66f515d91 100644 --- a/src/capabilities.rs +++ b/src/capabilities.rs @@ -1,19 +1,126 @@ //! Handles Management of Capabilities use crate::syscall::Syscall; +use caps::Capability as CapsCapability; use caps::*; use anyhow::Result; -use oci_spec::LinuxCapabilities; +use oci_spec::runtime::{Capabilities, Capability as SpecCapability, LinuxCapabilities}; /// Converts a list of capability types to capabilities has set -fn to_set(caps: &[Capability]) -> CapsHashSet { +fn to_set(caps: &Capabilities) -> CapsHashSet { let mut capabilities = CapsHashSet::new(); + for c in caps { - capabilities.insert(*c); + let cap = c.to_cap(); + capabilities.insert(cap); } capabilities } +pub trait CapabilityExt { + /// Convert self to caps::Capability + fn to_cap(&self) -> caps::Capability; + /// Convert caps::Capability to self + fn from_cap(c: CapsCapability) -> Self; +} + +impl CapabilityExt for SpecCapability { + /// Convert oci::runtime::Capability to caps::Capability + fn to_cap(&self) -> caps::Capability { + match self { + SpecCapability::AuditControl => CapsCapability::CAP_AUDIT_CONTROL, + SpecCapability::AuditRead => CapsCapability::CAP_AUDIT_READ, + SpecCapability::AuditWrite => CapsCapability::CAP_AUDIT_WRITE, + SpecCapability::BlockSuspend => CapsCapability::CAP_BLOCK_SUSPEND, + SpecCapability::Bpf => CapsCapability::CAP_BPF, + SpecCapability::CheckpointRestore => CapsCapability::CAP_CHECKPOINT_RESTORE, + SpecCapability::Chown => CapsCapability::CAP_CHOWN, + SpecCapability::DacOverride => CapsCapability::CAP_DAC_OVERRIDE, + SpecCapability::DacReadSearch => CapsCapability::CAP_DAC_READ_SEARCH, + SpecCapability::Fowner => CapsCapability::CAP_FOWNER, + SpecCapability::Fsetid => CapsCapability::CAP_FSETID, + SpecCapability::IpcLock => CapsCapability::CAP_IPC_LOCK, + SpecCapability::IpcOwner => CapsCapability::CAP_IPC_OWNER, + SpecCapability::Kill => CapsCapability::CAP_KILL, + SpecCapability::Lease => CapsCapability::CAP_LEASE, + SpecCapability::LinuxImmutable => CapsCapability::CAP_LINUX_IMMUTABLE, + SpecCapability::MacAdmin => CapsCapability::CAP_MAC_ADMIN, + SpecCapability::MacOverride => CapsCapability::CAP_MAC_OVERRIDE, + SpecCapability::Mknod => CapsCapability::CAP_MKNOD, + SpecCapability::NetAdmin => CapsCapability::CAP_NET_ADMIN, + SpecCapability::NetBindService => CapsCapability::CAP_NET_BIND_SERVICE, + SpecCapability::NetBroadcast => CapsCapability::CAP_NET_BROADCAST, + SpecCapability::NetRaw => CapsCapability::CAP_NET_RAW, + SpecCapability::Perfmon => CapsCapability::CAP_PERFMON, + SpecCapability::Setgid => CapsCapability::CAP_SETGID, + SpecCapability::Setfcap => CapsCapability::CAP_SETFCAP, + SpecCapability::Setpcap => CapsCapability::CAP_SETPCAP, + SpecCapability::Setuid => CapsCapability::CAP_SETUID, + SpecCapability::SysAdmin => CapsCapability::CAP_SYS_ADMIN, + SpecCapability::SysBoot => CapsCapability::CAP_SYS_BOOT, + SpecCapability::SysChroot => CapsCapability::CAP_SYS_CHROOT, + SpecCapability::SysModule => CapsCapability::CAP_SYS_MODULE, + SpecCapability::SysNice => CapsCapability::CAP_SYS_NICE, + SpecCapability::SysPacct => CapsCapability::CAP_SYS_PACCT, + SpecCapability::SysPtrace => CapsCapability::CAP_SYS_PTRACE, + SpecCapability::SysRawio => CapsCapability::CAP_SYS_RAWIO, + SpecCapability::SysResource => CapsCapability::CAP_SYS_RESOURCE, + SpecCapability::SysTime => CapsCapability::CAP_SYS_TIME, + SpecCapability::SysTtyConfig => CapsCapability::CAP_SYS_TTY_CONFIG, + SpecCapability::Syslog => CapsCapability::CAP_SYSLOG, + SpecCapability::WakeAlarm => CapsCapability::CAP_WAKE_ALARM, + } + } + + /// Convert caps::Capability to oci::runtime::Capability + fn from_cap(c: CapsCapability) -> SpecCapability { + match c { + CapsCapability::CAP_AUDIT_CONTROL => SpecCapability::AuditControl, + CapsCapability::CAP_AUDIT_READ => SpecCapability::AuditRead, + CapsCapability::CAP_AUDIT_WRITE => SpecCapability::AuditWrite, + CapsCapability::CAP_BLOCK_SUSPEND => SpecCapability::BlockSuspend, + CapsCapability::CAP_BPF => SpecCapability::Bpf, + CapsCapability::CAP_CHECKPOINT_RESTORE => SpecCapability::CheckpointRestore, + CapsCapability::CAP_CHOWN => SpecCapability::Chown, + CapsCapability::CAP_DAC_OVERRIDE => SpecCapability::DacOverride, + CapsCapability::CAP_DAC_READ_SEARCH => SpecCapability::DacReadSearch, + CapsCapability::CAP_FOWNER => SpecCapability::Fowner, + CapsCapability::CAP_FSETID => SpecCapability::Fsetid, + CapsCapability::CAP_IPC_LOCK => SpecCapability::IpcLock, + CapsCapability::CAP_IPC_OWNER => SpecCapability::IpcOwner, + CapsCapability::CAP_KILL => SpecCapability::Kill, + CapsCapability::CAP_LEASE => SpecCapability::Lease, + CapsCapability::CAP_LINUX_IMMUTABLE => SpecCapability::LinuxImmutable, + CapsCapability::CAP_MAC_ADMIN => SpecCapability::MacAdmin, + CapsCapability::CAP_MAC_OVERRIDE => SpecCapability::MacOverride, + CapsCapability::CAP_MKNOD => SpecCapability::Mknod, + CapsCapability::CAP_NET_ADMIN => SpecCapability::NetAdmin, + CapsCapability::CAP_NET_BIND_SERVICE => SpecCapability::NetBindService, + CapsCapability::CAP_NET_BROADCAST => SpecCapability::NetBroadcast, + CapsCapability::CAP_NET_RAW => SpecCapability::NetRaw, + CapsCapability::CAP_PERFMON => SpecCapability::Perfmon, + CapsCapability::CAP_SETGID => SpecCapability::Setgid, + CapsCapability::CAP_SETFCAP => SpecCapability::Setfcap, + CapsCapability::CAP_SETPCAP => SpecCapability::Setpcap, + CapsCapability::CAP_SETUID => SpecCapability::Setuid, + CapsCapability::CAP_SYS_ADMIN => SpecCapability::SysAdmin, + CapsCapability::CAP_SYS_BOOT => SpecCapability::SysBoot, + CapsCapability::CAP_SYS_CHROOT => SpecCapability::SysChroot, + CapsCapability::CAP_SYS_MODULE => SpecCapability::SysModule, + CapsCapability::CAP_SYS_NICE => SpecCapability::SysNice, + CapsCapability::CAP_SYS_PACCT => SpecCapability::SysPacct, + CapsCapability::CAP_SYS_PTRACE => SpecCapability::SysPtrace, + CapsCapability::CAP_SYS_RAWIO => SpecCapability::SysRawio, + CapsCapability::CAP_SYS_RESOURCE => SpecCapability::SysResource, + CapsCapability::CAP_SYS_TIME => SpecCapability::SysTime, + CapsCapability::CAP_SYS_TTY_CONFIG => SpecCapability::SysTtyConfig, + CapsCapability::CAP_SYSLOG => SpecCapability::Syslog, + CapsCapability::CAP_WAKE_ALARM => SpecCapability::WakeAlarm, + CapsCapability::__Nonexhaustive => unreachable!("invalid capability"), + } + } +} + /// reset capabilities of process calling this to effective capabilities /// effective capability set is set of capabilities used by kernel to perform checks /// see https://man7.org/linux/man-pages/man7/capabilities.7.html for more information @@ -68,4 +175,12 @@ mod tests { .collect(); assert_eq!(set_capability_args, vec![caps::all()]); } + + #[test] + fn test_convert_oci_spec_to_caps_type() { + let chown = oci_spec::runtime::Capability::Chown; + + let cap = chown.to_cap(); + assert_eq!(cap, Capability::CAP_CHOWN); + } } diff --git a/src/commands/delete.rs b/src/commands/delete.rs index 97e83c474..b12cf4ad8 100644 --- a/src/commands/delete.rs +++ b/src/commands/delete.rs @@ -44,7 +44,7 @@ impl Delete { if container.root.exists() { let config_absolute_path = container.root.join("config.json"); log::debug!("load spec from {:?}", config_absolute_path); - let spec = oci_spec::Spec::load(config_absolute_path)?; + let spec = oci_spec::runtime::Spec::load(config_absolute_path)?; log::debug!("spec: {:?}", spec); // remove the directory storing container state diff --git a/src/commands/pause.rs b/src/commands/pause.rs index 7010698b6..3200086bb 100644 --- a/src/commands/pause.rs +++ b/src/commands/pause.rs @@ -9,7 +9,7 @@ use crate::container::Container; use crate::container::ContainerStatus; use crate::utils; use cgroups; -use oci_spec::FreezerState; +use cgroups::common::FreezerState; /// Structure to implement pause command #[derive(Clap, Debug)] diff --git a/src/commands/ps.rs b/src/commands/ps.rs index ac6f17163..854bad9db 100644 --- a/src/commands/ps.rs +++ b/src/commands/ps.rs @@ -25,7 +25,7 @@ impl Ps { if container.root.exists() { let config_absolute_path = container.root.join("config.json"); log::debug!("load spec from {:?}", config_absolute_path); - let spec = oci_spec::Spec::load(config_absolute_path)?; + let spec = oci_spec::runtime::Spec::load(config_absolute_path)?; log::debug!("spec: {:?}", spec); let cgroups_path = utils::get_cgroup_path( &spec.linux.context("no linux in spec")?.cgroups_path, diff --git a/src/commands/resume.rs b/src/commands/resume.rs index 234554148..a64dd19e1 100644 --- a/src/commands/resume.rs +++ b/src/commands/resume.rs @@ -9,7 +9,7 @@ use crate::container::Container; use crate::container::ContainerStatus; use crate::utils; use cgroups; -use oci_spec::FreezerState; +use cgroups::common::FreezerState; /// Structure to implement resume command #[derive(Clap, Debug)] diff --git a/src/commands/spec_json.rs b/src/commands/spec_json.rs index 38acc129b..4ae9e05fc 100644 --- a/src/commands/spec_json.rs +++ b/src/commands/spec_json.rs @@ -1,6 +1,6 @@ use anyhow::Result; use clap::Clap; -use oci_spec::Spec; +use oci_spec::runtime::Spec; use serde_json::to_writer_pretty; use std::fs::File; diff --git a/src/commands/start.rs b/src/commands/start.rs index b767cd440..8d58d6b1d 100644 --- a/src/commands/start.rs +++ b/src/commands/start.rs @@ -37,7 +37,7 @@ impl Start { } let spec_path = container.root.join("config.json"); - let spec = oci_spec::Spec::load(spec_path).context("failed to load spec")?; + let spec = oci_spec::runtime::Spec::load(spec_path).context("failed to load spec")?; if let Some(hooks) = spec.hooks.as_ref() { // While prestart is marked as deprecated in the OCI spec, the docker and integration test still // uses it. diff --git a/src/container/builder_impl.rs b/src/container/builder_impl.rs index 24a084cff..042f3dd89 100644 --- a/src/container/builder_impl.rs +++ b/src/container/builder_impl.rs @@ -8,7 +8,7 @@ use crate::{ }; use anyhow::{Context, Result}; use cgroups; -use oci_spec::Spec; +use oci_spec::runtime::Spec; use std::{fs, io::Write, os::unix::prelude::RawFd, path::PathBuf}; use super::{Container, ContainerStatus}; @@ -153,12 +153,16 @@ impl<'a> ContainerBuilderImpl<'a> { log::debug!("init pid is {:?}", init_pid); if self.rootless.is_none() && linux.resources.is_some() && self.init { + let controller_opt = cgroups::common::ControllerOpt { + resources: linux.resources.clone().unwrap(), + ..Default::default() + }; cmanager .add_task(init_pid) .context("Failed to add tasks to cgroup manager")?; cmanager - .apply(linux.resources.as_ref().unwrap()) + .apply(&controller_opt) .context("Failed to apply resource limits through cgroup")?; } diff --git a/src/container/container.rs b/src/container/container.rs index cb38abb6c..afcf76e1a 100644 --- a/src/container/container.rs +++ b/src/container/container.rs @@ -8,7 +8,7 @@ use chrono::DateTime; use nix::unistd::Pid; use chrono::Utc; -use oci_spec::Spec; +use oci_spec::runtime::Spec; use procfs::process::Process; use crate::syscall::syscall::create_syscall; @@ -198,7 +198,8 @@ impl Container { } pub fn spec(&self) -> Result { - Spec::load(self.root.join("config.json")) + let spec = Spec::load(self.root.join("config.json"))?; + Ok(spec) } } diff --git a/src/container/init_builder.rs b/src/container/init_builder.rs index ab572a679..493f918fb 100644 --- a/src/container/init_builder.rs +++ b/src/container/init_builder.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Context, Result}; use nix::unistd; -use oci_spec::Spec; +use oci_spec::runtime::Spec; use rootless::Rootless; use std::{ fs, @@ -99,7 +99,7 @@ impl InitContainerBuilder { fn load_spec(&self) -> Result { let source_spec_path = self.bundle.join("config.json"); - let mut spec = oci_spec::Spec::load(&source_spec_path)?; + let mut spec = Spec::load(&source_spec_path)?; if !spec.version.starts_with("1.0") { bail!( "runtime spec has incompatible version '{}'. Only 1.0.X is supported", @@ -110,7 +110,7 @@ impl InitContainerBuilder { Ok(spec) } - fn save_spec(&self, spec: &oci_spec::Spec, container_dir: &Path) -> Result<()> { + fn save_spec(&self, spec: &Spec, container_dir: &Path) -> Result<()> { let target_spec_path = container_dir.join("config.json"); spec.save(target_spec_path)?; Ok(()) diff --git a/src/container/tenant_builder.rs b/src/container/tenant_builder.rs index abb801dca..49e9e29d4 100644 --- a/src/container/tenant_builder.rs +++ b/src/container/tenant_builder.rs @@ -1,7 +1,10 @@ use anyhow::{bail, Context, Result}; use caps::Capability; use nix::unistd; -use oci_spec::{LinuxCapabilities, LinuxNamespace, LinuxNamespaceType, Process, Spec}; +use oci_spec::runtime::{ + Capabilities as SpecCapabilities, Capability as SpecCapability, LinuxCapabilities, + LinuxNamespace, LinuxNamespaceType, Process, Spec, +}; use procfs::process::Namespace; use std::{ @@ -13,6 +16,7 @@ use std::{ str::FromStr, }; +use crate::capabilities::CapabilityExt; use crate::{notify_socket::NotifySocket, rootless::Rootless, tty, utils}; use super::{builder::ContainerBuilder, builder_impl::ContainerBuilderImpl, Container}; @@ -136,7 +140,7 @@ impl TenantContainerBuilder { fn load_init_spec(&self, container_dir: &Path) -> Result { let spec_path = container_dir.join("config.json"); - let spec = oci_spec::Spec::load(spec_path).context("failed to load spec")?; + let spec = Spec::load(spec_path).context("failed to load spec")?; Ok(spec) } @@ -196,8 +200,7 @@ impl TenantContainerBuilder { ); } - spec.process.as_mut().context("no process in spec")?.cwd = - cwd.to_string_lossy().to_string(); + spec.process.as_mut().context("no process in spec")?.cwd = cwd.to_path_buf(); } Ok(()) @@ -247,6 +250,9 @@ impl TenantContainerBuilder { caps.push(Capability::from_str(cap)?); } + let caps: SpecCapabilities = + caps.iter().map(|c| SpecCapability::from_cap(*c)).collect(); + if let Some(ref mut spec_caps) = spec .process .as_mut() @@ -257,27 +263,27 @@ impl TenantContainerBuilder { .ambient .as_mut() .context("no ambient caps in process spec")? - .append(&mut caps.clone()); + .extend(&caps); spec_caps .bounding .as_mut() .context("no bounding caps in process spec")? - .append(&mut caps.clone()); + .extend(&caps); spec_caps .effective .as_mut() .context("no effective caps in process spec")? - .append(&mut caps.clone()); + .extend(&caps); spec_caps .inheritable .as_mut() .context("no inheritable caps in process spec")? - .append(&mut caps.clone()); + .extend(&caps); spec_caps .permitted .as_mut() .context("no permitted caps in process spec")? - .append(&mut caps); + .extend(&caps); } else { spec.process .as_mut() diff --git a/src/hooks.rs b/src/hooks.rs index 8f819b572..7b9a325cf 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Context, Result}; use nix::{sys::signal, unistd::Pid}; -use oci_spec::Hook; +use oci_spec::runtime::Hook; use std::{ collections::HashMap, fmt, io::ErrorKind, io::Write, os::unix::prelude::CommandExt, process, thread, time, diff --git a/src/namespaces.rs b/src/namespaces.rs index 981c2aebe..03e92e214 100644 --- a/src/namespaces.rs +++ b/src/namespaces.rs @@ -10,7 +10,7 @@ use crate::syscall::{syscall::create_syscall, Syscall}; use anyhow::{Context, Result}; use nix::{fcntl, sched::CloneFlags, sys::stat, unistd}; -use oci_spec::{LinuxNamespace, LinuxNamespaceType}; +use oci_spec::runtime::{LinuxNamespace, LinuxNamespaceType}; use std::collections; /// Holds information about namespaces @@ -87,7 +87,7 @@ impl Namespaces { mod tests { use super::*; use crate::syscall::test::TestHelperSyscall; - use oci_spec::LinuxNamespaceType; + use oci_spec::runtime::LinuxNamespaceType; fn gen_sample_linux_namespaces() -> Vec { vec![ diff --git a/src/process/init.rs b/src/process/init.rs index 5e348b3b9..6009cbf38 100644 --- a/src/process/init.rs +++ b/src/process/init.rs @@ -7,8 +7,7 @@ use nix::{ sys::statfs, unistd::{self, Gid, Uid}, }; -use oci_spec::User; -use oci_spec::{LinuxNamespaceType, Spec}; +use oci_spec::runtime::{LinuxNamespaceType, Spec, User}; use std::collections::HashMap; use std::{ env, @@ -396,7 +395,8 @@ pub fn container_init( } } - let do_chdir = if proc.cwd.is_empty() { + let cwd = format!("{}", proc.cwd.display()); + let do_chdir = if cwd.is_empty() { false } else { // This chdir must run before setting up the user. @@ -466,7 +466,8 @@ pub fn container_init( // change directory to process.cwd if process.cwd is not empty if do_chdir { - unistd::chdir(&*proc.cwd).with_context(|| format!("Failed to chdir {}", proc.cwd))?; + unistd::chdir(&*proc.cwd) + .with_context(|| format!("Failed to chdir {}", proc.cwd.display()))?; } // Reset the process env based on oci spec. diff --git a/src/rootfs.rs b/src/rootfs.rs index 322296960..0b6345674 100644 --- a/src/rootfs.rs +++ b/src/rootfs.rs @@ -7,11 +7,11 @@ use nix::errno::Errno; use nix::fcntl::{open, OFlag}; use nix::mount::mount as nix_mount; use nix::mount::MsFlags; -use nix::sys::stat::Mode; use nix::sys::stat::{mknod, umask}; +use nix::sys::stat::{Mode, SFlag}; use nix::unistd::{chown, close}; use nix::unistd::{Gid, Uid}; -use oci_spec::{LinuxDevice, LinuxDeviceType, Mount, Spec}; +use oci_spec::runtime::{LinuxDevice, LinuxDeviceType, Mount, Spec}; use std::fs::OpenOptions; use std::fs::{canonicalize, create_dir_all, remove_file}; use std::os::unix::fs::symlink; @@ -222,6 +222,15 @@ fn bind_dev(rootfs: &Path, dev: &LinuxDevice) -> Result<()> { Ok(()) } +fn to_sflag(dev_type: LinuxDeviceType) -> SFlag { + match dev_type { + LinuxDeviceType::A => SFlag::S_IFBLK | SFlag::S_IFCHR | SFlag::S_IFIFO, + LinuxDeviceType::B => SFlag::S_IFBLK, + LinuxDeviceType::C | LinuxDeviceType::U => SFlag::S_IFCHR, + LinuxDeviceType::P => SFlag::S_IFIFO, + } +} + fn mknod_dev(rootfs: &Path, dev: &LinuxDevice) -> Result<()> { fn makedev(major: i64, minor: i64) -> u64 { ((minor & 0xff) @@ -233,7 +242,7 @@ fn mknod_dev(rootfs: &Path, dev: &LinuxDevice) -> Result<()> { let full_container_path = rootfs.join(dev.path.as_in_container()?); mknod( &full_container_path, - dev.typ.to_sflag()?, + to_sflag(dev.typ), Mode::from_bits_truncate(dev.file_mode.unwrap_or(0)), makedev(dev.major, dev.minor), )?; diff --git a/src/rootless.rs b/src/rootless.rs index 7f2d5dd1c..a7db9b0ba 100644 --- a/src/rootless.rs +++ b/src/rootless.rs @@ -1,7 +1,7 @@ use crate::{namespaces::Namespaces, utils}; use anyhow::{bail, Context, Result}; use nix::unistd::Pid; -use oci_spec::{Linux, LinuxIdMapping, LinuxNamespace, LinuxNamespaceType, Mount, Spec}; +use oci_spec::runtime::{Linux, LinuxIdMapping, LinuxNamespace, LinuxNamespaceType, Mount, Spec}; use std::path::Path; use std::process::Command; use std::{env, path::PathBuf}; @@ -231,7 +231,7 @@ pub fn write_gid_mapping(target_pid: Pid, rootless: Option<&Rootless>) -> Result fn write_id_mapping( map_file: &str, - mappings: &[oci_spec::LinuxIdMapping], + mappings: &[LinuxIdMapping], map_binary: Option<&Path>, ) -> Result<()> { let mappings: Vec = mappings diff --git a/src/syscall/linux.rs b/src/syscall/linux.rs index 137d1bb4e..25fdc0986 100644 --- a/src/syscall/linux.rs +++ b/src/syscall/linux.rs @@ -22,7 +22,7 @@ use nix::{ }; use nix::{sched::unshare, sys::stat::Mode}; -use oci_spec::LinuxRlimit; +use oci_spec::runtime::LinuxRlimit; use super::Syscall; use crate::capabilities; diff --git a/src/syscall/syscall.rs b/src/syscall/syscall.rs index c3acbd6b6..15bd53fba 100644 --- a/src/syscall/syscall.rs +++ b/src/syscall/syscall.rs @@ -10,7 +10,7 @@ use nix::{ unistd::{Gid, Uid}, }; -use oci_spec::LinuxRlimit; +use oci_spec::runtime::LinuxRlimit; use crate::syscall::{linux::LinuxSyscall, test::TestHelperSyscall}; diff --git a/src/syscall/test.rs b/src/syscall/test.rs index b7d76bbd0..6259bb70b 100644 --- a/src/syscall/test.rs +++ b/src/syscall/test.rs @@ -2,7 +2,7 @@ use std::{any::Any, cell::RefCell, ffi::OsStr, sync::Arc}; use caps::{errors::CapsError, CapSet, CapsHashSet}; use nix::sched::CloneFlags; -use oci_spec::LinuxRlimit; +use oci_spec::runtime::LinuxRlimit; use super::Syscall;