1
0
Fork 0
mirror of https://github.com/containers/youki synced 2024-05-08 16:46:17 +02:00
youki/src/commands/exec.rs
2021-10-22 21:55:16 +02:00

71 lines
2.4 KiB
Rust

use anyhow::Result;
use clap::Clap;
use std::{error::Error, path::PathBuf};
use crate::{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()?))
}