linera_service/cli_wrappers/
docker.rs1use std::path::PathBuf;
5
6use anyhow::{Context, Result};
7use linera_base::command::{current_binary_parent, CommandExt};
8use pathdiff::diff_paths;
9use tokio::process::Command;
10
11use crate::cli_wrappers::local_kubernetes_net::BuildMode;
12
13pub struct DockerImage {
14 name: String,
15}
16
17impl DockerImage {
18 pub fn name(&self) -> &String {
19 &self.name
20 }
21
22 pub async fn build(
23 name: &str,
24 binaries: &BuildArg,
25 github_root: &PathBuf,
26 build_mode: &BuildMode,
27 dual_store: bool,
28 ) -> Result<Self> {
29 let build_arg = match binaries {
30 BuildArg::Directory(bin_path) => {
31 let bin_path =
33 diff_paths(bin_path, github_root).context("Getting relative path failed")?;
34 let bin_path_str = bin_path.to_str().context("Getting str failed")?;
35 format!("binaries={bin_path_str}")
36 }
37 BuildArg::ParentDirectory => {
38 let parent_path = current_binary_parent()
40 .expect("Fetching current binaries path should not fail");
41 let bin_path =
42 diff_paths(parent_path, github_root).context("Getting relative path failed")?;
43 let bin_path_str = bin_path.to_str().context("Getting str failed")?;
44 format!("binaries={bin_path_str}")
45 }
46 BuildArg::Build => {
47 let arch = std::env::consts::ARCH;
49 let docker_arch = match arch {
51 "arm" => "aarch",
52 _ => arch,
53 };
54 format!("target={}-unknown-linux-gnu", docker_arch)
55 }
56 };
57
58 let docker_image = Self {
59 name: name.to_owned(),
60 };
61 let mut command = Command::new("docker");
62 command
63 .current_dir(github_root)
64 .arg("build")
65 .args(["-f", "docker/Dockerfile"])
66 .args(["--build-arg", &build_arg]);
67
68 match build_mode {
69 BuildMode::Release => {}
71 BuildMode::Debug => {
72 command.args(["--build-arg", "build_folder=debug"]);
73 command.args(["--build-arg", "build_flag="]);
74 }
75 }
76
77 if dual_store {
78 command.args(["--build-arg", "build_features=rocksdb,scylladb,metrics"]);
79 }
80
81 #[cfg(not(with_testing))]
82 command
83 .args([
84 "--build-arg",
85 &format!(
86 "git_commit={}",
87 linera_version::VersionInfo::get()?.git_commit
88 ),
89 ])
90 .args([
91 "--build-arg",
92 &format!(
93 "build_date={}",
94 chrono::Utc::now().format("%a %b %d %T UTC %Y")
96 ),
97 ]);
98
99 command.arg(".").args(["-t", name]).spawn_and_wait().await?;
100 Ok(docker_image)
101 }
102}
103
104#[derive(Clone)]
106pub enum BuildArg {
107 Build,
109 ParentDirectory,
111 Directory(PathBuf),
113}
114
115impl From<Option<Option<PathBuf>>> for BuildArg {
116 fn from(arg: Option<Option<PathBuf>>) -> Self {
117 match arg {
118 None => BuildArg::Build,
119 Some(None) => BuildArg::ParentDirectory,
120 Some(Some(path)) => BuildArg::Directory(path),
121 }
122 }
123}