build using bollard, not CLI
This commit is contained in:
parent
a9aa989b66
commit
de6969f824
@ -1,14 +1,19 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use bollard::{Docker, body_full};
|
||||||
use dockerfile_builder::Dockerfile;
|
use dockerfile_builder::Dockerfile;
|
||||||
use dockerfile_builder::instruction::{CMD, COPY, ENV, EXPOSE, FROM, RUN, USER, WORKDIR};
|
use dockerfile_builder::instruction::{CMD, COPY, ENV, EXPOSE, FROM, RUN, USER, WORKDIR};
|
||||||
use dockerfile_builder::instruction_builder::CopyBuilder;
|
use dockerfile_builder::instruction_builder::CopyBuilder;
|
||||||
|
use futures_util::StreamExt;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use tar::Archive;
|
||||||
|
use tempfile::tempfile;
|
||||||
|
|
||||||
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
use crate::config::{REGISTRY_PROJECT, REGISTRY_URL};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -108,6 +113,7 @@ impl OCICompliant for RustWebapp {
|
|||||||
// 1. Build the local image by calling the synchronous helper function.
|
// 1. Build the local image by calling the synchronous helper function.
|
||||||
let local_image_name = self.local_image_name();
|
let local_image_name = self.local_image_name();
|
||||||
self.build_docker_image(&local_image_name)
|
self.build_docker_image(&local_image_name)
|
||||||
|
.await
|
||||||
.map_err(|e| format!("Failed to build Docker image: {}", e))?;
|
.map_err(|e| format!("Failed to build Docker image: {}", e))?;
|
||||||
info!(
|
info!(
|
||||||
"Successfully built local Docker image: {}",
|
"Successfully built local Docker image: {}",
|
||||||
@ -153,31 +159,46 @@ impl RustWebapp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the Docker image using the generated Dockerfile.
|
/// Builds the Docker image using the generated Dockerfile.
|
||||||
pub fn build_docker_image(
|
pub async fn build_docker_image(
|
||||||
&self,
|
&self,
|
||||||
image_name: &str,
|
image_name: &str,
|
||||||
) -> Result<String, Box<dyn std::error::Error>> {
|
) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
info!("Generating Dockerfile for '{}'", self.name);
|
info!("Generating Dockerfile for '{}'", self.name);
|
||||||
let dockerfile_path = self.build_dockerfile()?;
|
let _dockerfile_path = self.build_dockerfile()?;
|
||||||
|
|
||||||
info!(
|
let docker = Docker::connect_with_socket_defaults().unwrap();
|
||||||
"Building Docker image with file {} from root {}",
|
|
||||||
dockerfile_path.to_string_lossy(),
|
let build_image_options = bollard::query_parameters::BuildImageOptionsBuilder::default()
|
||||||
self.project_root.to_string_lossy()
|
.dockerfile("Dockerfile.harmony")
|
||||||
|
.t(image_name)
|
||||||
|
.q(false)
|
||||||
|
.version(bollard::query_parameters::BuilderVersion::BuilderV1)
|
||||||
|
.platform("linux/x86_64");
|
||||||
|
|
||||||
|
let mut temp_tar_builder = tar::Builder::new(Vec::new());
|
||||||
|
let _ = temp_tar_builder
|
||||||
|
.append_dir_all("", self.project_root.clone())
|
||||||
|
.unwrap();
|
||||||
|
let archive = temp_tar_builder
|
||||||
|
.into_inner()
|
||||||
|
.expect("couldn't finish creating tar");
|
||||||
|
let archived_files = Archive::new(archive.as_slice())
|
||||||
|
.entries()
|
||||||
|
.unwrap()
|
||||||
|
.map(|entry| entry.unwrap().path().unwrap().into_owned())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
debug!("files in docker tar: {:#?}", archived_files);
|
||||||
|
|
||||||
|
let mut image_build_stream = docker.build_image(
|
||||||
|
build_image_options.build(),
|
||||||
|
None,
|
||||||
|
Some(body_full(archive.into())),
|
||||||
);
|
);
|
||||||
let output = process::Command::new("docker")
|
|
||||||
.args([
|
|
||||||
"build",
|
|
||||||
"--file",
|
|
||||||
dockerfile_path.to_str().unwrap(),
|
|
||||||
"-t",
|
|
||||||
&image_name,
|
|
||||||
self.project_root.to_str().unwrap(),
|
|
||||||
])
|
|
||||||
.spawn()?
|
|
||||||
.wait_with_output()?;
|
|
||||||
|
|
||||||
self.check_output(&output, "Failed to build Docker image")?;
|
while let Some(msg) = image_build_stream.next().await {
|
||||||
|
println!("Message: {msg:?}");
|
||||||
|
}
|
||||||
|
|
||||||
Ok(image_name.to_string())
|
Ok(image_name.to_string())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user