From de6969f824cfd58088cd84d8815d9beebd59badd Mon Sep 17 00:00:00 2001 From: tahahawa Date: Wed, 9 Jul 2025 00:13:51 -0400 Subject: [PATCH] build using bollard, not CLI --- harmony/src/modules/application/rust.rs | 57 +++++++++++++++++-------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/harmony/src/modules/application/rust.rs b/harmony/src/modules/application/rust.rs index ac684b8..8e1d03b 100644 --- a/harmony/src/modules/application/rust.rs +++ b/harmony/src/modules/application/rust.rs @@ -1,14 +1,19 @@ use std::fs; +use std::io::Read; use std::path::PathBuf; use std::process; use std::sync::Arc; use async_trait::async_trait; +use bollard::{Docker, body_full}; use dockerfile_builder::Dockerfile; use dockerfile_builder::instruction::{CMD, COPY, ENV, EXPOSE, FROM, RUN, USER, WORKDIR}; use dockerfile_builder::instruction_builder::CopyBuilder; +use futures_util::StreamExt; use log::{debug, error, info}; use serde::Serialize; +use tar::Archive; +use tempfile::tempfile; use crate::config::{REGISTRY_PROJECT, REGISTRY_URL}; use crate::{ @@ -108,6 +113,7 @@ impl OCICompliant for RustWebapp { // 1. Build the local image by calling the synchronous helper function. let local_image_name = self.local_image_name(); self.build_docker_image(&local_image_name) + .await .map_err(|e| format!("Failed to build Docker image: {}", e))?; info!( "Successfully built local Docker image: {}", @@ -153,31 +159,46 @@ impl RustWebapp { } /// Builds the Docker image using the generated Dockerfile. - pub fn build_docker_image( + pub async fn build_docker_image( &self, image_name: &str, ) -> Result> { info!("Generating Dockerfile for '{}'", self.name); - let dockerfile_path = self.build_dockerfile()?; + let _dockerfile_path = self.build_dockerfile()?; - info!( - "Building Docker image with file {} from root {}", - dockerfile_path.to_string_lossy(), - self.project_root.to_string_lossy() + let docker = Docker::connect_with_socket_defaults().unwrap(); + + let build_image_options = bollard::query_parameters::BuildImageOptionsBuilder::default() + .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::>(); + + 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()) }