143 lines
4.2 KiB
Rust
143 lines
4.2 KiB
Rust
use std::fs;
|
|
use std::process::Command;
|
|
use rust_util::XResult;
|
|
use rust_util::util_cmd;
|
|
use crate::build_util;
|
|
use crate::build_util::Builder;
|
|
|
|
const DOCKER_CMD: &str = "docker";
|
|
const DCOLER_TEMP_CMD: &str = "temp_sub_cmd";
|
|
const DOCKER_WORK_DIR: &str = "/usr/src/app";
|
|
|
|
// $ 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<String>,
|
|
docker_run_uid: Option<u32>,
|
|
docker_run_gid: Option<u32>,
|
|
volumns: Vec<(String, String)>,
|
|
mirror: Option<String>,
|
|
}
|
|
|
|
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 mirror(&mut self, mirror: &str) -> &mut Self {
|
|
self.mirror = Some(mirror.into());
|
|
self
|
|
}
|
|
|
|
pub fn add_volumn(&mut self, outer_vol: &str, docker_vol: &str) -> &mut Self {
|
|
self.volumns.push((outer_vol.into(), docker_vol.into()));
|
|
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!("{}:{}", build_util::get_work_dir(&self.docker_current_dir)?, DOCKER_WORK_DIR));
|
|
for (outer_vol, docker_vol) in self.volumns {
|
|
cmd.arg("-v");
|
|
cmd.arg(&format!("{}:{}", outer_vol, docker_vol));
|
|
}
|
|
cmd.args(vec!["-w", DOCKER_WORK_DIR]);
|
|
cmd.arg(&self.docker_name);
|
|
|
|
let builder = Builder::from(&self.docker_current_dir)?;
|
|
let builder_name = match builder.get_name() {
|
|
Some(n) => n, None => {
|
|
warning!("Unknown builder, use default: cargo");
|
|
"cargo".into() // default use cargo?
|
|
},
|
|
};
|
|
|
|
let mut sub_cmd = String::with_capacity(1024);
|
|
if let Some(mirror) = self.mirror {
|
|
sub_cmd.push_str(&make_cmd(&mirror));
|
|
sub_cmd.push_str("\n");
|
|
}
|
|
|
|
let mut builder_cmd = builder_name;
|
|
let mut sub_build_cmd = vec![];
|
|
let mut cmds_iter = cmds.iter();
|
|
if let Some(cmd0) = cmds_iter.next() {
|
|
if cmd0.starts_with(":") {
|
|
builder_cmd = cmd0.chars().skip(1).collect::<String>();
|
|
} else {
|
|
sub_build_cmd.push(cmd0.clone());
|
|
}
|
|
} else {
|
|
warning!("Docker build param is empty!");
|
|
}
|
|
cmds_iter.for_each(|c| { sub_build_cmd.push(c.clone()); });
|
|
|
|
sub_cmd.push_str(&builder_cmd);
|
|
sub_cmd.push(' ');
|
|
sub_cmd.push_str(&sub_build_cmd.iter().map(|arg| escape_arg(arg)).collect::<Vec<_>>().join(" "));
|
|
|
|
fs::write(DCOLER_TEMP_CMD, &sub_cmd).ok();
|
|
|
|
cmd.args(vec!["bash", DCOLER_TEMP_CMD]);
|
|
|
|
success!("Docker cmd exec: {:?}", cmd);
|
|
success!("Docker temp sub cmd: {}", sub_cmd);
|
|
let r = util_cmd::run_command_and_wait(&mut cmd).map_err(|e| e.into());
|
|
fs::remove_file(DCOLER_TEMP_CMD).ok();
|
|
r
|
|
}
|
|
}
|
|
|
|
fn escape_arg(arg: &str) -> String {
|
|
let mut r = String::with_capacity(arg.len() + 10);
|
|
r.push('\'');
|
|
for c in arg.chars() {
|
|
if c == '\'' {
|
|
r.push('\\');
|
|
}
|
|
r.push(c);
|
|
}
|
|
r.push('\'');
|
|
r
|
|
}
|
|
|
|
fn make_cmd(mirror: &str) -> String {
|
|
let mut s = String::with_capacity(256);
|
|
s.push_str(&format!(r#"echo '[source.crates-io]
|
|
registry = "https://github.com/rust-lang/crates.io-index"
|
|
replace-with = "mirror"
|
|
[source.mirror]
|
|
registry = "{}"
|
|
' > /usr/local/cargo/config"#, mirror));
|
|
s
|
|
}
|