From d862ca059045dc917c9e8015c1fecf26ebe6c228 Mon Sep 17 00:00:00 2001 From: Manabu Sugimoto Date: Sun, 29 May 2022 16:34:38 +0900 Subject: [PATCH] runk: Handle rootfs path in config.json properly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit enables runk to handle `root.path` in `config.json` properly even if the path is specified by a relative path that includes the single (`.`) or the double (`..`) dots. For example, with a bundle at `/to/bundle` and a rootfs directly under `/to/bundle` such as `/to/bundle/{bin,dev,etc,home,...}`, the `root.path` value can be either `/to/bundle` or just `.`. This behavior conforms to OCI runtime spec. Accordingly, a bundle path managed by runk's status file (`status.json`) always is statically stored as a canonical path. Previously, a bundle path has been got by `oci_state()` of rustjail's API that returns the path as the parent directory path of a rootfs (`root.path`). In case of the kata-agent, this works properly because the kata containers assume that the rootfs path is always `/to/bundle/rootfs`. However in case of standard OCI runtimes, a rootfs can be placed anywhere under a bundle, so the rootfs path doesn't always have to be at a `/to/bundle/rootfs`. Fixes: #4334 Signed-off-by: Manabu Sugimoto --- src/tools/runk/libcontainer/src/builder.rs | 12 ++++++------ src/tools/runk/libcontainer/src/container.rs | 3 ++- src/tools/runk/libcontainer/src/status.rs | 4 +++- src/tools/runk/libcontainer/src/utils.rs | 4 +++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/tools/runk/libcontainer/src/builder.rs b/src/tools/runk/libcontainer/src/builder.rs index 738c639ae2..28bb730461 100644 --- a/src/tools/runk/libcontainer/src/builder.rs +++ b/src/tools/runk/libcontainer/src/builder.rs @@ -37,20 +37,20 @@ impl Container { // If the rootfs path in the spec file is a relative path, // convert it into a canonical path to pass validation of rootfs in the agent. if !&rootfs_path.is_absolute() { - let rootfs_name = rootfs_path - .file_name() - .ok_or_else(|| anyhow!("invalid rootfs name"))?; spec_root.path = bundle_canon - .join(rootfs_name) + .join(rootfs_path) + .canonicalize()? .to_str() .map(|s| s.to_string()) - .ok_or_else(|| anyhow!("failed to convert bundle path"))?; + .ok_or_else(|| { + anyhow!("failed to convert a rootfs path into a canonical path") + })?; } } Ok(ContainerContext { id: self.id, - bundle: self.bundle, + bundle: bundle_canon, state_root: self.root, spec, // TODO: liboci-cli does not support --no-pivot option for create and run command. diff --git a/src/tools/runk/libcontainer/src/container.rs b/src/tools/runk/libcontainer/src/container.rs index d5464e9239..2d8b423178 100644 --- a/src/tools/runk/libcontainer/src/container.rs +++ b/src/tools/runk/libcontainer/src/container.rs @@ -95,6 +95,7 @@ impl ContainerContext { let oci_state = ctr.oci_state()?; let status = Status::new( &self.state_root, + &self.bundle, oci_state, ctr.init_process_start_time, ctr.created, @@ -141,7 +142,7 @@ mod tests { #[test] fn test_get_fifo_path() { - let test_data = PathBuf::from(TEST_BUNDLE_PATH) + let test_data = PathBuf::from(TEST_STATE_ROOT_PATH) .join(TEST_CONTAINER_ID) .join(EXEC_FIFO_FILENAME); let status = create_dummy_status(); diff --git a/src/tools/runk/libcontainer/src/status.rs b/src/tools/runk/libcontainer/src/status.rs index 21ba00cda4..3cd9768b10 100644 --- a/src/tools/runk/libcontainer/src/status.rs +++ b/src/tools/runk/libcontainer/src/status.rs @@ -42,6 +42,7 @@ pub struct Status { impl Status { pub fn new( root: &Path, + bundle: &Path, oci_state: OCIState, process_start_time: u64, created_time: SystemTime, @@ -64,7 +65,7 @@ impl Status { id: oci_state.id, pid: oci_state.pid, root: root.to_path_buf(), - bundle: PathBuf::from(&oci_state.bundle), + bundle: bundle.to_path_buf(), rootfs, process_start_time, created, @@ -209,6 +210,7 @@ mod tests { let oci_state = create_dummy_oci_state(); let created = SystemTime::now(); let status = Status::new( + Path::new(TEST_STATE_ROOT_PATH), Path::new(TEST_BUNDLE_PATH), oci_state.clone(), 1, diff --git a/src/tools/runk/libcontainer/src/utils.rs b/src/tools/runk/libcontainer/src/utils.rs index 5a356d7c2d..dcd9f7f7f1 100644 --- a/src/tools/runk/libcontainer/src/utils.rs +++ b/src/tools/runk/libcontainer/src/utils.rs @@ -45,7 +45,8 @@ pub(crate) mod test_utils { use std::time::SystemTime; pub const TEST_CONTAINER_ID: &str = "test"; - pub const TEST_BUNDLE_PATH: &str = "/test"; + pub const TEST_STATE_ROOT_PATH: &str = "/state"; + pub const TEST_BUNDLE_PATH: &str = "/bundle"; pub const TEST_ANNOTATION: &str = "test"; pub const TEST_CGM_DATA: &str = r#"{ "paths": { @@ -92,6 +93,7 @@ pub(crate) mod test_utils { let oci_state = create_dummy_oci_state(); let created = SystemTime::now(); let status = Status::new( + Path::new(TEST_STATE_ROOT_PATH), Path::new(TEST_BUNDLE_PATH), oci_state.clone(), 1,