diff --git a/.gitignore b/.gitignore index 93f8b77..53649aa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ Cargo.lock .idea *.tar.gz +.vscode +ctr-bundle \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c3eb43d..a93a297 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,7 +406,6 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "unshare" version = "0.7.0" -source = "git+https://github.com/virt-do/unshare?branch=main#7b0a2e8d906bcdb2efa62d3ce9580dc359b731fd" dependencies = [ "libc", "nix", diff --git a/Cargo.toml b/Cargo.toml index d11e5ae..5491fd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ authors = ["Polytech Montpellier - DevOps"] clap = { version = "3.0.5", features = ["derive"] } lazy_static = "1.4.0" oci-spec = "0.5.3" -unshare = { git = "https://github.com/virt-do/unshare", branch = "main" } +# unshare = { git = "https://github.com/virt-do/unshare", branch = "main" } +unshare = { path = "../unshare" } diff --git a/src/container/mod.rs b/src/container/mod.rs index c33f846..af9b672 100644 --- a/src/container/mod.rs +++ b/src/container/mod.rs @@ -1,6 +1,7 @@ use std::path::PathBuf; use oci_spec::runtime::Spec; +use unshare::{UidMap, GidMap}; use crate::container::environment::Environment; use command::Command; @@ -29,6 +30,8 @@ pub type Result = std::result::Result; /// Some OCI constants useful for our container implementation. const OCI_RUNTIME_SPEC_FILE: &str = "config.json"; const OCI_RUNTIME_SPEC_ROOTFS: &str = "rootfs"; +const OCI_RUNTIME_SPEC_USER_UID: u32 = 0; +const OCI_RUNTIME_SPEC_USER_GID: u32 = 0; /// The `Container` struct provides a simple way to /// create and run a container on the host. @@ -44,6 +47,10 @@ pub struct Container { environment: Environment, /// The command entrypoint command: Command, + /// User uid, default: 0 (root) + uid: u32, + /// User gid, default: 0 (root) + gid: u32, } impl Container { @@ -72,11 +79,24 @@ impl Container { Namespaces::from(linux.namespaces()) }); + let uid: u32 = spec + .process() + .as_ref() + .map_or(OCI_RUNTIME_SPEC_USER_UID, |process| process.user().uid()); + + let gid: u32 = spec + .process() + .as_ref() + .map_or(OCI_RUNTIME_SPEC_USER_GID, |process| process.user().gid()); + + Ok(Container { environment: Environment::from(spec.process()), command: Command::from(spec.process()), namespaces, rootfs, + uid, + gid, ..Default::default() }) } @@ -87,6 +107,18 @@ impl Container { let code = unsafe { unshare::Command::from(&self.command) .chroot_dir(&self.rootfs) + .set_id_maps( + vec![UidMap { + count: 1, + inside_uid: 0, + outside_uid: 0, + }], + vec![GidMap { + count: 1, + inside_gid: 0, + outside_gid: 0, + }], + ) .unshare(&*self.namespaces.get()) .pre_exec(move || Mounts::apply(&mounts)) .envs(self.environment.get())