From 3cae52c481a6fb7928edad5dbf2b9a9e019ecec9 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sat, 14 Nov 2020 11:46:36 +0800 Subject: [PATCH] feat: add docker_util --- Cargo.toml | 2 +- src/docker_util.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 +++++- 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/docker_util.rs diff --git a/Cargo.toml b/Cargo.toml index 3fe6da1..b955d5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,4 @@ edition = "2018" [dependencies] rust_util = "0.6" - +users = "0.11" diff --git a/src/docker_util.rs b/src/docker_util.rs new file mode 100644 index 0000000..659bbbb --- /dev/null +++ b/src/docker_util.rs @@ -0,0 +1,78 @@ +use std::process::Command; +use rust_util::XResult; +use rust_util::util_cmd; + +const DOCKER_CMD: &str = "docker"; + +// $ docker run --rm --user "$(id -u)":"$(id -g)" \ +// -v "$PWD":/usr/src/app -w /usr/src/app rust:1.47 \ +// cargo build --release +#[derive(Default)] +pub struct DockerCmd { + docker_name: String, + docker_current_dir: Option, + docker_run_uid: Option, + docker_run_gid: Option, +} + +impl DockerCmd { + pub fn new(docker_name: &str) -> Self { + Self { + docker_name: docker_name.into(), + ..Default::default() + } + } + + pub fn current_dir(&mut self, current_dir: &str) -> &mut Self { + self.docker_current_dir = Some(current_dir.into()); + self + } + + pub fn uid(&mut self, uid: u32) -> &mut Self { + self.docker_run_uid = Some(uid); + self + } + + pub fn gid(&mut self, gid: u32) -> &mut Self { + self.docker_run_gid = Some(gid); + self + } + + pub fn exec(self, cmds: &[String]) -> XResult<()> { + let mut cmd = Command::new(DOCKER_CMD); + cmd.arg("run"); + cmd.arg("--rm"); + cmd.arg("--user"); + cmd.arg(&format!("{}:{}", + self.docker_run_uid.unwrap_or_else(|| users::get_current_uid() as u32), + self.docker_run_gid.unwrap_or_else(|| users::get_current_gid() as u32), + )); + cmd.arg("-v"); + cmd.arg(&format!("{}:/usr/src/app", match self.docker_current_dir { + Some(dir) => dir, None => match std::env::current_dir() { + Ok(dir) => match dir.as_path().to_str() { + Some(dir) => dir.into(), None => return Err(rust_util::new_box_error("Error in get current dir!")), + }, + Err(e) => return Err(rust_util::new_box_error(&format!("Error in get current dir: {}", e))), + }, + })); + cmd.arg("-w"); + cmd.arg("/usr/src/app"); + cmd.arg(&self.docker_name); + let mut cmds_iter = cmds.iter(); + if let Some(cmd0) = cmds_iter.next() { + if cmd0.starts_with(":") { + cmd.arg(&cmd0.chars().skip(1).collect::()); + } else { + cmd.arg("cargo"); + cmd.arg(&cmd0); + } + } else { + cmd.arg("cargo"); + } + cmds_iter.for_each(|c| { cmd.arg(c); }); + information!("Docker cmd exec: {:?}", cmd); + util_cmd::run_command_and_wait(&mut cmd).map_err(|e| e.into()) + // Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 2ca4ccd..2551cdc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,14 @@ #[macro_use] extern crate rust_util; +mod docker_util; + +pub use docker_util::DockerCmd; + fn main() { - information!("Hello World!") + information!("dockerbuild v0.1"); + + let args_iter = std::env::args().skip(1); + let args = args_iter.map(|a| a.to_owned()).collect::>(); + DockerCmd::new("rust:1.47").exec(&args).unwrap(); }