-
Notifications
You must be signed in to change notification settings - Fork 346
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,204 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
youki | ||
|
||
|
||
/tutorial | ||
.idea/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
[package] | ||
name = "youki" | ||
version = "0.0.1" | ||
authors = ["youki team"] | ||
edition = "2018" | ||
description = "A container runtime written in Rust" | ||
|
||
[dependencies.clap] | ||
version = "3.0.0-beta.2" | ||
default-features = false | ||
features = ["std", "suggestions", "derive", "cargo"] | ||
|
||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
chrono = { version="0.4", features = ["serde"] } | ||
libcgroups = { path = "../libcgroups" } | ||
libcontainer = { path = "../libcontainer" } | ||
log = "0.4" | ||
nix = "0.22.0" | ||
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "d6fb1e91742313cd0d0085937e2d6df5d4669720" } | ||
once_cell = "1.6.0" | ||
pentacle = "1.0.0" | ||
procfs = "0.11.0" | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
tabwriter = "1" | ||
|
||
[dev-dependencies] | ||
serial_test = "0.5.1" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
//! Handles the creation of a new container | ||
use anyhow::Result; | ||
use clap::Clap; | ||
use std::path::PathBuf; | ||
|
||
use libcontainer::{container::builder::ContainerBuilder, syscall::syscall::create_syscall}; | ||
|
||
/// Create a container | ||
#[derive(Clap, Debug)] | ||
pub struct Create { | ||
/// File to write pid of the container created | ||
// note that in the end, container is just another process | ||
#[clap(short, long)] | ||
pid_file: Option<PathBuf>, | ||
/// path to the bundle directory, containing config.json and root filesystem | ||
#[clap(short, long, default_value = ".")] | ||
bundle: PathBuf, | ||
/// Unix socket (file) path , which will receive file descriptor of the writing end of the pseudoterminal | ||
#[clap(short, long)] | ||
console_socket: Option<PathBuf>, | ||
/// Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total) | ||
#[clap(long, default_value = "0")] | ||
preserve_fds: i32, | ||
/// name of the container instance to be started | ||
#[clap(required = true)] | ||
pub container_id: String, | ||
} | ||
|
||
// One thing to note is that in the end, container is just another process in Linux | ||
// it has specific/different control group, namespace, using which program executing in it | ||
// can be given impression that is is running on a complete system, but on the system which | ||
// it is running, it is just another process, and has attributes such as pid, file descriptors, etc. | ||
// associated with it like any other process. | ||
impl Create { | ||
pub fn exec(&self, root_path: PathBuf, systemd_cgroup: bool) -> Result<()> { | ||
let syscall = create_syscall(); | ||
ContainerBuilder::new(self.container_id.clone(), syscall.as_ref()) | ||
.with_pid_file(self.pid_file.as_ref()) | ||
.with_console_socket(self.console_socket.as_ref()) | ||
.with_root_path(root_path) | ||
.with_preserved_fds(self.preserve_fds) | ||
.as_init(&self.bundle) | ||
.with_systemd(systemd_cgroup) | ||
.build()?; | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
use crate::commands::load_container; | ||
use anyhow::{Context, Result}; | ||
use clap::Clap; | ||
use std::path::PathBuf; | ||
|
||
/// Release any resources held by the container | ||
#[derive(Clap, Debug)] | ||
pub struct Delete { | ||
#[clap(required = true)] | ||
container_id: String, | ||
/// forces deletion of the container if it is still running (using SIGKILL) | ||
#[clap(short, long)] | ||
force: bool, | ||
} | ||
|
||
impl Delete { | ||
pub fn exec(&self, root_path: PathBuf) -> Result<()> { | ||
log::debug!("start deleting {}", self.container_id); | ||
let mut container = load_container(root_path, &self.container_id)?; | ||
container | ||
.delete(self.force) | ||
.with_context(|| format!("failed to delete container {}", self.container_id)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use clap::Clap; | ||
use std::path::PathBuf; | ||
|
||
use anyhow::{Context, Result}; | ||
|
||
use crate::commands::load_container; | ||
|
||
/// Show resource statistics for the container | ||
#[derive(Clap, Debug)] | ||
pub struct Events { | ||
/// Sets the stats collection interval in seconds (default: 5s) | ||
#[clap(long, default_value = "5")] | ||
pub interval: u32, | ||
/// Display the container stats only once | ||
#[clap(long)] | ||
pub stats: bool, | ||
/// Name of the container instance | ||
#[clap(required = true)] | ||
pub container_id: String, | ||
} | ||
|
||
impl Events { | ||
pub fn exec(&self, root_path: PathBuf) -> Result<()> { | ||
let mut container = load_container(root_path, &self.container_id)?; | ||
container | ||
.events(self.interval, self.stats) | ||
.with_context(|| format!("failed to get events from container {}", self.container_id)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use anyhow::Result; | ||
use clap::Clap; | ||
use std::{error::Error, path::PathBuf}; | ||
|
||
use libcontainer::{container::builder::ContainerBuilder, syscall::syscall::create_syscall}; | ||
|
||
/// Execute a process within an existing container | ||
#[derive(Clap, Debug)] | ||
pub struct Exec { | ||
/// Unix socket (file) path , which will receive file descriptor of the writing end of the pseudoterminal | ||
#[clap(long)] | ||
pub console_socket: Option<PathBuf>, | ||
#[clap(short, long)] | ||
pub tty: bool, | ||
#[clap(long)] | ||
/// Current working directory of the container | ||
pub cwd: Option<PathBuf>, | ||
#[clap(long)] | ||
/// The file to which the pid of the container process should be written to | ||
pub pid_file: Option<PathBuf>, | ||
/// Environment variables that should be set in the container | ||
#[clap(short, long, parse(try_from_str = parse_key_val), number_of_values = 1)] | ||
pub env: Vec<(String, String)>, | ||
/// Prevent the process from gaining additional privileges | ||
#[clap(long)] | ||
pub no_new_privs: bool, | ||
/// Path to process.json | ||
#[clap(short, long)] | ||
pub process: Option<PathBuf>, | ||
/// Detach from the container process | ||
#[clap(short, long)] | ||
pub detach: bool, | ||
/// Identifier of the container | ||
#[clap(required = true)] | ||
pub container_id: String, | ||
/// Command that should be executed in the container | ||
#[clap(required = false)] | ||
pub command: Vec<String>, | ||
} | ||
|
||
impl Exec { | ||
pub fn exec(&self, root_path: PathBuf) -> Result<()> { | ||
let syscall = create_syscall(); | ||
ContainerBuilder::new(self.container_id.clone(), syscall.as_ref()) | ||
.with_root_path(root_path) | ||
.with_console_socket(self.console_socket.as_ref()) | ||
.with_pid_file(self.pid_file.as_ref()) | ||
.as_tenant() | ||
.with_cwd(self.cwd.as_ref()) | ||
.with_env(self.env.clone().into_iter().collect()) | ||
.with_process(self.process.as_ref()) | ||
.with_no_new_privs(self.no_new_privs) | ||
.with_process(self.process.as_ref()) | ||
.with_container_args(self.command.clone()) | ||
.build() | ||
} | ||
} | ||
|
||
fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>> | ||
where | ||
T: std::str::FromStr, | ||
T::Err: Error + Send + Sync + 'static, | ||
U: std::str::FromStr, | ||
U::Err: Error + Send + Sync + 'static, | ||
{ | ||
let pos = s | ||
.find('=') | ||
.ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?; | ||
Ok((s[..pos].parse()?, s[pos + 1..].parse()?)) | ||
} |
Oops, something went wrong.