mirror of
https://github.com/moghtech/komodo.git
synced 2026-04-29 21:27:26 -05:00
125 lines
3.8 KiB
Rust
125 lines
3.8 KiB
Rust
use std::{collections::HashMap, path::PathBuf};
|
|
|
|
use anyhow::{anyhow, Context};
|
|
use helpers::to_monitor_name;
|
|
use types::{Build, DockerBuildArgs, EnvironmentVar, Log, Version};
|
|
|
|
use crate::helpers::run_monitor_command;
|
|
|
|
use super::{docker_login, parse_extra_args};
|
|
|
|
pub async fn prune_images() -> Log {
|
|
let command = format!("docker image prune -a -f");
|
|
run_monitor_command("prune images", command).await
|
|
}
|
|
|
|
pub async fn build(
|
|
Build {
|
|
name,
|
|
version,
|
|
docker_build_args,
|
|
docker_account,
|
|
docker_organization,
|
|
skip_secret_interp,
|
|
..
|
|
}: &Build,
|
|
mut repo_dir: PathBuf,
|
|
docker_token: Option<String>,
|
|
secrets: &HashMap<String, String>,
|
|
) -> anyhow::Result<Vec<Log>> {
|
|
let mut logs = Vec::new();
|
|
let DockerBuildArgs {
|
|
build_path,
|
|
dockerfile_path,
|
|
build_args,
|
|
extra_args,
|
|
use_buildx,
|
|
} = docker_build_args
|
|
.as_ref()
|
|
.ok_or(anyhow!("build missing docker build args"))?;
|
|
let name = to_monitor_name(name);
|
|
let using_account = docker_login(docker_account, &docker_token)
|
|
.await
|
|
.context("failed to login to docker")?;
|
|
repo_dir.push(&name);
|
|
let build_dir = repo_dir.join(build_path);
|
|
let dockerfile_path = match dockerfile_path {
|
|
Some(dockerfile_path) => dockerfile_path.to_owned(),
|
|
None => "Dockerfile".to_owned(),
|
|
};
|
|
let build_args = parse_build_args(build_args);
|
|
let extra_args = parse_extra_args(extra_args);
|
|
let buildx = if *use_buildx {
|
|
" buildx"
|
|
} else {
|
|
""
|
|
};
|
|
let image_name = get_image_name(&name, docker_account, docker_organization);
|
|
let image_tags = image_tags(&image_name, &version);
|
|
let docker_push = if using_account {
|
|
format!(" && docker image push --all-tags {image_name}")
|
|
} else {
|
|
String::new()
|
|
};
|
|
let command = format!(
|
|
"cd {} && docker{buildx} build {build_args}{extra_args}{image_tags} -f {dockerfile_path} .{docker_push}",
|
|
build_dir.display()
|
|
);
|
|
if *skip_secret_interp {
|
|
let build_log = run_monitor_command("docker build", command).await;
|
|
logs.push(build_log);
|
|
} else {
|
|
let (command, replacers) =
|
|
svi::interpolate_variables(&command, secrets, svi::Interpolator::DoubleBrackets)
|
|
.context("failed to interpolate secrets into docker build command")?;
|
|
let mut build_log = run_monitor_command("docker build", command).await;
|
|
build_log.command = svi::replace_in_string(&build_log.command, &replacers);
|
|
build_log.stdout = svi::replace_in_string(&build_log.stdout, &replacers);
|
|
build_log.stderr = svi::replace_in_string(&build_log.stderr, &replacers);
|
|
logs.push(build_log);
|
|
}
|
|
Ok(logs)
|
|
}
|
|
|
|
fn get_image_name(
|
|
name: &str,
|
|
docker_account: &Option<String>,
|
|
docker_organization: &Option<String>,
|
|
) -> String {
|
|
match docker_organization {
|
|
Some(docker_org) => format!("{docker_org}/{name}"),
|
|
None => match docker_account {
|
|
Some(docker_account) => format!("{docker_account}/{name}"),
|
|
None => name.to_string(),
|
|
},
|
|
}
|
|
}
|
|
|
|
fn get_version_image_name(image_name: &str, version: &Version) -> String {
|
|
format!("{image_name}:{}", version.to_string())
|
|
}
|
|
|
|
fn get_latest_image_name(image_name: &str) -> String {
|
|
format!("{image_name}:latest")
|
|
}
|
|
|
|
fn image_tags(image_name: &str, version: &Version) -> String {
|
|
format!(
|
|
"-t {} -t {}",
|
|
get_version_image_name(image_name, version),
|
|
get_latest_image_name(image_name)
|
|
)
|
|
}
|
|
|
|
fn parse_build_args(build_args: &Vec<EnvironmentVar>) -> String {
|
|
let mut args = build_args
|
|
.iter()
|
|
.map(|p| format!(" --build-arg {}={}", p.variable, p.value))
|
|
.collect::<Vec<String>>()
|
|
.join("");
|
|
if args.len() > 0 {
|
|
args.push(' ');
|
|
}
|
|
args
|
|
}
|