diff --git a/crates/libcgroups/src/systemd/manager.rs b/crates/libcgroups/src/systemd/manager.rs index 4f66c151..4b0d9c93 100644 --- a/crates/libcgroups/src/systemd/manager.rs +++ b/crates/libcgroups/src/systemd/manager.rs @@ -61,6 +61,42 @@ struct CgroupsPath { name: String, } +impl TryFrom<&Path> for CgroupsPath { + type Error = anyhow::Error; + + fn try_from(cgroups_path: &Path) -> Result { + // cgroups path may never be empty as it is defaulted to `/youki` + // see 'get_cgroup_path' under utils.rs. + // if cgroups_path was provided it should be of the form [slice]:[prefix]:[name], + // for example: "system.slice:docker:1234". + let mut parent = ""; + let prefix; + let name; + if cgroups_path.starts_with("/youki") { + prefix = "youki"; + name = cgroups_path + .strip_prefix("/youki/")? + .to_str() + .ok_or_else(|| anyhow!("failed to parse cgroups path {:?}", cgroups_path))?; + } else { + let parts = cgroups_path + .to_str() + .ok_or_else(|| anyhow!("failed to parse cgroups path {:?}", cgroups_path))? + .split(':') + .collect::>(); + parent = parts[0]; + prefix = parts[1]; + name = parts[2]; + } + + Ok(CgroupsPath { + parent: parent.to_owned(), + prefix: prefix.to_owned(), + name: name.to_owned(), + }) + } +} + impl Display for CgroupsPath { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}:{}:{}", self.parent, self.prefix, self.name) @@ -89,7 +125,9 @@ impl Manager { container_name: String, use_system: bool, ) -> Result { - let destructured_path = Self::destructure_cgroups_path(&cgroups_path) + let destructured_path = cgroups_path + .as_path() + .try_into() .with_context(|| format!("failed to destructure cgroups path {:?}", cgroups_path))?; let client = match use_system { true => Client::new_system().context("failed to create system dbus client")?, @@ -111,38 +149,6 @@ impl Manager { }) } - fn destructure_cgroups_path(cgroups_path: &Path) -> Result { - // cgroups path may never be empty as it is defaulted to `/youki` - // see 'get_cgroup_path' under utils.rs. - // if cgroups_path was provided it should be of the form [slice]:[prefix]:[name], - // for example: "system.slice:docker:1234". - let mut parent = ""; - let prefix; - let name; - if cgroups_path.starts_with("/youki") { - prefix = "youki"; - name = cgroups_path - .strip_prefix("/youki/")? - .to_str() - .ok_or_else(|| anyhow!("failed to parse cgroups path"))?; - } else { - let parts = cgroups_path - .to_str() - .ok_or_else(|| anyhow!("failed to parse cgroups path"))? - .split(':') - .collect::>(); - parent = parts[0]; - prefix = parts[1]; - name = parts[2]; - } - - Ok(CgroupsPath { - parent: parent.to_owned(), - prefix: prefix.to_owned(), - name: name.to_owned(), - }) - } - /// get_unit_name returns the unit (scope) name from the path provided by the user /// for example: foo:docker:bar returns in '/docker-bar.scope' fn get_unit_name(cgroups_path: &CgroupsPath) -> String { @@ -425,8 +431,9 @@ mod tests { #[test] fn get_cgroups_path_works_with_a_complex_slice() -> Result<()> { - let cgroups_path = - Manager::destructure_cgroups_path(Path::new("test-a-b.slice:docker:foo")).expect(""); + let cgroups_path = Path::new("test-a-b.slice:docker:foo") + .try_into() + .context("construct path")?; assert_eq!( Manager::construct_cgroups_path(&cgroups_path, &TestSystemdClient {})?.0, @@ -438,8 +445,9 @@ mod tests { #[test] fn get_cgroups_path_works_with_a_simple_slice() -> Result<()> { - let cgroups_path = - Manager::destructure_cgroups_path(Path::new("machine.slice:libpod:foo")).expect(""); + let cgroups_path = Path::new("machine.slice:libpod:foo") + .try_into() + .context("construct path")?; assert_eq!( Manager::construct_cgroups_path(&cgroups_path, &TestSystemdClient {})?.0, @@ -451,7 +459,9 @@ mod tests { #[test] fn get_cgroups_path_works_with_scope() -> Result<()> { - let cgroups_path = Manager::destructure_cgroups_path(Path::new(":docker:foo")).expect(""); + let cgroups_path = Path::new(":docker:foo") + .try_into() + .context("construct path")?; assert_eq!( Manager::construct_cgroups_path(&cgroups_path, &TestSystemdClient {})?.0, diff --git a/crates/libcontainer/src/process/container_intermediate_process.rs b/crates/libcontainer/src/process/container_intermediate_process.rs index 66ce9c5d..1f265ab0 100644 --- a/crates/libcontainer/src/process/container_intermediate_process.rs +++ b/crates/libcontainer/src/process/container_intermediate_process.rs @@ -25,7 +25,7 @@ pub fn container_intermediate_process( // this needs to be done before we create the init process, so that the init // process will already be captured by the cgroup. It also needs to be done // before we enter the user namespace because if a privileged user starts a - // rootless container on a cgroup v1 system we can still fullfill resource + // rootless container on a cgroup v1 system we can still fulfill resource // restrictions through the cgroup fs support (delegation through systemd is // not supported for v1 by us). This only works if the user has not yet been // mapped to an unprivileged user by the user namespace however. diff --git a/docs/.drawio.svg b/docs/.drawio.svg index c2fcf5cc..505da318 100644 --- a/docs/.drawio.svg +++ b/docs/.drawio.svg @@ -1,4 +1,4 @@ - + @@ -115,13 +115,13 @@ - - - + + + -
+
@@ -133,18 +133,18 @@
- + fork(2) - - - + + + -
+
@@ -154,16 +154,16 @@
- + send identifier mapping request - + -
+
unshare(CLONE_NEWUSER) @@ -171,18 +171,18 @@
- + unshare(CLONE_NEWUSER) - + - + -
+
write uid mapping @@ -190,16 +190,16 @@
- + write uid mapping - + -
+
write gid mapping @@ -207,18 +207,18 @@
- + write gid mapping - - - + + + -
+
@@ -228,7 +228,7 @@
- + send mapping written @@ -410,13 +410,13 @@ - + - + -
+
setup cgroup @@ -424,17 +424,17 @@
- + setup cgroup - - + + -
+
unshare(CLONE_NEWPID) @@ -442,16 +442,16 @@
- + unshare(CLONE_NEWPID) - + -
+
set uid and gid @@ -459,7 +459,7 @@
- + set uid and gid