mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-18 17:33:02 +00:00
runk: Align oci spec with oci-spec-rs
Utilized oci-spec-rs to align OCI Spec structures and data representations in runk with the OCI Spec. Fixes #9766 Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
parent
b3eab5ffea
commit
bf813f85f2
1650
src/tools/runk/Cargo.lock
generated
1650
src/tools/runk/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,8 @@ edition = "2018"
|
||||
[dependencies]
|
||||
libcontainer = { path = "./libcontainer" }
|
||||
rustjail = { path = "../../agent/rustjail", features = ["standard-oci-runtime"] }
|
||||
oci = { path = "../../libs/oci" }
|
||||
runtime-spec = { path = "../../libs/runtime-spec" }
|
||||
oci-spec = { version = "0.6.8", features = ["runtime"] }
|
||||
logging = { path = "../../libs/logging" }
|
||||
liboci-cli = "0.0.4"
|
||||
clap = { version = "3.0.6", features = ["derive", "cargo"] }
|
||||
|
@ -8,7 +8,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
rustjail = { path = "../../../agent/rustjail", features = ["standard-oci-runtime"] }
|
||||
oci = { path = "../../../libs/oci" }
|
||||
runtime-spec = { path = "../../../libs/runtime-spec" }
|
||||
oci-spec = { version = "0.6.8", features = ["runtime"] }
|
||||
kata-sys-util = { path = "../../../libs/kata-sys-util" }
|
||||
logging = { path = "../../../libs/logging" }
|
||||
derive_builder = "0.10.2"
|
||||
@ -26,3 +27,4 @@ procfs = "0.14.0"
|
||||
[dev-dependencies]
|
||||
tempfile = "3.3.0"
|
||||
test-utils = { path = "../../../libs/test-utils" }
|
||||
protocols = { path ="../../../libs/protocols" }
|
||||
|
@ -8,7 +8,9 @@ use crate::status::Status;
|
||||
use crate::utils::validate_spec;
|
||||
use anyhow::{anyhow, Result};
|
||||
use derive_builder::Builder;
|
||||
use oci::{ContainerState, Process as OCIProcess, Spec};
|
||||
use oci::{Process as OCIProcess, Spec};
|
||||
use oci_spec::runtime as oci;
|
||||
use runtime_spec::ContainerState;
|
||||
use rustjail::container::update_namespaces;
|
||||
use slog::{debug, Logger};
|
||||
use std::fs::File;
|
||||
@ -105,8 +107,8 @@ impl ActivatedContainer {
|
||||
// If with --process, load process from file.
|
||||
// Otherwise, update process with args and other options.
|
||||
if let Some(process_path) = self.process.as_ref() {
|
||||
spec.process = Some(Self::get_process(process_path)?);
|
||||
} else if let Some(process) = spec.process.as_mut() {
|
||||
spec.set_process(Some(Self::get_process(process_path)?));
|
||||
} else if let Some(process) = spec.process_mut().as_mut() {
|
||||
self.update_process(process)?;
|
||||
} else {
|
||||
return Err(anyhow!("process is empty in spec"));
|
||||
@ -118,15 +120,15 @@ impl ActivatedContainer {
|
||||
|
||||
/// Update process with args and other options.
|
||||
fn update_process(&self, process: &mut OCIProcess) -> Result<()> {
|
||||
process.args = self.args.clone();
|
||||
process.no_new_privileges = self.no_new_privs;
|
||||
process.terminal = self.tty;
|
||||
process.set_args(Some(self.args.clone()));
|
||||
process.set_no_new_privileges(Some(self.no_new_privs));
|
||||
process.set_terminal(Some(self.tty));
|
||||
if let Some(cwd) = self.cwd.as_ref() {
|
||||
process.cwd = cwd.as_path().display().to_string();
|
||||
process.set_cwd(cwd.as_path().to_path_buf());
|
||||
}
|
||||
if let Some(process_env) = process.env_mut() {
|
||||
process_env.extend(self.env.iter().map(|kv| format!("{}={}", kv.0, kv.1)));
|
||||
}
|
||||
process
|
||||
.env
|
||||
.extend(self.env.iter().map(|kv| format!("{}={}", kv.0, kv.1)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -143,7 +145,7 @@ mod tests {
|
||||
use crate::status::Status;
|
||||
use crate::utils::test_utils::*;
|
||||
use nix::unistd::getpid;
|
||||
use oci::{Linux, LinuxNamespace, User};
|
||||
use oci_spec::runtime::{LinuxBuilder, LinuxNamespaceBuilder, ProcessBuilder, User};
|
||||
use rustjail::container::TYPETONAME;
|
||||
use scopeguard::defer;
|
||||
use slog::o;
|
||||
@ -193,11 +195,10 @@ mod tests {
|
||||
let pid = getpid().as_raw();
|
||||
|
||||
let mut spec = create_dummy_spec();
|
||||
spec.root.as_mut().unwrap().path = bundle_dir
|
||||
.path()
|
||||
.join(TEST_ROOTFS_PATH)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
spec.root_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_path(bundle_dir.path().join(TEST_ROOTFS_PATH));
|
||||
|
||||
let status = create_custom_dummy_status(&id, pid, root.path(), &spec);
|
||||
status.save().unwrap();
|
||||
@ -223,36 +224,39 @@ mod tests {
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let linux = Linux {
|
||||
namespaces: TYPETONAME
|
||||
let linux = LinuxBuilder::default()
|
||||
.namespaces(
|
||||
TYPETONAME
|
||||
.iter()
|
||||
.filter(|&(_, &name)| name != "user")
|
||||
.map(|ns| LinuxNamespace {
|
||||
r#type: ns.0.to_string(),
|
||||
path: format!("/proc/{}/ns/{}", pid, ns.1),
|
||||
.map(|ns| {
|
||||
LinuxNamespaceBuilder::default()
|
||||
.typ(ns.0.clone())
|
||||
.path(PathBuf::from(&format!("/proc/{}/ns/{}", pid, ns.1)))
|
||||
.build()
|
||||
.unwrap()
|
||||
})
|
||||
.collect(),
|
||||
..Default::default()
|
||||
};
|
||||
spec.linux = Some(linux);
|
||||
spec.process = Some(OCIProcess {
|
||||
terminal: result.tty,
|
||||
console_size: None,
|
||||
user: User::default(),
|
||||
args: result.args.clone(),
|
||||
cwd: result.cwd.clone().unwrap().to_string_lossy().to_string(),
|
||||
env: vec![
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
spec.set_linux(Some(linux));
|
||||
let process = ProcessBuilder::default()
|
||||
.terminal(result.tty)
|
||||
.user(User::default())
|
||||
.args(result.args.clone())
|
||||
.cwd(result.cwd.clone().unwrap().to_string_lossy().to_string())
|
||||
.env(vec![
|
||||
"PATH=/bin:/usr/bin".to_string(),
|
||||
"K1=V1".to_string(),
|
||||
"K2=V2".to_string(),
|
||||
],
|
||||
capabilities: None,
|
||||
rlimits: Vec::new(),
|
||||
no_new_privileges: result.no_new_privs,
|
||||
apparmor_profile: "".to_string(),
|
||||
oom_score_adj: None,
|
||||
selinux_label: "".to_string(),
|
||||
});
|
||||
])
|
||||
.no_new_privileges(result.no_new_privs)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
spec.set_process(Some(process));
|
||||
let launcher = result.clone().create_launcher(&logger).unwrap();
|
||||
assert!(!launcher.init);
|
||||
assert_eq!(launcher.runner.config.spec.unwrap(), spec);
|
||||
@ -269,11 +273,11 @@ mod tests {
|
||||
skip_if_not_root!();
|
||||
let bundle_dir = tempdir().unwrap();
|
||||
let process_file = bundle_dir.path().join(TEST_PROCESS_FILE_NAME);
|
||||
let process_template = OCIProcess {
|
||||
args: vec!["sleep".to_string(), "10".to_string()],
|
||||
cwd: "/".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut process_template = OCIProcess::default();
|
||||
process_template.set_args(Some(vec!["sleep".to_string(), "10".to_string()]));
|
||||
process_template.set_cwd(PathBuf::from("/"));
|
||||
|
||||
let file = File::create(process_file.clone()).unwrap();
|
||||
serde_json::to_writer(&file, &process_template).unwrap();
|
||||
|
||||
@ -284,11 +288,10 @@ mod tests {
|
||||
let id = "test_activated_container_create_with_process".to_string();
|
||||
let pid = getpid().as_raw();
|
||||
let mut spec = create_dummy_spec();
|
||||
spec.root.as_mut().unwrap().path = bundle_dir
|
||||
.path()
|
||||
.join(TEST_ROOTFS_PATH)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
spec.root_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_path(bundle_dir.path().join(TEST_ROOTFS_PATH));
|
||||
create_activated_dirs(root.path(), &id, bundle_dir.path());
|
||||
|
||||
let status = create_custom_dummy_status(&id, pid, root.path(), &spec);
|
||||
@ -300,7 +303,7 @@ mod tests {
|
||||
let launcher = ActivatedContainerBuilder::default()
|
||||
.id(id)
|
||||
.root(root.into_path())
|
||||
.console_socket(None)
|
||||
.console_socket(Some(PathBuf::from(TEST_CONSOLE_SOCKET_PATH)))
|
||||
.pid_file(None)
|
||||
.tty(true)
|
||||
.cwd(Some(PathBuf::from(TEST_BUNDLE_PATH)))
|
||||
@ -319,7 +322,14 @@ mod tests {
|
||||
assert!(!launcher.init);
|
||||
|
||||
assert_eq!(
|
||||
launcher.runner.config.spec.unwrap().process.unwrap(),
|
||||
launcher
|
||||
.runner
|
||||
.config
|
||||
.spec
|
||||
.unwrap()
|
||||
.process()
|
||||
.clone()
|
||||
.unwrap(),
|
||||
process_template
|
||||
);
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ use nix::{
|
||||
sys::signal::SIGKILL,
|
||||
unistd::{chdir, unlink, Pid},
|
||||
};
|
||||
use oci::{ContainerState, State as OCIState};
|
||||
use procfs;
|
||||
use runtime_spec::{ContainerState, State as OCIState};
|
||||
use rustjail::cgroups::fs::Manager as CgroupManager;
|
||||
use rustjail::{
|
||||
container::{BaseContainer, LinuxContainer, EXEC_FIFO_FILENAME},
|
||||
@ -59,15 +59,18 @@ impl Container {
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("spec config was not present"))?;
|
||||
let linux = spec
|
||||
.linux
|
||||
.linux()
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("linux config was not present"))?;
|
||||
let cpath = if linux.cgroups_path.is_empty() {
|
||||
let cpath = if linux.cgroups_path().is_none() {
|
||||
id.to_string()
|
||||
} else {
|
||||
linux
|
||||
.cgroups_path
|
||||
.cgroups_path()
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.display()
|
||||
.to_string()
|
||||
.trim_start_matches('/')
|
||||
.to_string()
|
||||
};
|
||||
@ -142,13 +145,16 @@ impl Container {
|
||||
.to_str()
|
||||
.ok_or_else(|| anyhow!("invalid bundle path"))?
|
||||
.to_string(),
|
||||
annotations: spec.annotations.clone(),
|
||||
annotations: spec.annotations().clone().unwrap_or_default(),
|
||||
};
|
||||
|
||||
if let Some(hooks) = spec.hooks.as_ref() {
|
||||
if let Some(hooks) = spec.hooks().as_ref() {
|
||||
info!(&logger, "Poststop Hooks");
|
||||
let mut poststop_hookstates = HookStates::new();
|
||||
poststop_hookstates.execute_hooks(&hooks.poststop, Some(oci_state.clone()))?;
|
||||
poststop_hookstates.execute_hooks(
|
||||
&hooks.poststop().clone().unwrap_or_default(),
|
||||
Some(oci_state.clone()),
|
||||
)?;
|
||||
}
|
||||
|
||||
match oci_state.status {
|
||||
@ -281,12 +287,10 @@ impl ContainerLauncher {
|
||||
/// Generate rustjail::Process from OCI::Process
|
||||
fn get_process(&self, logger: &Logger) -> Result<Process> {
|
||||
let spec = self.runner.config.spec.as_ref().unwrap();
|
||||
if spec.process.is_some() {
|
||||
if spec.process().is_some() {
|
||||
Ok(Process::new(
|
||||
logger,
|
||||
spec.process
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("process config was not present in the spec file"))?,
|
||||
spec.process().as_ref().unwrap(),
|
||||
// rustjail::LinuxContainer use the exec_id to identify processes in a container,
|
||||
// so we can get the spawned process by ctr.get_process(exec_id) later.
|
||||
// Since LinuxContainer is temporarily created to spawn one process in each runk invocation,
|
||||
|
@ -6,7 +6,7 @@
|
||||
use crate::container::{load_linux_container, Container, ContainerLauncher};
|
||||
use anyhow::{anyhow, Result};
|
||||
use derive_builder::Builder;
|
||||
use oci::ContainerState;
|
||||
use runtime_spec::ContainerState;
|
||||
use slog::{debug, Logger};
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -113,11 +113,10 @@ mod tests {
|
||||
let pid = getpid().as_raw();
|
||||
|
||||
let mut spec = create_dummy_spec();
|
||||
spec.root.as_mut().unwrap().path = bundle_dir
|
||||
.path()
|
||||
.join(TEST_ROOTFS_PATH)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
spec.root_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_path(bundle_dir.path().join(TEST_ROOTFS_PATH));
|
||||
|
||||
let status = create_custom_dummy_status(&id, pid, root.path(), &spec);
|
||||
status.save().unwrap();
|
||||
|
@ -8,7 +8,7 @@ use crate::status::Status;
|
||||
use crate::utils::{canonicalize_spec_root, validate_spec};
|
||||
use anyhow::{anyhow, Result};
|
||||
use derive_builder::Builder;
|
||||
use oci::Spec;
|
||||
use oci_spec::runtime::Spec;
|
||||
use rustjail::specconv::CreateOpts;
|
||||
use slog::{debug, Logger};
|
||||
use std::path::PathBuf;
|
||||
@ -91,11 +91,11 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::container::CONFIG_FILE_NAME;
|
||||
use crate::utils::test_utils::*;
|
||||
use oci_spec::runtime::Process;
|
||||
use slog::o;
|
||||
use std::fs::{create_dir, File};
|
||||
use std::path::Path;
|
||||
use tempfile::tempdir;
|
||||
use test_utils::skip_if_not_root;
|
||||
|
||||
#[test]
|
||||
fn test_init_container_validate() {
|
||||
@ -126,11 +126,10 @@ mod tests {
|
||||
let file = File::create(config_file).unwrap();
|
||||
serde_json::to_writer(&file, &spec).unwrap();
|
||||
|
||||
spec.root.as_mut().unwrap().path = bundle_dir
|
||||
.path()
|
||||
.join(TEST_ROOTFS_PATH)
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
spec.root_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_path(bundle_dir.path().join(TEST_ROOTFS_PATH));
|
||||
let test_data = TestContainerData {
|
||||
// Since tests are executed concurrently, container_id must be unique in tests with cgroup.
|
||||
// Or the cgroup directory may be removed by other tests in advance.
|
||||
@ -179,11 +178,12 @@ mod tests {
|
||||
let bundle_dir = tempdir().unwrap();
|
||||
let config_file = bundle_dir.path().join(CONFIG_FILE_NAME);
|
||||
|
||||
let mut spec = oci::Spec {
|
||||
process: Some(oci::Process::default()),
|
||||
..Default::default()
|
||||
};
|
||||
spec.process.as_mut().unwrap().terminal = true;
|
||||
let mut spec = Spec::default();
|
||||
spec.set_process(Some(Process::default()));
|
||||
spec.process_mut()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_terminal(Some(true));
|
||||
|
||||
let file = File::create(config_file).unwrap();
|
||||
serde_json::to_writer(&file, &spec).unwrap();
|
||||
|
@ -14,8 +14,8 @@ use nix::{
|
||||
sys::{signal::kill, stat::Mode},
|
||||
unistd::Pid,
|
||||
};
|
||||
use oci::{ContainerState, State as OCIState};
|
||||
use procfs::process::ProcState;
|
||||
use runtime_spec::{ContainerState, State as OCIState};
|
||||
use rustjail::{cgroups::fs::Manager as CgroupManager, specconv::CreateOpts};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
@ -60,10 +60,10 @@ impl Status {
|
||||
.clone()
|
||||
.spec
|
||||
.ok_or_else(|| anyhow!("spec config was not present"))?
|
||||
.root
|
||||
.root()
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("root config was not present in the spec"))?
|
||||
.path
|
||||
.path()
|
||||
.clone();
|
||||
|
||||
Ok(Self {
|
||||
@ -72,7 +72,7 @@ impl Status {
|
||||
pid: oci_state.pid,
|
||||
root: root.to_path_buf(),
|
||||
bundle: bundle.to_path_buf(),
|
||||
rootfs,
|
||||
rootfs: rootfs.display().to_string(),
|
||||
process_start_time,
|
||||
created,
|
||||
cgroup_manager: cgroup_mg,
|
||||
@ -187,7 +187,7 @@ mod tests {
|
||||
use ::test_utils::skip_if_not_root;
|
||||
use chrono::{DateTime, Utc};
|
||||
use nix::unistd::getpid;
|
||||
use oci::ContainerState;
|
||||
use runtime_spec::ContainerState;
|
||||
use rustjail::cgroups::fs::Manager as CgroupManager;
|
||||
use scopeguard::defer;
|
||||
use std::path::Path;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use nix::sys::stat::Mode;
|
||||
use oci::{Process, Spec};
|
||||
use oci_spec::runtime::{Process, Spec};
|
||||
use std::{
|
||||
fs::{DirBuilder, File},
|
||||
io::{prelude::*, BufReader},
|
||||
@ -37,28 +37,24 @@ pub fn create_dir_with_mode<P: AsRef<Path>>(path: P, mode: Mode, recursive: bool
|
||||
/// If root in spec is a relative path, make it absolute.
|
||||
pub fn canonicalize_spec_root(spec: &mut Spec, bundle_canon: &Path) -> Result<()> {
|
||||
let spec_root = spec
|
||||
.root
|
||||
.root_mut()
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("root config was not present in the spec file"))?;
|
||||
let rootfs_path = Path::new(&spec_root.path);
|
||||
let rootfs_path = &spec_root.path();
|
||||
if !rootfs_path.is_absolute() {
|
||||
spec_root.path = bundle_canon
|
||||
.join(rootfs_path)
|
||||
.canonicalize()?
|
||||
.to_str()
|
||||
.map(|s| s.to_string())
|
||||
.ok_or_else(|| anyhow!("failed to convert a rootfs path into a canonical path"))?;
|
||||
let bundle_canon_path = bundle_canon.join(rootfs_path).canonicalize()?;
|
||||
spec_root.set_path(bundle_canon_path);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check whether spec is valid. Now runk only support detach mode.
|
||||
pub fn validate_spec(spec: &Spec, console_socket: &Option<PathBuf>) -> Result<()> {
|
||||
validate_process_spec(&spec.process)?;
|
||||
if let Some(process) = spec.process.as_ref() {
|
||||
validate_process_spec(spec.process())?;
|
||||
if let Some(process) = spec.process().as_ref() {
|
||||
// runk always launches containers with detached mode, so users have to
|
||||
// use a console socket with run or create operation when a terminal is used.
|
||||
if process.terminal && console_socket.is_none() {
|
||||
if process.terminal().is_some() && console_socket.is_none() {
|
||||
return Err(anyhow!(
|
||||
"cannot allocate a pseudo-TTY without setting a console socket"
|
||||
));
|
||||
@ -72,14 +68,14 @@ pub fn validate_process_spec(process: &Option<Process>) -> Result<()> {
|
||||
let process = process
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("process property must not be empty"))?;
|
||||
if process.cwd.is_empty() {
|
||||
if process.cwd().as_os_str().is_empty() {
|
||||
return Err(anyhow!("cwd property must not be empty"));
|
||||
}
|
||||
let cwd = Path::new(process.cwd.as_str());
|
||||
let cwd = process.cwd();
|
||||
if !cwd.is_absolute() {
|
||||
return Err(anyhow!("cwd must be an absolute path"));
|
||||
}
|
||||
if process.args.is_empty() {
|
||||
if process.args().is_none() {
|
||||
return Err(anyhow!("args must not be empty"));
|
||||
}
|
||||
Ok(())
|
||||
@ -91,7 +87,9 @@ pub(crate) mod test_utils {
|
||||
use crate::status::Status;
|
||||
use chrono::DateTime;
|
||||
use nix::unistd::getpid;
|
||||
use oci::{ContainerState, LinuxNamespace, Process, Root, Spec, State as OCIState};
|
||||
use oci::{LinuxBuilder, LinuxNamespaceBuilder, Process, Root, Spec};
|
||||
use oci_spec::runtime as oci;
|
||||
use runtime_spec::{ContainerState, State as OCIState};
|
||||
use rustjail::{
|
||||
cgroups::fs::Manager as CgroupManager, container::TYPETONAME, specconv::CreateOpts,
|
||||
};
|
||||
@ -129,40 +127,46 @@ pub(crate) mod test_utils {
|
||||
}
|
||||
|
||||
pub fn create_dummy_spec() -> Spec {
|
||||
let linux = oci::Linux {
|
||||
namespaces: TYPETONAME
|
||||
let linux = LinuxBuilder::default()
|
||||
.namespaces(
|
||||
TYPETONAME
|
||||
.iter()
|
||||
.filter(|&(_, &name)| name != "user")
|
||||
.map(|ns| LinuxNamespace {
|
||||
r#type: ns.0.to_string(),
|
||||
path: "".to_string(),
|
||||
.map(|ns| {
|
||||
LinuxNamespaceBuilder::default()
|
||||
.typ(ns.0.clone())
|
||||
.path(PathBuf::from(""))
|
||||
.build()
|
||||
.unwrap()
|
||||
})
|
||||
.collect(),
|
||||
..Default::default()
|
||||
};
|
||||
Spec {
|
||||
version: TEST_OCI_SPEC_VERSION.to_string(),
|
||||
process: Some(Process {
|
||||
args: vec!["sleep".to_string(), "10".to_string()],
|
||||
env: vec!["PATH=/bin:/usr/bin".to_string()],
|
||||
cwd: "/".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
hostname: TEST_HOST_NAME.to_string(),
|
||||
root: Some(Root {
|
||||
path: TEST_ROOTFS_PATH.to_string(),
|
||||
readonly: false,
|
||||
}),
|
||||
linux: Some(linux),
|
||||
..Default::default()
|
||||
}
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let mut process = Process::default();
|
||||
process.set_args(Some(vec!["sleep".to_string(), "10".to_string()]));
|
||||
process.set_env(Some(vec!["PATH=/bin:/usr/bin".to_string()]));
|
||||
process.set_cwd(PathBuf::from("/"));
|
||||
|
||||
let mut root = Root::default();
|
||||
root.set_path(PathBuf::from(TEST_ROOTFS_PATH));
|
||||
root.set_readonly(Some(false));
|
||||
|
||||
let mut spec = Spec::default();
|
||||
spec.set_version(TEST_OCI_SPEC_VERSION.to_string());
|
||||
spec.set_process(Some(process));
|
||||
spec.set_hostname(Some(TEST_HOST_NAME.to_string()));
|
||||
spec.set_root(Some(root));
|
||||
spec.set_linux(Some(linux));
|
||||
|
||||
spec
|
||||
}
|
||||
|
||||
pub fn create_dummy_opts() -> CreateOpts {
|
||||
let spec = Spec {
|
||||
root: Some(Root::default()),
|
||||
..Default::default()
|
||||
};
|
||||
let mut spec = Spec::default();
|
||||
spec.set_root(Some(Root::default()));
|
||||
|
||||
CreateOpts {
|
||||
cgroup_name: "".to_string(),
|
||||
use_systemd_cgroup: false,
|
||||
@ -219,7 +223,7 @@ pub(crate) mod test_utils {
|
||||
.unwrap()
|
||||
.starttime;
|
||||
Status {
|
||||
oci_version: spec.version.clone(),
|
||||
oci_version: spec.version().clone(),
|
||||
id: id.to_string(),
|
||||
pid,
|
||||
root: root.to_path_buf(),
|
||||
@ -247,13 +251,13 @@ pub(crate) mod test_utils {
|
||||
#[test]
|
||||
fn test_canonicalize_spec_root() {
|
||||
let gen_spec = |p: &str| -> Spec {
|
||||
Spec {
|
||||
root: Some(Root {
|
||||
path: p.to_string(),
|
||||
readonly: false,
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
let mut root = Root::default();
|
||||
root.set_path(PathBuf::from(p));
|
||||
root.set_readonly(Some(false));
|
||||
|
||||
let mut spec = Spec::default();
|
||||
spec.set_root(Some(root));
|
||||
spec
|
||||
};
|
||||
|
||||
let rootfs_name = TEST_ROOTFS_PATH;
|
||||
@ -263,29 +267,28 @@ pub(crate) mod test_utils {
|
||||
create_dir_all(abs_root.clone()).unwrap();
|
||||
let mut spec = gen_spec(abs_root.to_str().unwrap());
|
||||
assert!(canonicalize_spec_root(&mut spec, bundle_dir).is_ok());
|
||||
assert_eq!(spec.root.unwrap().path, abs_root.to_str().unwrap());
|
||||
assert_eq!(spec.root_mut().clone().unwrap().path(), &abs_root);
|
||||
let mut spec = gen_spec(rootfs_name);
|
||||
assert!(canonicalize_spec_root(&mut spec, bundle_dir).is_ok());
|
||||
assert_eq!(spec.root.unwrap().path, abs_root.to_str().unwrap());
|
||||
assert_eq!(spec.root().clone().unwrap().path(), &abs_root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_validate_process_spec() {
|
||||
let valid_process = Process {
|
||||
args: vec!["test".to_string()],
|
||||
cwd: "/".to_string(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut valid_process = Process::default();
|
||||
valid_process.set_args(Some(vec!["test".to_string()]));
|
||||
valid_process.set_cwd(PathBuf::from("/"));
|
||||
|
||||
assert!(validate_process_spec(&None).is_err());
|
||||
assert!(validate_process_spec(&Some(valid_process.clone())).is_ok());
|
||||
let mut invalid_process = valid_process.clone();
|
||||
invalid_process.args = vec![];
|
||||
invalid_process.set_args(None);
|
||||
assert!(validate_process_spec(&Some(invalid_process)).is_err());
|
||||
let mut invalid_process = valid_process.clone();
|
||||
invalid_process.cwd = "".to_string();
|
||||
invalid_process.set_cwd(PathBuf::from(""));
|
||||
assert!(validate_process_spec(&Some(invalid_process)).is_err());
|
||||
let mut invalid_process = valid_process;
|
||||
invalid_process.cwd = "test/".to_string();
|
||||
invalid_process.set_cwd(PathBuf::from("test/"));
|
||||
assert!(validate_process_spec(&Some(invalid_process)).is_err());
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use super::state::get_container_state_name;
|
||||
use anyhow::Result;
|
||||
use libcontainer::container::Container;
|
||||
use liboci_cli::List;
|
||||
use oci::ContainerState;
|
||||
use runtime_spec::ContainerState;
|
||||
use slog::{info, Logger};
|
||||
use std::fmt::Write as _;
|
||||
use std::{fs, os::unix::prelude::MetadataExt, path::Path};
|
||||
|
@ -7,7 +7,7 @@ use anyhow::Result;
|
||||
use chrono::{DateTime, Utc};
|
||||
use libcontainer::{container::Container, status::Status};
|
||||
use liboci_cli::State;
|
||||
use oci::ContainerState;
|
||||
use runtime_spec::ContainerState;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use slog::{info, Logger};
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -62,7 +62,7 @@ pub fn get_container_state_name(state: ContainerState) -> String {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use oci::ContainerState;
|
||||
use runtime_spec::ContainerState;
|
||||
|
||||
#[test]
|
||||
fn test_get_container_state_name() {
|
||||
|
Loading…
Reference in New Issue
Block a user