Skip to content

Commit

Permalink
Merge pull request #509 from dgibson/frontend
Browse files Browse the repository at this point in the history
Split CLI parsing front end into a separate crate
  • Loading branch information
utam0k authored Dec 4, 2021
2 parents bf9a22c + 3626f4f commit f7c23d5
Show file tree
Hide file tree
Showing 36 changed files with 578 additions and 486 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ youki
!youki/
youki_integration_test

.vscode
.vscode

*~
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 4 additions & 7 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
#!/bin/bash

set -e

TARGET=${TARGET-x86_64-unknown-linux-gnu}
if [ "$TARGET" != "" ]; then
TGT="--target $TARGET"
fi
VERSION=debug
if [[ "$1" == "--release" ]]; then
if [ "$1" == "--release" ]; then
VERSION=release
fi

cargo build --verbose $TGT $1
if [ ! -e ./youki ]; then
rm -f youki
fi
if [ ! -e ./youki_integration_test ]; then
rm -f youki_integration_test
fi

cp target/$TARGET/$VERSION/youki .
cp target/$TARGET/$VERSION/integration_test ./youki_integration_test
12 changes: 12 additions & 0 deletions crates/liboci-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "liboci-cli"
version = "0.0.1"
authors = ["youki team"]
edition = "2021"
description = "Parse command line arguments for OCI container runtimes"
readme = "README.md"

[dependencies.clap]
version = "3.0.0-beta.5"
default-features = false
features = ["std", "suggestions", "derive", "cargo"]
26 changes: 26 additions & 0 deletions crates/liboci-cli/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# liboci-cli

This is a crate to parse command line arguments for OCI container
runtimes as specified in the [OCI Runtime Command Line
Interface][https://github.com/opencontainers/runtime-tools/blob/master/docs/command-line-interface.md).

## Implemented subcommands

| Command | liboci-cli | CLI Specification | runc | crun | youki |
| :--------: | :--------: | :---------------: | :--: | :--: | :---: |
| create ||||||
| start ||||||
| state ||||||
| kill ||||||
| delete ||||||
| checkpoint | | ||| |
| events || || ||
| exec || ||||
| list || ||||
| pause || ||||
| ps || ||||
| restore | | ||| |
| resume || ||||
| run || ||||
| spec || ||||
| update | | ||| |
24 changes: 24 additions & 0 deletions crates/liboci-cli/src/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//! Handles the creation of a new container
use clap::Parser;
use std::path::PathBuf;

/// Create a container
#[derive(Parser, 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)]
pub pid_file: Option<PathBuf>,
/// path to the bundle directory, containing config.json and root filesystem
#[clap(short, long, default_value = ".")]
pub bundle: PathBuf,
/// Unix socket (file) path , which will receive file descriptor of the writing end of the pseudoterminal
#[clap(short, long)]
pub console_socket: Option<PathBuf>,
/// Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)
#[clap(long, default_value = "0")]
pub preserve_fds: i32,
/// name of the container instance to be started
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
11 changes: 11 additions & 0 deletions crates/liboci-cli/src/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use clap::Parser;

/// Release any resources held by the container
#[derive(Parser, Debug)]
pub struct Delete {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
/// forces deletion of the container if it is still running (using SIGKILL)
#[clap(short, long)]
pub force: bool,
}
15 changes: 15 additions & 0 deletions crates/liboci-cli/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use clap::Parser;

/// Show resource statistics for the container
#[derive(Parser, 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(forbid_empty_values = true, required = true)]
pub container_id: String,
}
51 changes: 51 additions & 0 deletions crates/liboci-cli/src/exec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::error::Error;
use std::path::PathBuf;

use clap::Parser;

/// Execute a process within an existing container
#[derive(Parser, 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(forbid_empty_values = true, required = true)]
pub container_id: String,
/// Command that should be executed in the container
#[clap(required = false)]
pub command: Vec<String>,
}

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()?))
}
5 changes: 5 additions & 0 deletions crates/liboci-cli/src/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use clap::Parser;

/// Show information about the system
#[derive(Parser, Debug)]
pub struct Info {}
9 changes: 9 additions & 0 deletions crates/liboci-cli/src/kill.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use clap::Parser;

/// Send the specified signal to the container
#[derive(Parser, Debug)]
pub struct Kill {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
pub signal: String,
}
79 changes: 79 additions & 0 deletions crates/liboci-cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::fmt::Debug;
use std::path::PathBuf;

use clap::Parser;

// Subcommands that are specified in https://github.com/opencontainers/runtime-tools/blob/master/docs/command-line-interface.md

mod create;
mod delete;
mod kill;
mod start;
mod state;

pub use {create::Create, delete::Delete, kill::Kill, start::Start, state::State};

// Other common subcommands that aren't specified in the document
mod events;
mod exec;
mod list;
mod pause;
mod ps;
mod resume;
mod run;
mod spec;

pub use {
events::Events, exec::Exec, list::List, pause::Pause, ps::Ps, resume::Resume, run::Run,
spec::Spec,
};

// Subcommands parsed by liboci-cli, based on the [OCI
// runtime-spec](https://github.com/opencontainers/runtime-spec/blob/master/runtime.md)
// and specifically the [OCI Command Line
// Interface](https://github.com/opencontainers/runtime-tools/blob/master/docs/command-line-interface.md)
#[derive(Parser, Debug)]
pub enum StandardCmd {
Create(Create),
Start(Start),
State(State),
Kill(Kill),
Delete(Delete),
}

// Extra subcommands not documented in the OCI Command Line Interface,
// but found in
// [runc](https://github.com/opencontainers/runc/blob/master/man/runc.8.md)
// and other runtimes.
#[derive(Parser, Debug)]
pub enum CommonCmd {
Events(Events),
Exec(Exec),
List(List),
Pause(Pause),
#[clap(setting=clap::AppSettings::AllowLeadingHyphen)]
Ps(Ps),
Resume(Resume),
Run(Run),
Spec(Spec),
}

// The OCI Command Line Interface document doesn't define any global
// flags, but these are commonly accepted by runtimes
#[derive(Parser, Debug)]
pub struct GlobalOpts {
/// change log level to debug.
// Example in future : '--debug change log level to debug. (default: "warn")'
#[clap(long)]
pub debug: bool,
#[clap(short, long)]
pub log: Option<PathBuf>,
#[clap(long)]
pub log_format: Option<String>,
/// root directory to store container state
#[clap(short, long)]
pub root: Option<PathBuf>,
/// Enable systemd cgroup manager, rather then use the cgroupfs directly.
#[clap(short, long)]
pub systemd_cgroup: bool,
}
5 changes: 5 additions & 0 deletions crates/liboci-cli/src/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use clap::Parser;

/// List created containers
#[derive(Parser, Debug)]
pub struct List {}
8 changes: 8 additions & 0 deletions crates/liboci-cli/src/pause.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use clap::Parser;

/// Suspend the processes within the container
#[derive(Parser, Debug)]
pub struct Pause {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
14 changes: 14 additions & 0 deletions crates/liboci-cli/src/ps.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use clap::{self, Parser};

/// Display the processes inside the container
#[derive(Parser, Debug)]
pub struct Ps {
/// format to display processes: table or json (default: "table")
#[clap(short, long, default_value = "table")]
pub format: String,
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
/// options will be passed to the ps utility
#[clap(setting = clap::ArgSettings::Last)]
pub ps_options: Vec<String>,
}
8 changes: 8 additions & 0 deletions crates/liboci-cli/src/resume.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use clap::Parser;

/// Resume the processes within the container
#[derive(Parser, Debug)]
pub struct Resume {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
23 changes: 23 additions & 0 deletions crates/liboci-cli/src/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use clap::Parser;
use std::path::PathBuf;

/// Create a container and immediately start it
#[derive(Parser, Debug)]
pub struct Run {
/// File to write pid of the container created
// note that in the end, container is just another process
#[clap(short, long)]
pub pid_file: Option<PathBuf>,
/// path to the bundle directory, containing config.json and root filesystem
#[clap(short, long, default_value = ".")]
pub bundle: PathBuf,
/// Unix socket (file) path , which will receive file descriptor of the writing end of the pseudoterminal
#[clap(short, long)]
pub console_socket: Option<PathBuf>,
/// Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)
#[clap(long, default_value = "0")]
pub preserve_fds: i32,
/// name of the container instance to be started
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
9 changes: 9 additions & 0 deletions crates/liboci-cli/src/spec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use clap::Parser;

/// Command generates a config.json
#[derive(Parser, Debug)]
pub struct Spec {
/// Generate a configuration for a rootless container
#[clap(long)]
pub rootless: bool,
}
8 changes: 8 additions & 0 deletions crates/liboci-cli/src/start.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use clap::Parser;

/// Start a previously created container
#[derive(Parser, Debug)]
pub struct Start {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
8 changes: 8 additions & 0 deletions crates/liboci-cli/src/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use clap::Parser;

/// Show the container state
#[derive(Parser, Debug)]
pub struct State {
#[clap(forbid_empty_values = true, required = true)]
pub container_id: String,
}
1 change: 1 addition & 0 deletions crates/youki/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ anyhow = "1.0"
chrono = { version="0.4", features = ["serde"] }
libcgroups = { path = "../libcgroups" }
libcontainer = { path = "../libcontainer" }
liboci-cli = { path = "../liboci-cli" }
log = {version = "0.4", features = ["std"]}
nix = "0.23.0"
oci-spec = { git = "https://github.com/containers/oci-spec-rs", rev = "d6fb1e91742313cd0d0085937e2d6df5d4669720" }
Expand Down
Loading

0 comments on commit f7c23d5

Please sign in to comment.