Skip to content

Commit

Permalink
Liboci additional flags and subcommands, as required by ociplex (#2149)
Browse files Browse the repository at this point in the history
Add the missing OCI cli options and change options order

- checkpoint:

Add the missing command-line options as documented for runc, and also reorder
the options to match the documentation:
https://github.com/opencontainers/runc/blob/main/man/runc-checkpoint.8.md

(This does not mean that they are necessarily implemented)

- no-pivot:

The --no-pivot option is documented in
https://github.com/opencontainers/runc/blob/main/man/runc-create.8.md

Also change the options order in order to match the doc, this makes the code a
bit easier to maintain.

- exec:

Add the missing command-line options for the exec subcommand.
Reference: https://github.com/opencontainers/runc/blob/main/man/runc-exec.8.md

- run:

Also change the order to match the documentation in
https://github.com/opencontainers/runc/blob/main/man/runc-run.8.md

- update

Add command-line options as documented in
https://github.com/opencontainers/runc/blob/main/man/runc-update.8.md

- spec:

Add the missing bundle option, as documented in
https://github.com/opencontainers/runc/blob/main/man/runc-spec.8.md

- features

The 'features' subcommand is not publicly documented yet, but it was introduced
in `runc` in opencontainers/runc#3296.

- liboci-cli: Update README with information about features subcommand

The `features` subcommand is  implemented in `runc`, but not documented.
See opencontainers/runc#3296

- list: Add missing command-line options

Add the command-line options documented in

-------

Signed-off-by: Christophe de Dinechin <dinechin@redhat.com>
Signed-off-by: yihuaf <yihuaf@unkies.org>
Co-authored-by: yihuaf <yihuaf@unkies.org>
  • Loading branch information
c3d and yihuaf authored Jul 13, 2023
1 parent 03d6ca0 commit b9b5fa8
Show file tree
Hide file tree
Showing 13 changed files with 218 additions and 44 deletions.
1 change: 1 addition & 0 deletions crates/liboci-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Interface](https://github.com/opencontainers/runtime-tools/blob/master/docs/comm
| checkpoint | | ||| |
| events || || ||
| exec || ||||
| features || || | |
| list || ||||
| pause || ||||
| ps || ||||
Expand Down
50 changes: 38 additions & 12 deletions crates/liboci-cli/src/checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,55 @@ use clap::Parser;
use std::path::PathBuf;

/// Checkpoint a running container
/// Reference: https://github.com/opencontainers/runc/blob/main/man/runc-checkpoint.8.md
#[derive(Parser, Debug)]
pub struct Checkpoint {
#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,
/// Allow external unix sockets
#[clap(long)]
pub ext_unix_sk: bool,
/// Allow file locks
#[clap(long)]
pub file_locks: bool,
/// Path for saving criu image files
#[clap(long, default_value = "checkpoint")]
pub image_path: PathBuf,
/// Path for saving work files and logs
#[clap(long)]
pub work_path: Option<PathBuf>,
/// Path for previous criu image file in pre-dump
#[clap(long)]
pub parent_path: Option<PathBuf>,
/// Leave the process running after checkpointing
#[clap(long)]
pub leave_running: bool,
/// Allow open tcp connections
#[clap(long)]
pub tcp_established: bool,
/// Allow external unix sockets
#[clap(long)]
pub ext_unix_sk: bool,
/// Allow shell jobs
#[clap(long)]
pub shell_job: bool,
/// Allow open tcp connections
/// Use lazy migration mechanism
#[clap(long)]
pub tcp_established: bool,
/// Path for saving work files and logs
pub lazy_pages: bool,
/// Pass a file descriptor fd to criu
#[clap(long)]
pub work_path: Option<PathBuf>,
pub status_fd: Option<u32>, // TODO: Is u32 the right type?
/// Start a page server at the given URL
#[clap(long)]
pub page_server: Option<String>,
/// Allow file locks
#[clap(long)]
pub file_locks: bool,
/// Do a pre-dump
#[clap(long)]
pub pre_dump: bool,
/// Cgroups mode
#[clap(long)]
pub manage_cgroups_mode: Option<String>,
/// Checkpoint a namespace, but don't save its properties
#[clap(long)]
pub empty_ns: bool,
/// Enable auto-deduplication
#[clap(long)]
pub auto_dedup: bool,

#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,
}
20 changes: 14 additions & 6 deletions crates/liboci-cli/src/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,30 @@ use clap::Parser;
use std::path::PathBuf;

/// Create a container
/// Reference: https://github.com/opencontainers/runc/blob/main/man/runc-create.8.md
#[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
/// 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>,
/// 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>,
/// Do not use pivot rool to jail process inside rootfs
#[clap(long)]
pub no_pivot: bool,
/// Do not create a new session keyring for the container.
#[clap(long)]
pub no_new_keyring: bool,
/// 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

/// Name of the container instance to be started
#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,
}
63 changes: 52 additions & 11 deletions crates/liboci-cli/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,67 @@ use std::path::PathBuf;
use clap::Parser;

/// Execute a process within an existing container
/// Reference: https://github.com/opencontainers/runc/blob/main/man/runc-exec.8.md
#[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, value_parser = parse_key_val::<String, String>, number_of_values = 1)]
#[clap(short, long, value_parser = parse_env::<String, String>, number_of_values = 1)]
pub env: Vec<(String, String)>,
/// Prevent the process from gaining additional privileges
#[clap(long)]
pub no_new_privs: bool,
#[clap(short, long)]
pub tty: bool,
/// Run the command as a user
#[clap(short, long, value_parser = parse_user::<u32, u32>)]
pub user: Option<(u32, Option<u32>)>,
/// Add additional group IDs. Can be specified multiple times
#[clap(long, short = 'g', number_of_values = 1)]
pub additional_gids: Vec<u32>,
/// Path to process.json
#[clap(short, long)]
pub process: Option<PathBuf>,
/// Detach from the container process
#[clap(short, long)]
pub detach: bool,
#[clap(long)]
/// The file to which the pid of the container process should be written to
pub pid_file: Option<PathBuf>,
/// Set the asm process label for the process commonly used with selinux
#[clap(long)]
pub process_label: Option<String>,
/// Set the apparmor profile for the process
#[clap(long)]
pub apparmor: Option<String>,
/// Prevent the process from gaining additional privileges
#[clap(long)]
pub no_new_privs: bool,
/// Add a capability to the bounding set for the process
#[clap(long, number_of_values = 1)]
pub cap: Vec<String>,
/// Pass N additional file descriptors to the container
#[clap(long, default_value = "0")]
pub preserve_fds: i32,
/// Allow exec in a paused container
#[clap(long)]
pub ignore_paused: bool,
/// Execute a process in a sub-cgroup
#[clap(long)]
pub cgroup: Option<String>,

/// Identifier of the container
#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), 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>>
fn parse_env<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
where
T: std::str::FromStr,
T::Err: Error + Send + Sync + 'static,
Expand All @@ -46,6 +73,20 @@ where
{
let pos = s
.find('=')
.ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
.ok_or_else(|| format!("invalid VAR=value: no `=` found in `{s}`"))?;
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
}

fn parse_user<T, U>(s: &str) -> Result<(T, Option<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,
{
if let Some(pos) = s.find(':') {
Ok((s[..pos].parse()?, Some(s[pos + 1..].parse()?)))
} else {
Ok((s.parse()?, None))
}
}
9 changes: 9 additions & 0 deletions crates/liboci-cli/src/features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use clap::Parser;

/// Return the features list for a container
/// This subcommand was introduced in runc by
/// https://github.com/opencontainers/runc/pull/3296
/// It is documented here:
/// https://github.com/opencontainers/runtime-spec/blob/main/features-linux.md
#[derive(Parser, Debug)]
pub struct Features {}
6 changes: 4 additions & 2 deletions crates/liboci-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub use {create::Create, delete::Delete, kill::Kill, start::Start, state::State}
mod checkpoint;
mod events;
mod exec;
mod features;
mod list;
mod pause;
mod ps;
Expand All @@ -26,8 +27,8 @@ mod spec;
mod update;

pub use {
checkpoint::Checkpoint, events::Events, exec::Exec, list::List, pause::Pause, ps::Ps,
resume::Resume, run::Run, spec::Spec, update::Update,
checkpoint::Checkpoint, events::Events, exec::Exec, features::Features, list::List,
pause::Pause, ps::Ps, resume::Resume, run::Run, spec::Spec, update::Update,
};

// Subcommands parsed by liboci-cli, based on the [OCI
Expand All @@ -52,6 +53,7 @@ pub enum CommonCmd {
Checkpointt(Checkpoint),
Events(Events),
Exec(Exec),
Features(Features),
List(List),
Pause(Pause),
#[clap(allow_hyphen_values = true)]
Expand Down
10 changes: 9 additions & 1 deletion crates/liboci-cli/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ use clap::Parser;

/// List created containers
#[derive(Parser, Debug)]
pub struct List {}
pub struct List {
/// Specify the format (default or table)
#[clap(long, default_value = "table")]
pub format: String,

/// Only display container IDs
#[clap(long, short)]
pub quiet: bool,
}
22 changes: 17 additions & 5 deletions crates/liboci-cli/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ 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
/// 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>,
/// 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>,
/// Disable the use of the subreaper used to reap reparented processes
#[clap(long)]
pub no_subreaper: bool,
/// Do not use pivot root to jail process inside rootfs
#[clap(long)]
pub no_pivot: bool,
/// Do not create a new session keyring for the container. This will cause the container to inherit the calling processes session key.
#[clap(long)]
pub no_new_keyring: bool,
/// Pass N additional file descriptors to the container (stdio + $LISTEN_FDS + N in total)
#[clap(long, default_value = "0")]
pub preserve_fds: i32,
// Keep container's state directory and cgroup
#[clap(long)]
pub keep: bool,
/// name of the container instance to be started
#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,
Expand Down
5 changes: 5 additions & 0 deletions crates/liboci-cli/src/spec.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use clap::Parser;
use std::path::PathBuf;

/// Command generates a config.json
#[derive(Parser, Debug)]
pub struct Spec {
/// Set path to the root of the bundle directory
#[clap(long, short)]
pub bundle: Option<PathBuf>,

/// Generate a configuration for a rootless container
#[clap(long)]
pub rootless: bool,
Expand Down
58 changes: 55 additions & 3 deletions crates/liboci-cli/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,67 @@ use std::path::PathBuf;
/// Update running container resource constraints
#[derive(Parser, Debug)]
pub struct Update {
#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,

/// Read the new resource limits from the given json file. Use - to read from stdin.
/// If this option is used, all other options are ignored.
#[clap(short, long)]
pub resources: Option<PathBuf>,

/// Set a new I/O weight
#[clap(long)]
pub blkio_weight: Option<u64>,

/// Set CPU CFS period to be used for hardcapping (in microseconds)
#[clap(long)]
pub cpu_period: Option<u64>,

/// Set CPU usage limit within a given period (in microseconds)
#[clap(long)]
pub cpu_quota: Option<u64>,

/// Set CPU realtime period to be used for hardcapping (in microseconds)
#[clap(long)]
pub cpu_rt_period: Option<u64>,

/// Set CPU realtime hardcap limit (in microseconds)
#[clap(long)]
pub cpu_rt_runtime: Option<u64>,

/// Set CPU shares (relative weight vs. other containers)
#[clap(long)]
pub cpu_share: Option<u64>,

/// Set CPU(s) to use. The list can contain commas and ranges. For example: 0-3,7
#[clap(long)]
pub cpuset_cpus: Option<String>,

/// Set memory node(s) to use. The list format is the same as for --cpuset-cpus.
#[clap(long)]
pub cpuset_mems: Option<String>,

/// Set memory limit to num bytes.
#[clap(long)]
pub memory: Option<u64>,

/// Set memory reservation (or soft limit) to num bytes.
#[clap(long)]
pub memory_reservation: Option<u64>,

/// Set total memory + swap usage to num bytes. Use -1 to unset the limit (i.e. use unlimited swap).
#[clap(long)]
pub memory_swap: Option<i64>,

/// Set the maximum number of processes allowed in the container
#[clap(long)]
pub pids_limit: Option<i64>,

/// Set the value for Intel RDT/CAT L3 cache schema.
#[clap(long)]
pub l3_cache_schema: Option<String>,

/// Set the Intel RDT/MBA memory bandwidth schema.
#[clap(long)]
pub mem_bw_schema: Option<String>,

#[clap(value_parser = clap::builder::NonEmptyStringValueParser::new(), required = true)]
pub container_id: String,
}
8 changes: 8 additions & 0 deletions crates/youki/src/commands/features.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Contains Functionality of `features` container command
use anyhow::Result;
use liboci_cli::Features;

/// lists all existing containers
pub fn features(_: Features) -> Result<()> {
Ok(())
}
Loading

0 comments on commit b9b5fa8

Please sign in to comment.