Skip to content

Commit 3ada451

Browse files
committed
feat(namespace): allow containers to associate with an existing namespace
This closes #2.
1 parent 60c05f8 commit 3ada451

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern crate libc;
66
extern crate tempfile;
77
extern crate failure;
88
extern crate exitcode;
9+
extern crate phf;
910

1011
pub mod bundle;
1112
pub mod spec;

src/platform/linux/namespace.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,53 @@ use crate::Error;
22
use crate::spec::PosixSpec;
33
use crate::spec::FromSpec;
44
use failure::ResultExt;
5-
use std::path::PathBuf;
5+
use nix::sched;
6+
use nix::sched::CloneFlags;
7+
use phf::phf_map;
68
use std::collections::HashMap;
9+
use std::fs::File;
10+
use std::os::unix::io::AsRawFd;
11+
use std::path::PathBuf;
712

8-
static TYPES: [&str; 7] = [
9-
"pid",
10-
"uts",
11-
"ipc",
12-
"user",
13-
"mount",
14-
"cgroup",
15-
"network",
16-
];
13+
static NS_TYPES: phf::Map<&'static str, CloneFlags> = phf_map! {
14+
"pid" => CloneFlags::CLONE_NEWPID,
15+
"uts" => CloneFlags::CLONE_NEWUTS,
16+
"ipc" => CloneFlags::CLONE_NEWIPC,
17+
"user" => CloneFlags::CLONE_NEWUSER,
18+
"mount" => CloneFlags::CLONE_NEWNS,
19+
"cgroup" => CloneFlags::CLONE_NEWCGROUP,
20+
"network" => CloneFlags::CLONE_NEWNET,
21+
};
1722

1823
pub struct Namespaces {
1924
namespaces: HashMap<String, Option<PathBuf>>,
2025
}
2126

2227
impl Namespaces {
28+
pub fn enter(&self) -> Result<(), Error> {
29+
let mut flags = CloneFlags::empty();
30+
for (kind, path) in &self.namespaces {
31+
let flag = NS_TYPES[kind.as_str()];
32+
if path.is_none() {
33+
flags.insert(flag);
34+
} else {
35+
let file = File::open(path.as_ref().unwrap()).context(format!("{:?}", &path))?;
36+
let fd = file.as_raw_fd();
37+
sched::setns(fd, flag).context(format!("{:?}: {:?}", &kind, &path))?;
38+
}
39+
}
40+
if !flags.is_empty() {
41+
sched::unshare(flags).context(format!("{:?}", flags))?;
42+
}
43+
Ok(())
44+
}
45+
2346
fn empty() -> Namespaces {
2447
Namespaces{ namespaces: HashMap::new() }
2548
}
2649

2750
fn insert(&mut self, ns_type: String, path: Option<PathBuf>) -> Result<(), Error> {
28-
if !TYPES.contains(&ns_type.as_str()) {
51+
if !NS_TYPES.contains_key(ns_type.as_str()) {
2952
Err(Error::from("invalid namespace type".to_string())).context(ns_type.clone())?;
3053
}
3154
if self.namespaces.contains_key(&ns_type) {

src/process/posix/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ impl Process for PosixProcess {
4242
Ok(())
4343
};
4444
unsafe { self.command.pre_exec(exec_fn); }
45-
let child = self.command.spawn().context(format!("cannot exec container process"))?;
46-
Ok(child)
45+
match self.command.spawn() {
46+
Ok(child) => Ok(child),
47+
Err(_) => Err(Error::from("cannot create container process".to_string())),
48+
}
4749
}
4850
}
4951

0 commit comments

Comments
 (0)