linera_service/cli_wrappers/
docker.rsuse std::path::PathBuf;
use anyhow::{Context, Result};
use linera_base::command::{current_binary_parent, CommandExt};
use pathdiff::diff_paths;
use tokio::process::Command;
use crate::cli_wrappers::local_kubernetes_net::BuildMode;
pub struct DockerImage {
name: String,
}
impl DockerImage {
pub fn name(&self) -> &String {
&self.name
}
pub async fn build(
name: &str,
binaries: &BuildArg,
github_root: &PathBuf,
build_mode: &BuildMode,
) -> Result<Self> {
let build_arg = match binaries {
BuildArg::Directory(bin_path) => {
let bin_path =
diff_paths(bin_path, github_root).context("Getting relative path failed")?;
let bin_path_str = bin_path.to_str().context("Getting str failed")?;
format!("binaries={bin_path_str}")
}
BuildArg::ParentDirectory => {
let parent_path = current_binary_parent()
.expect("Fetching current binaries path should not fail");
let bin_path =
diff_paths(parent_path, github_root).context("Getting relative path failed")?;
let bin_path_str = bin_path.to_str().context("Getting str failed")?;
format!("binaries={bin_path_str}")
}
BuildArg::Build => {
let arch = std::env::consts::ARCH;
let docker_arch = match arch {
"arm" => "aarch",
_ => arch,
};
format!("target={}-unknown-linux-gnu", docker_arch)
}
};
let docker_image = Self {
name: name.to_owned(),
};
let mut command = Command::new("docker");
command
.current_dir(github_root)
.arg("build")
.args(["-f", "docker/Dockerfile"])
.args(["--build-arg", &build_arg]);
match build_mode {
BuildMode::Release => {
command.args(["--build-arg", "build_flag=--release"]);
command.args(["--build-arg", "build_folder=release"]);
}
BuildMode::Debug => {
command.args(["--build-arg", "build_folder=debug"]);
}
}
#[cfg(not(with_testing))]
command
.args([
"--build-arg",
&format!(
"git_commit={}",
linera_version::VersionInfo::get()?.git_commit
),
])
.args([
"--build-arg",
&format!(
"build_date={}",
chrono::Utc::now().format("%a %b %d %T UTC %Y")
),
]);
command.arg(".").args(["-t", name]).spawn_and_wait().await?;
Ok(docker_image)
}
}
#[derive(Clone)]
pub enum BuildArg {
Build,
ParentDirectory,
Directory(PathBuf),
}
impl From<Option<Option<PathBuf>>> for BuildArg {
fn from(arg: Option<Option<PathBuf>>) -> Self {
match arg {
None => BuildArg::Build,
Some(None) => BuildArg::ParentDirectory,
Some(Some(path)) => BuildArg::Directory(path),
}
}
}