diff --git a/src/commands/build.rs b/src/commands/build.rs index b1234807..c1695469 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -21,7 +21,10 @@ use typed_builder::TypedBuilder; use crate::{ commands::template::TemplateCommand, credentials, - drivers::{opts::BuildTagPushOpts, Driver}, + drivers::{ + opts::{BuildTagPushOpts, CompressionType}, + Driver, + }, }; use super::BlueBuildCommand; @@ -42,6 +45,12 @@ pub struct BuildCommand { #[builder(default)] push: bool, + /// The compression format the images + /// will be pushed in. + #[arg(short, long, default_value_t = CompressionType::Zstd)] + #[builder(default)] + compression_format: CompressionType, + /// Block `bluebuild` from retrying to push the image. #[arg(short, long, default_value_t = true)] #[builder(default)] @@ -207,6 +216,7 @@ impl BuildCommand { .push(self.push) .no_retry_push(self.no_retry_push) .retry_count(self.retry_count) + .compression(self.compression_format) .build() }; diff --git a/src/drivers.rs b/src/drivers.rs index b8cc257c..c3f8d308 100644 --- a/src/drivers.rs +++ b/src/drivers.rs @@ -22,8 +22,11 @@ use uuid::Uuid; use crate::{credentials, image_metadata::ImageMetadata}; use self::{ - buildah_driver::BuildahDriver, docker_driver::DockerDriver, opts::BuildTagPushOpts, - podman_driver::PodmanDriver, skopeo_driver::SkopeoDriver, + buildah_driver::BuildahDriver, + docker_driver::DockerDriver, + opts::{BuildTagPushOpts, CompressionType}, + podman_driver::PodmanDriver, + skopeo_driver::SkopeoDriver, }; mod buildah_driver; @@ -117,7 +120,7 @@ pub trait BuildDriver: Sync + Send { /// /// # Errors /// Will error if the push fails. - fn push(&self, image: &str) -> Result<()>; + fn push(&self, image: &str, compression: CompressionType) -> Result<()>; /// Runs the login logic for the strategy. /// @@ -173,7 +176,7 @@ pub trait BuildDriver: Sync + Send { debug!("Pushing image {tag_image}"); - self.push(&tag_image) + self.push(&tag_image, opts.compression) })?; } } diff --git a/src/drivers/buildah_driver.rs b/src/drivers/buildah_driver.rs index d3379cd5..1cae33c5 100644 --- a/src/drivers/buildah_driver.rs +++ b/src/drivers/buildah_driver.rs @@ -7,7 +7,7 @@ use serde::Deserialize; use crate::credentials; -use super::{BuildDriver, DriverVersion}; +use super::{opts::CompressionType, BuildDriver, DriverVersion}; #[derive(Debug, Deserialize)] struct BuildahVersionJson { @@ -68,9 +68,13 @@ impl BuildDriver for BuildahDriver { Ok(()) } - fn push(&self, image: &str) -> Result<()> { + fn push(&self, image: &str, compression: CompressionType) -> Result<()> { trace!("buildah push {image}"); - let status = Command::new("buildah").arg("push").arg(image).status()?; + let status = Command::new("buildah") + .arg("push") + .arg(format!("--compression-format={compression}")) + .arg(image) + .status()?; if status.success() { info!("Successfully pushed {image}!"); diff --git a/src/drivers/docker_driver.rs b/src/drivers/docker_driver.rs index 4a533ba8..50a6cc29 100644 --- a/src/drivers/docker_driver.rs +++ b/src/drivers/docker_driver.rs @@ -11,7 +11,11 @@ use serde::Deserialize; use crate::image_metadata::ImageMetadata; -use super::{credentials, opts::BuildTagPushOpts, BuildDriver, DriverVersion, InspectDriver}; +use super::{ + credentials, + opts::{BuildTagPushOpts, CompressionType}, + BuildDriver, DriverVersion, InspectDriver, +}; #[derive(Debug, Deserialize)] struct DockerVerisonJsonClient { @@ -88,7 +92,7 @@ impl BuildDriver for DockerDriver { Ok(()) } - fn push(&self, image: &str) -> Result<()> { + fn push(&self, image: &str, _: CompressionType) -> Result<()> { trace!("DockerDriver::push({image})"); trace!("docker push {image}"); @@ -162,8 +166,11 @@ impl BuildDriver for DockerDriver { } if opts.push { - trace!("--push"); - command.arg("--push"); + trace!("--output type=image,name={image},push=true,compression={},oci-mediatypes=true", opts.compression); + command.arg("--output").arg(format!( + "type=image,name={image},push=true,compression={},oci-mediatypes=true", + opts.compression + )); } else { trace!("--builder default"); command.arg("--builder").arg("default"); diff --git a/src/drivers/opts/build.rs b/src/drivers/opts/build.rs index 1a82c2cd..2a39033b 100644 --- a/src/drivers/opts/build.rs +++ b/src/drivers/opts/build.rs @@ -1,7 +1,24 @@ use std::borrow::Cow; +use clap::ValueEnum; use typed_builder::TypedBuilder; +#[derive(Debug, Copy, Clone, Default, ValueEnum)] +pub enum CompressionType { + #[default] + Zstd, + Gzip, +} + +impl std::fmt::Display for CompressionType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Zstd => "zstd", + Self::Gzip => "gzip", + }) + } +} + /// Options for building, tagging, and pusing images. #[derive(Debug, Clone, TypedBuilder)] pub struct BuildTagPushOpts<'a> { @@ -34,4 +51,7 @@ pub struct BuildTagPushOpts<'a> { /// Defaults to 1. #[builder(default = 1)] pub retry_count: u8, + + #[builder(default)] + pub compression: CompressionType, } diff --git a/src/drivers/podman_driver.rs b/src/drivers/podman_driver.rs index aa05ef06..8debd851 100644 --- a/src/drivers/podman_driver.rs +++ b/src/drivers/podman_driver.rs @@ -8,7 +8,7 @@ use serde::Deserialize; use crate::image_metadata::ImageMetadata; -use super::{credentials, BuildDriver, DriverVersion, InspectDriver}; +use super::{credentials, opts::CompressionType, BuildDriver, DriverVersion, InspectDriver}; #[derive(Debug, Deserialize)] struct PodmanVersionJsonClient { @@ -79,9 +79,13 @@ impl BuildDriver for PodmanDriver { Ok(()) } - fn push(&self, image: &str) -> Result<()> { + fn push(&self, image: &str, compression: CompressionType) -> Result<()> { trace!("podman push {image}"); - let status = Command::new("podman").arg("push").arg(image).status()?; + let status = Command::new("podman") + .arg("push") + .arg(format!("--compression-format={compression}")) + .arg(image) + .status()?; if status.success() { info!("Successfully pushed {image}!");