Skip to content

Commit

Permalink
Fix ignored files
Browse files Browse the repository at this point in the history
  • Loading branch information
Furisto committed Oct 22, 2021
1 parent 359db4c commit 52a262f
Show file tree
Hide file tree
Showing 21 changed files with 1,204 additions and 76 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
youki


/tutorial
.idea/
Expand Down
32 changes: 32 additions & 0 deletions crates/youki/Cargo.toml
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"


48 changes: 48 additions & 0 deletions crates/youki/src/commands/create.rs
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(())
}
}
24 changes: 24 additions & 0 deletions crates/youki/src/commands/delete.rs
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))
}
}
29 changes: 29 additions & 0 deletions crates/youki/src/commands/events.rs
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))
}
}
70 changes: 70 additions & 0 deletions crates/youki/src/commands/exec.rs
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()?))
}
Loading

0 comments on commit 52a262f

Please sign in to comment.