|
|
|
@ -9,8 +9,6 @@ use nix::sys::wait::{wait, waitpid, waitid, WaitPidFlag};
|
|
|
|
|
use nix::unistd::{chdir, chroot, dup2, execv, pivot_root, setuid, sleep, Gid, Pid, Uid, User, setgroups};
|
|
|
|
|
use nix::mount::{mount, MntFlags, MsFlags, umount2, umount};
|
|
|
|
|
use nix::env::clearenv;
|
|
|
|
|
use nix::pty;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
|
use clap::Parser;
|
|
|
|
|
use error::{Result, RockerError};
|
|
|
|
@ -18,7 +16,7 @@ mod error;
|
|
|
|
|
use uuid;
|
|
|
|
|
use std::{io, fs};
|
|
|
|
|
use toml;
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
|
|
static WORKSPACE: &str = "/root/rocker";
|
|
|
|
|
static USER_NAME: &str = "rocker";
|
|
|
|
@ -38,6 +36,14 @@ struct RockerArgs {
|
|
|
|
|
log: bool,
|
|
|
|
|
#[arg(long)]
|
|
|
|
|
wait: bool,
|
|
|
|
|
|
|
|
|
|
// --logs container_id
|
|
|
|
|
#[arg(long)]
|
|
|
|
|
logs: Option<String>,
|
|
|
|
|
|
|
|
|
|
// --ps
|
|
|
|
|
#[arg(long)]
|
|
|
|
|
ps: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -279,33 +285,61 @@ fn run_container(cmd: &String, wait:bool, log:bool, volume_path: &PathBuf) -> Re
|
|
|
|
|
Ok(_container_id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
|
|
|
struct ContainerInfo {
|
|
|
|
|
id: String,
|
|
|
|
|
run: String,
|
|
|
|
|
image: String,
|
|
|
|
|
volume: String,
|
|
|
|
|
volume: Option<String>,
|
|
|
|
|
env: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn save_container_info(container_id: &String) -> Result<()> {
|
|
|
|
|
let container_info_path = Path::new(WORKSPACE).join("containers").join(container_id).join("container.json");
|
|
|
|
|
fn save_container_info(args: &RockerArgs, container_id: &String) -> Result<()> {
|
|
|
|
|
let container_info_path = Path::new(WORKSPACE).join("containers").join(container_id).join("info.toml");
|
|
|
|
|
let container_info = ContainerInfo {
|
|
|
|
|
id: container_id.to_string(),
|
|
|
|
|
image: "".to_string(),
|
|
|
|
|
volume: "".to_string(),
|
|
|
|
|
id: container_id.clone(),
|
|
|
|
|
run: args.run.as_ref().unwrap().clone(),
|
|
|
|
|
image: args.image.as_ref().unwrap().clone(),
|
|
|
|
|
volume: None,
|
|
|
|
|
env: None
|
|
|
|
|
};
|
|
|
|
|
let toml_str = toml::to_string(&container_info)?;
|
|
|
|
|
// println!("")
|
|
|
|
|
fs::write(container_info_path, toml_str)?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 读取所有容器的状态
|
|
|
|
|
fn show_containers() -> Result<()> {
|
|
|
|
|
let containers_path = Path::new(WORKSPACE).join("containers");
|
|
|
|
|
|
|
|
|
|
for entry in fs::read_dir(containers_path)? {
|
|
|
|
|
let path = entry?.path();
|
|
|
|
|
let info_path = path.join("info.toml");
|
|
|
|
|
let info_str = fs::read_to_string(info_path)?;
|
|
|
|
|
let container_info: ContainerInfo = toml::from_str(&info_str)?;
|
|
|
|
|
println!("{container_info:?}");
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn main() -> Result<()>{
|
|
|
|
|
let args = RockerArgs::parse();
|
|
|
|
|
// run
|
|
|
|
|
if let (Some(cmd), Some(image_name)) = (&args.run, &args.image) {
|
|
|
|
|
let volume_path = extend_image(image_name)?;
|
|
|
|
|
let container_id = run_container(cmd, args.wait, args.log, &volume_path)?;
|
|
|
|
|
|
|
|
|
|
save_container_info(&args, &container_id)?;
|
|
|
|
|
} else if args.ps {
|
|
|
|
|
show_containers()?
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// exec
|
|
|
|
|
|
|
|
|
|
// logs
|
|
|
|
|
|
|
|
|
|
// rm
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|