diff --git a/build.sh b/build.sh index 336e694b0..d45c72282 100755 --- a/build.sh +++ b/build.sh @@ -16,9 +16,9 @@ fi # not a part of youki workspace. For the reasoning behind this, # please check the docs and readme -cargo build --verbose $TGT $1 +cargo build $TGT $1 $2 cd ./runtimetest -cargo build --verbose $TGT $1 +cargo build $TGT $1 $2 cd .. cp target/$TARGET/$VERSION/youki . diff --git a/crates/libcontainer/src/process/container_init_process.rs b/crates/libcontainer/src/process/container_init_process.rs index fab695c88..1f0e2a877 100644 --- a/crates/libcontainer/src/process/container_init_process.rs +++ b/crates/libcontainer/src/process/container_init_process.rs @@ -412,8 +412,16 @@ pub fn container_init_process( unistd::chdir(proc.cwd()).with_context(|| format!("failed to chdir {:?}", proc.cwd()))?; } + // add HOME into envs if not exists + let home_in_envs = envs.iter().any(|x| x.starts_with("HOME=")); + if !home_in_envs { + if let Some(dir_home) = utils::get_user_home(proc.user().uid()) { + envs.push(format!("HOME={}", dir_home.to_string_lossy())); + } + } + // Reset the process env based on oci spec. - env::vars().for_each(|(key, _value)| std::env::remove_var(key)); + env::vars().for_each(|(key, _value)| env::remove_var(key)); utils::parse_env(&envs) .iter() .for_each(|(key, value)| env::set_var(key, value)); diff --git a/crates/libcontainer/src/utils.rs b/crates/libcontainer/src/utils.rs index 5f3482f0b..c4d77e4e0 100644 --- a/crates/libcontainer/src/utils.rs +++ b/crates/libcontainer/src/utils.rs @@ -5,6 +5,7 @@ use anyhow::{bail, Result}; use nix::sys::stat::Mode; use nix::sys::statfs; use nix::unistd; +use nix::unistd::{Uid, User}; use std::collections::HashMap; use std::ffi::CString; use std::fs::{self, DirBuilder, File}; @@ -56,6 +57,22 @@ pub fn parse_env(envs: &[String]) -> HashMap { .collect() } +/// Get a nix::unistd::User via UID. Potential errors will be ignored. +pub fn get_unix_user(uid: Uid) -> Option { + match User::from_uid(uid) { + Ok(x) => x, + Err(_) => None, + } +} + +/// Get home path of a User via UID. +pub fn get_user_home(uid: u32) -> Option { + match get_unix_user(Uid::from_raw(uid)) { + Some(user) => Some(user.dir), + None => None, + } +} + pub fn do_exec(path: impl AsRef, args: &[String]) -> Result<()> { let p = CString::new(path.as_ref().as_os_str().as_bytes()) .with_context(|| format!("failed to convert path {:?} to cstring", path.as_ref()))?; @@ -318,6 +335,26 @@ pub(crate) mod test_utils { mod tests { use super::*; + #[test] + pub fn test_get_unix_user() { + let user = get_unix_user(Uid::from_raw(0)); + assert_eq!(user.unwrap().name, "root"); + + // for a non-exist UID + let user = get_unix_user(Uid::from_raw(1000000000)); + assert!(user.is_none()); + } + + #[test] + pub fn test_get_user_home() { + let dir = get_user_home(0); + assert_eq!(dir.unwrap().to_str().unwrap(), "/root"); + + // for a non-exist UID + let dir = get_user_home(1000000000); + assert!(dir.is_none()); + } + #[test] fn test_get_cgroup_path() { let cid = "sample_container_id"; diff --git a/docs/src/user/basic_usage.md b/docs/src/user/basic_usage.md index 477d9c591..c7c0a90ca 100644 --- a/docs/src/user/basic_usage.md +++ b/docs/src/user/basic_usage.md @@ -56,6 +56,26 @@ Then to start the original/normal Docker daemon, you can run sudo systemctl start docker ``` +#### Let docker permanently know youki as a runtime + +With newer versions of docker, you can update file `/etc/docker/daemon.json` to +let docker know youki +([source](https://docs.docker.com/engine/reference/commandline/dockerd/#on-linux)). +A sample content of it: +``` +{ + "default-runtime": "runc", + "runtimes": { + "youki": { + "path": "/path/to/youki/youki" + } + } +} +``` + +After this (need to restart docker at the first time), you can use youki +with docker: `docker run --runtime youki ...`. + #### Using Youki Standalone Youki can also be used directly, without a higher-level runtime such as Docker to create, start, stop and delete the container, but the process can be tedious. Here we will show how you can do that, to run a simple container with desired program running in it.