Skip to content

Commit

Permalink
adding HOME into envs when init containers (#681)
Browse files Browse the repository at this point in the history
* WIP: adding HOME into envs when init containers

Signed-off-by: Hugo Wang <[email protected]>
  • Loading branch information
mitnk authored Feb 8, 2022
1 parent bdde864 commit 62a10c6
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 .
Expand Down
10 changes: 9 additions & 1 deletion crates/libcontainer/src/process/container_init_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
37 changes: 37 additions & 0 deletions crates/libcontainer/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -56,6 +57,22 @@ pub fn parse_env(envs: &[String]) -> HashMap<String, String> {
.collect()
}

/// Get a nix::unistd::User via UID. Potential errors will be ignored.
pub fn get_unix_user(uid: Uid) -> Option<User> {
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<PathBuf> {
match get_unix_user(Uid::from_raw(uid)) {
Some(user) => Some(user.dir),
None => None,
}
}

pub fn do_exec(path: impl AsRef<Path>, 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()))?;
Expand Down Expand Up @@ -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";
Expand Down
20 changes: 20 additions & 0 deletions docs/src/user/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 62a10c6

Please sign in to comment.