feat: Add platform arg to force building a specific architecture
This commit is contained in:
parent
20d1950530
commit
75eae89e4a
22 changed files with 408 additions and 71 deletions
|
|
@ -6,7 +6,7 @@ use miette::{bail, miette, IntoDiagnostic, Result};
|
|||
use semver::Version;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::logging::CommandLogging;
|
||||
use crate::{drivers::types::Platform, logging::CommandLogging};
|
||||
|
||||
use super::{
|
||||
opts::{BuildOpts, PushOpts, TagOpts},
|
||||
|
|
@ -50,6 +50,10 @@ impl BuildDriver for BuildahDriver {
|
|||
let command = cmd!(
|
||||
"buildah",
|
||||
"build",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
opts.platform.to_string(),
|
||||
],
|
||||
"--pull=true",
|
||||
format!("--layers={}", !opts.squash),
|
||||
"-f",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use blue_build_utils::{
|
|||
constants::{BB_BUILDKIT_CACHE_GHA, CONTAINER_FILE, DOCKER_HOST, SKOPEO_IMAGE},
|
||||
credentials::Credentials,
|
||||
string_vec,
|
||||
traits::IntoCollector,
|
||||
};
|
||||
use colored::Colorize;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
|
|
@ -26,6 +27,7 @@ use crate::{
|
|||
drivers::{
|
||||
image_metadata::ImageMetadata,
|
||||
opts::{RunOptsEnv, RunOptsVolume},
|
||||
types::Platform,
|
||||
},
|
||||
logging::{CommandLogging, Logger},
|
||||
signal_handler::{add_cid, remove_cid, ContainerId, ContainerRuntime},
|
||||
|
|
@ -130,6 +132,10 @@ impl BuildDriver for DockerDriver {
|
|||
let status = cmd!(
|
||||
"docker",
|
||||
"build",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
opts.platform.to_string(),
|
||||
],
|
||||
"-t",
|
||||
&*opts.image,
|
||||
"-f",
|
||||
|
|
@ -235,6 +241,10 @@ impl BuildDriver for DockerDriver {
|
|||
},
|
||||
"build",
|
||||
"--pull",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
opts.platform.to_string(),
|
||||
],
|
||||
"-f",
|
||||
&*opts.containerfile,
|
||||
// https://github.com/moby/buildkit?tab=readme-ov-file#github-actions-cache-experimental
|
||||
|
|
@ -322,10 +332,16 @@ impl InspectDriver for DockerDriver {
|
|||
);
|
||||
progress.enable_steady_tick(Duration::from_millis(100));
|
||||
|
||||
let mut args = Vec::new();
|
||||
if !matches!(opts.platform, Platform::Native) {
|
||||
args.extend(["--override-arch", opts.platform.arch()]);
|
||||
}
|
||||
args.extend(["inspect", &url]);
|
||||
|
||||
let output = Self::run_output(
|
||||
&RunOpts::builder()
|
||||
.image(SKOPEO_IMAGE)
|
||||
.args(bon::vec!["inspect", &url])
|
||||
.args(args.collect_into_vec())
|
||||
.remove(true)
|
||||
.build(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,11 @@ impl CiDriver for GithubDriver {
|
|||
fn generate_tags(opts: &GenerateTagsOpts) -> miette::Result<Vec<String>> {
|
||||
const PR_EVENT: &str = "pull_request";
|
||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||
let os_version =
|
||||
Driver::get_os_version(opts.oci_ref).inspect(|v| trace!("os_version={v}"))?;
|
||||
let os_version = Driver::get_os_version()
|
||||
.oci_ref(opts.oci_ref)
|
||||
.platform(opts.platform)
|
||||
.call()
|
||||
.inspect(|v| trace!("os_version={v}"))?;
|
||||
let ref_name = get_env_var(GITHUB_REF_NAME).inspect(|v| trace!("{GITHUB_REF_NAME}={v}"))?;
|
||||
let short_sha = {
|
||||
let mut short_sha = get_env_var(GITHUB_SHA).inspect(|v| trace!("{GITHUB_SHA}={v}"))?;
|
||||
|
|
@ -144,7 +147,7 @@ mod test {
|
|||
use rstest::rstest;
|
||||
|
||||
use crate::{
|
||||
drivers::{opts::GenerateTagsOpts, CiDriver},
|
||||
drivers::{opts::GenerateTagsOpts, types::Platform, CiDriver},
|
||||
test::{TEST_TAG_1, TEST_TAG_2, TIMESTAMP},
|
||||
};
|
||||
|
||||
|
|
@ -285,6 +288,7 @@ mod test {
|
|||
&GenerateTagsOpts::builder()
|
||||
.oci_ref(&oci_ref)
|
||||
.maybe_alt_tags(alt_tags)
|
||||
.platform(Platform::LinuxAmd64)
|
||||
.build(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ impl CiDriver for GitlabDriver {
|
|||
|
||||
fn generate_tags(opts: &GenerateTagsOpts) -> miette::Result<Vec<String>> {
|
||||
const MR_EVENT: &str = "merge_request_event";
|
||||
let os_version = Driver::get_os_version(opts.oci_ref)?;
|
||||
let os_version = Driver::get_os_version()
|
||||
.oci_ref(opts.oci_ref)
|
||||
.platform(opts.platform)
|
||||
.call()?;
|
||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||
let short_sha =
|
||||
get_env_var(CI_COMMIT_SHORT_SHA).inspect(|v| trace!("{CI_COMMIT_SHORT_SHA}={v}"))?;
|
||||
|
|
@ -293,6 +296,7 @@ mod test {
|
|||
&GenerateTagsOpts::builder()
|
||||
.oci_ref(&oci_ref)
|
||||
.maybe_alt_tags(alt_tags)
|
||||
.platform(crate::drivers::types::Platform::LinuxAmd64)
|
||||
.build(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ impl CiDriver for LocalDriver {
|
|||
|
||||
fn generate_tags(opts: &GenerateTagsOpts) -> miette::Result<Vec<String>> {
|
||||
trace!("LocalDriver::generate_tags({opts:?})");
|
||||
let os_version = Driver::get_os_version(opts.oci_ref)?;
|
||||
let os_version = Driver::get_os_version()
|
||||
.oci_ref(opts.oci_ref)
|
||||
.platform(opts.platform)
|
||||
.call()?;
|
||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||
let short_sha = commit_sha();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use std::{borrow::Cow, path::Path};
|
|||
|
||||
use bon::Builder;
|
||||
|
||||
use crate::drivers::types::Platform;
|
||||
|
||||
use super::CompressionType;
|
||||
|
||||
/// Options for building
|
||||
|
|
@ -15,14 +17,15 @@ pub struct BuildOpts<'scope> {
|
|||
|
||||
#[builder(into)]
|
||||
pub containerfile: Cow<'scope, Path>,
|
||||
|
||||
#[builder(default)]
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
#[builder(on(Cow<'_, str>, into))]
|
||||
pub struct TagOpts<'scope> {
|
||||
#[builder(into)]
|
||||
pub src_image: Cow<'scope, str>,
|
||||
|
||||
#[builder(into)]
|
||||
pub dest_image: Cow<'scope, str>,
|
||||
}
|
||||
|
||||
|
|
@ -80,4 +83,8 @@ pub struct BuildTagPushOpts<'scope> {
|
|||
/// Run all steps in a single layer.
|
||||
#[builder(default)]
|
||||
pub squash: bool,
|
||||
|
||||
/// The platform to build the image on.
|
||||
#[builder(default)]
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,17 @@ use std::borrow::Cow;
|
|||
use bon::Builder;
|
||||
use oci_distribution::Reference;
|
||||
|
||||
use crate::drivers::types::Platform;
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct GenerateTagsOpts<'scope> {
|
||||
pub oci_ref: &'scope Reference,
|
||||
|
||||
#[builder(into)]
|
||||
pub alt_tags: Option<Vec<Cow<'scope, str>>>,
|
||||
|
||||
#[builder(default)]
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ use std::borrow::Cow;
|
|||
|
||||
use bon::Builder;
|
||||
|
||||
use crate::drivers::types::Platform;
|
||||
|
||||
#[derive(Debug, Clone, Builder)]
|
||||
pub struct GetMetadataOpts<'scope> {
|
||||
#[builder(into)]
|
||||
|
|
@ -9,4 +11,7 @@ pub struct GetMetadataOpts<'scope> {
|
|||
|
||||
#[builder(into)]
|
||||
pub tag: Option<Cow<'scope, str>>,
|
||||
|
||||
#[builder(default)]
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ use bon::Builder;
|
|||
use miette::{IntoDiagnostic, Result};
|
||||
use zeroize::{Zeroize, Zeroizing};
|
||||
|
||||
use crate::drivers::types::Platform;
|
||||
|
||||
pub enum PrivateKey {
|
||||
Env(String),
|
||||
Path(PathBuf),
|
||||
|
|
@ -112,4 +114,7 @@ pub struct SignVerifyOpts<'scope> {
|
|||
/// Defaults to 1.
|
||||
#[builder(default = 1)]
|
||||
pub retry_count: u8,
|
||||
|
||||
#[builder(default)]
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use blue_build_utils::{cmd, constants::SKOPEO_IMAGE, credentials::Credentials};
|
||||
use blue_build_utils::{
|
||||
cmd, constants::SKOPEO_IMAGE, credentials::Credentials, traits::IntoCollector,
|
||||
};
|
||||
use colored::Colorize;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use log::{debug, error, info, trace, warn};
|
||||
|
|
@ -18,6 +20,7 @@ use crate::{
|
|||
drivers::{
|
||||
image_metadata::ImageMetadata,
|
||||
opts::{RunOptsEnv, RunOptsVolume},
|
||||
types::Platform,
|
||||
},
|
||||
logging::{CommandLogging, Logger},
|
||||
signal_handler::{add_cid, remove_cid, ContainerId, ContainerRuntime},
|
||||
|
|
@ -72,6 +75,10 @@ impl BuildDriver for PodmanDriver {
|
|||
let command = cmd!(
|
||||
"podman",
|
||||
"build",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--platform",
|
||||
opts.platform.to_string(),
|
||||
],
|
||||
"--pull=true",
|
||||
format!("--layers={}", !opts.squash),
|
||||
"-f",
|
||||
|
|
@ -198,10 +205,16 @@ impl InspectDriver for PodmanDriver {
|
|||
);
|
||||
progress.enable_steady_tick(Duration::from_millis(100));
|
||||
|
||||
let mut args = Vec::new();
|
||||
if !matches!(opts.platform, Platform::Native) {
|
||||
args.extend(["--override-arch", opts.platform.arch()]);
|
||||
}
|
||||
args.extend(["inspect", &url]);
|
||||
|
||||
let output = Self::run_output(
|
||||
&RunOpts::builder()
|
||||
.image(SKOPEO_IMAGE)
|
||||
.args(bon::vec!["inspect", &url])
|
||||
.args(args.collect_into_vec())
|
||||
.remove(true)
|
||||
.build(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use indicatif::{ProgressBar, ProgressStyle};
|
|||
use log::{debug, trace};
|
||||
use miette::{bail, IntoDiagnostic, Result};
|
||||
|
||||
use crate::logging::Logger;
|
||||
use crate::{drivers::types::Platform, logging::Logger};
|
||||
|
||||
use super::{image_metadata::ImageMetadata, opts::GetMetadataOpts, InspectDriver};
|
||||
|
||||
|
|
@ -29,11 +29,19 @@ impl InspectDriver for SkopeoDriver {
|
|||
);
|
||||
progress.enable_steady_tick(Duration::from_millis(100));
|
||||
|
||||
trace!("skopeo inspect {url}");
|
||||
let output = cmd!("skopeo", "inspect", &url)
|
||||
.stderr(Stdio::inherit())
|
||||
.output()
|
||||
.into_diagnostic()?;
|
||||
let mut command = cmd!(
|
||||
"skopeo",
|
||||
if !matches!(opts.platform, Platform::Native) => [
|
||||
"--override-arch",
|
||||
opts.platform.arch(),
|
||||
],
|
||||
"inspect",
|
||||
&url,
|
||||
stderr = Stdio::inherit(),
|
||||
);
|
||||
trace!("{command:?}");
|
||||
|
||||
let output = command.output().into_diagnostic()?;
|
||||
|
||||
progress.finish_and_clear();
|
||||
Logger::multi_progress().remove(&progress);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ pub trait BuildDriver {
|
|||
let build_opts = BuildOpts::builder()
|
||||
.image(&full_image)
|
||||
.containerfile(opts.containerfile.as_ref())
|
||||
.platform(opts.platform)
|
||||
.squash(opts.squash)
|
||||
.build();
|
||||
|
||||
|
|
@ -212,10 +213,12 @@ pub trait SigningDriver {
|
|||
.map_or_else(|| PathBuf::from("."), |d| d.to_path_buf());
|
||||
|
||||
let image_name: &str = opts.image.as_ref();
|
||||
let inspect_opts = GetMetadataOpts::builder().image(image_name);
|
||||
let inspect_opts = GetMetadataOpts::builder()
|
||||
.image(image_name)
|
||||
.platform(opts.platform);
|
||||
|
||||
let inspect_opts = if let Some(ref tag) = opts.tag {
|
||||
inspect_opts.tag(tag.as_ref() as &str).build()
|
||||
inspect_opts.tag(&**tag).build()
|
||||
} else {
|
||||
inspect_opts.build()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -167,3 +167,41 @@ impl DetermineDriver<CiDriverType> for Option<CiDriverType> {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, ValueEnum)]
|
||||
pub enum Platform {
|
||||
#[default]
|
||||
#[value(name = "native")]
|
||||
Native,
|
||||
#[value(name = "linux/amd64")]
|
||||
LinuxAmd64,
|
||||
|
||||
#[value(name = "linux/arm64")]
|
||||
LinuxArm64,
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
/// The architecture of the platform.
|
||||
#[must_use]
|
||||
pub const fn arch(&self) -> &str {
|
||||
match *self {
|
||||
Self::Native => "native",
|
||||
Self::LinuxAmd64 => "amd64",
|
||||
Self::LinuxArm64 => "arm64",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Platform {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
Self::Native => "native",
|
||||
Self::LinuxAmd64 => "linux/amd64",
|
||||
Self::LinuxArm64 => "linux/arm64",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue