feat: Add all linux platforms
This commit is contained in:
parent
de76312a38
commit
24a5c8d2b5
18 changed files with 185 additions and 78 deletions
|
|
@ -188,9 +188,9 @@ impl Driver {
|
||||||
pub fn get_os_version(
|
pub fn get_os_version(
|
||||||
/// The OCI image reference.
|
/// The OCI image reference.
|
||||||
oci_ref: &Reference,
|
oci_ref: &Reference,
|
||||||
|
|
||||||
/// The platform of the image to pull the version info from.
|
/// The platform of the image to pull the version info from.
|
||||||
#[builder(default)]
|
platform: Option<Platform>,
|
||||||
platform: Platform,
|
|
||||||
) -> Result<u64> {
|
) -> Result<u64> {
|
||||||
trace!("Driver::get_os_version({oci_ref:#?})");
|
trace!("Driver::get_os_version({oci_ref:#?})");
|
||||||
|
|
||||||
|
|
@ -208,7 +208,7 @@ impl Driver {
|
||||||
let os_version = Self::get_metadata(
|
let os_version = Self::get_metadata(
|
||||||
&GetMetadataOpts::builder()
|
&GetMetadataOpts::builder()
|
||||||
.image(oci_ref)
|
.image(oci_ref)
|
||||||
.platform(platform)
|
.maybe_platform(platform)
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
.and_then(|inspection| {
|
.and_then(|inspection| {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use miette::{Context, IntoDiagnostic, Result, bail, miette};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
use crate::{drivers::types::Platform, logging::CommandLogging};
|
use crate::logging::CommandLogging;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
BuildDriver, DriverVersion,
|
BuildDriver, DriverVersion,
|
||||||
|
|
@ -60,9 +60,9 @@ impl BuildDriver for BuildahDriver {
|
||||||
"build",
|
"build",
|
||||||
for opts.secrets.args(&temp_dir)?,
|
for opts.secrets.args(&temp_dir)?,
|
||||||
if opts.secrets.ssh() => "--ssh",
|
if opts.secrets.ssh() => "--ssh",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--platform",
|
"--platform",
|
||||||
opts.platform.to_string(),
|
platform.to_string(),
|
||||||
],
|
],
|
||||||
"--pull=true",
|
"--pull=true",
|
||||||
format!("--layers={}", !opts.squash),
|
format!("--layers={}", !opts.squash),
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ use crate::{
|
||||||
RunOptsVolume, TagOpts,
|
RunOptsVolume, TagOpts,
|
||||||
},
|
},
|
||||||
traits::{BuildDriver, DriverVersion, InspectDriver, RunDriver},
|
traits::{BuildDriver, DriverVersion, InspectDriver, RunDriver},
|
||||||
types::{ContainerId, ImageMetadata, ImageRef, Platform},
|
types::{ContainerId, ImageMetadata, ImageRef},
|
||||||
},
|
},
|
||||||
logging::CommandLogging,
|
logging::CommandLogging,
|
||||||
signal_handler::{ContainerRuntime, ContainerSignalId, add_cid, remove_cid},
|
signal_handler::{ContainerRuntime, ContainerSignalId, add_cid, remove_cid},
|
||||||
|
|
@ -207,9 +207,9 @@ impl BuildDriver for DockerDriver {
|
||||||
let c = cmd!(
|
let c = cmd!(
|
||||||
"docker",
|
"docker",
|
||||||
"build",
|
"build",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--platform",
|
"--platform",
|
||||||
opts.platform.to_string(),
|
platform.to_string(),
|
||||||
],
|
],
|
||||||
"-t",
|
"-t",
|
||||||
opts.image.to_string(),
|
opts.image.to_string(),
|
||||||
|
|
@ -456,9 +456,9 @@ fn build_tag_push_cmd(
|
||||||
}).collect()
|
}).collect()
|
||||||
}),
|
}),
|
||||||
"--pull",
|
"--pull",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--platform",
|
"--platform",
|
||||||
opts.platform.to_string(),
|
platform.to_string(),
|
||||||
],
|
],
|
||||||
"-f",
|
"-f",
|
||||||
&*opts.containerfile,
|
&*opts.containerfile,
|
||||||
|
|
@ -507,7 +507,7 @@ impl InspectDriver for DockerDriver {
|
||||||
#[cached(
|
#[cached(
|
||||||
result = true,
|
result = true,
|
||||||
key = "String",
|
key = "String",
|
||||||
convert = r#"{ format!("{}-{}", opts.image, opts.platform)}"#,
|
convert = r#"{ format!("{}-{:?}", opts.image, opts.platform)}"#,
|
||||||
sync_writes = "by_key"
|
sync_writes = "by_key"
|
||||||
)]
|
)]
|
||||||
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||||
use miette::{Report, bail};
|
use miette::{Report, bail};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::drivers::types::{ImageMetadata, Platform};
|
use crate::drivers::types::{ImageMetadata, Platform, PlatformInfo};
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
|
|
@ -48,10 +48,10 @@ pub struct Config {
|
||||||
labels: HashMap<String, serde_json::Value>,
|
labels: HashMap<String, serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<(Metadata, Platform)> for ImageMetadata {
|
impl TryFrom<(Metadata, Option<Platform>)> for ImageMetadata {
|
||||||
type Error = Report;
|
type Error = Report;
|
||||||
|
|
||||||
fn try_from((metadata, platform): (Metadata, Platform)) -> Result<Self, Self::Error> {
|
fn try_from((metadata, platform): (Metadata, Option<Platform>)) -> Result<Self, Self::Error> {
|
||||||
match metadata.image {
|
match metadata.image {
|
||||||
MetadataImage::Single(image) => Ok(Self {
|
MetadataImage::Single(image) => Ok(Self {
|
||||||
labels: image.config.labels,
|
labels: image.config.labels,
|
||||||
|
|
@ -59,7 +59,10 @@ impl TryFrom<(Metadata, Platform)> for ImageMetadata {
|
||||||
}),
|
}),
|
||||||
MetadataImage::Multi(mut platforms) => {
|
MetadataImage::Multi(mut platforms) => {
|
||||||
let Some(image) = platforms.remove(&platform.to_string()) else {
|
let Some(image) = platforms.remove(&platform.to_string()) else {
|
||||||
bail!("Image information does not exist for {platform}");
|
bail!(
|
||||||
|
"Image information does not exist for {}",
|
||||||
|
platform.to_string()
|
||||||
|
);
|
||||||
};
|
};
|
||||||
let Some(manifest) = metadata
|
let Some(manifest) = metadata
|
||||||
.manifest
|
.manifest
|
||||||
|
|
@ -67,7 +70,7 @@ impl TryFrom<(Metadata, Platform)> for ImageMetadata {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|manifest| manifest.platform.architecture == platform.arch())
|
.find(|manifest| manifest.platform.architecture == platform.arch())
|
||||||
else {
|
else {
|
||||||
bail!("Manifest does not exist for {platform}");
|
bail!("Manifest does not exist for {}", platform.to_string());
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
labels: image.config.labels,
|
labels: image.config.labels,
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl CiDriver for GithubDriver {
|
||||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||||
let os_version = Driver::get_os_version()
|
let os_version = Driver::get_os_version()
|
||||||
.oci_ref(opts.oci_ref)
|
.oci_ref(opts.oci_ref)
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.call()
|
.call()
|
||||||
.inspect(|v| trace!("os_version={v}"))?;
|
.inspect(|v| trace!("os_version={v}"))?;
|
||||||
let ref_name = get_env_var(GITHUB_REF_NAME)
|
let ref_name = get_env_var(GITHUB_REF_NAME)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ impl CiDriver for GitlabDriver {
|
||||||
const MR_EVENT: &str = "merge_request_event";
|
const MR_EVENT: &str = "merge_request_event";
|
||||||
let os_version = Driver::get_os_version()
|
let os_version = Driver::get_os_version()
|
||||||
.oci_ref(opts.oci_ref)
|
.oci_ref(opts.oci_ref)
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.call()?;
|
.call()?;
|
||||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||||
let short_sha =
|
let short_sha =
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ impl CiDriver for LocalDriver {
|
||||||
trace!("LocalDriver::generate_tags({opts:?})");
|
trace!("LocalDriver::generate_tags({opts:?})");
|
||||||
let os_version = Driver::get_os_version()
|
let os_version = Driver::get_os_version()
|
||||||
.oci_ref(opts.oci_ref)
|
.oci_ref(opts.oci_ref)
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.call()?;
|
.call()?;
|
||||||
let timestamp = blue_build_utils::get_tag_timestamp();
|
let timestamp = blue_build_utils::get_tag_timestamp();
|
||||||
let short_sha = commit_sha();
|
let short_sha = commit_sha();
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@ pub struct BuildOpts<'scope> {
|
||||||
#[builder(into)]
|
#[builder(into)]
|
||||||
pub containerfile: Cow<'scope, Path>,
|
pub containerfile: Cow<'scope, Path>,
|
||||||
|
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
|
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
pub host_network: bool,
|
pub host_network: bool,
|
||||||
|
|
@ -102,8 +101,7 @@ pub struct BuildTagPushOpts<'scope> {
|
||||||
pub squash: bool,
|
pub squash: bool,
|
||||||
|
|
||||||
/// The platform to build the image on.
|
/// The platform to build the image on.
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
|
|
||||||
/// Runs the build with elevated privileges
|
/// Runs the build with elevated privileges
|
||||||
#[builder(default)]
|
#[builder(default)]
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ pub struct GenerateTagsOpts<'scope> {
|
||||||
#[builder(into)]
|
#[builder(into)]
|
||||||
pub alt_tags: Option<Vec<Cow<'scope, str>>>,
|
pub alt_tags: Option<Vec<Cow<'scope, str>>>,
|
||||||
|
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Builder)]
|
#[derive(Debug, Clone, Builder)]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,5 @@ pub struct GetMetadataOpts<'scope> {
|
||||||
#[builder(into)]
|
#[builder(into)]
|
||||||
pub image: &'scope Reference,
|
pub image: &'scope Reference,
|
||||||
|
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@ pub struct RechunkOpts<'scope> {
|
||||||
#[builder(into)]
|
#[builder(into)]
|
||||||
pub containerfile: Cow<'scope, Path>,
|
pub containerfile: Cow<'scope, Path>,
|
||||||
|
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
pub version: Cow<'scope, str>,
|
pub version: Cow<'scope, str>,
|
||||||
pub name: Cow<'scope, str>,
|
pub name: Cow<'scope, str>,
|
||||||
pub description: Cow<'scope, str>,
|
pub description: Cow<'scope, str>,
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,5 @@ pub struct SignVerifyOpts<'scope> {
|
||||||
#[builder(default = 1)]
|
#[builder(default = 1)]
|
||||||
pub retry_count: u8,
|
pub retry_count: u8,
|
||||||
|
|
||||||
#[builder(default)]
|
pub platform: Option<Platform>,
|
||||||
pub platform: Platform,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ use crate::{
|
||||||
drivers::{
|
drivers::{
|
||||||
BuildDriver, DriverVersion, InspectDriver, RunDriver,
|
BuildDriver, DriverVersion, InspectDriver, RunDriver,
|
||||||
opts::{BuildOpts, GetMetadataOpts, PushOpts, RunOpts, RunOptsEnv, RunOptsVolume, TagOpts},
|
opts::{BuildOpts, GetMetadataOpts, PushOpts, RunOpts, RunOptsEnv, RunOptsVolume, TagOpts},
|
||||||
types::{ImageMetadata, Platform},
|
types::ImageMetadata,
|
||||||
},
|
},
|
||||||
logging::{CommandLogging, Logger},
|
logging::{CommandLogging, Logger},
|
||||||
signal_handler::{ContainerRuntime, ContainerSignalId, add_cid, remove_cid},
|
signal_handler::{ContainerRuntime, ContainerSignalId, add_cid, remove_cid},
|
||||||
|
|
@ -158,9 +158,9 @@ impl BuildDriver for PodmanDriver {
|
||||||
"podman",
|
"podman",
|
||||||
],
|
],
|
||||||
"build",
|
"build",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--platform",
|
"--platform",
|
||||||
opts.platform.to_string(),
|
platform.to_string(),
|
||||||
],
|
],
|
||||||
if let Some(cache_from) = opts.cache_from.as_ref() => [
|
if let Some(cache_from) = opts.cache_from.as_ref() => [
|
||||||
"--cache-from",
|
"--cache-from",
|
||||||
|
|
@ -347,7 +347,7 @@ impl InspectDriver for PodmanDriver {
|
||||||
#[cached(
|
#[cached(
|
||||||
result = true,
|
result = true,
|
||||||
key = "String",
|
key = "String",
|
||||||
convert = r#"{ format!("{}-{}", opts.image, opts.platform)}"#,
|
convert = r#"{ format!("{}-{:?}", opts.image, opts.platform)}"#,
|
||||||
sync_writes = "by_key"
|
sync_writes = "by_key"
|
||||||
)]
|
)]
|
||||||
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
||||||
|
|
@ -369,9 +369,9 @@ fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
||||||
let c = cmd!(
|
let c = cmd!(
|
||||||
"podman",
|
"podman",
|
||||||
"pull",
|
"pull",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--platform",
|
"--platform",
|
||||||
opts.platform.to_string(),
|
platform.to_string(),
|
||||||
],
|
],
|
||||||
&image_str,
|
&image_str,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ impl InspectDriver for SkopeoDriver {
|
||||||
#[cached(
|
#[cached(
|
||||||
result = true,
|
result = true,
|
||||||
key = "String",
|
key = "String",
|
||||||
convert = r#"{ format!("{}-{}", opts.image, opts.platform)}"#,
|
convert = r#"{ format!("{}-{:?}", opts.image, opts.platform)}"#,
|
||||||
sync_writes = "by_key"
|
sync_writes = "by_key"
|
||||||
)]
|
)]
|
||||||
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
||||||
|
|
@ -40,9 +40,13 @@ fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
|
||||||
|
|
||||||
let mut command = cmd!(
|
let mut command = cmd!(
|
||||||
"skopeo",
|
"skopeo",
|
||||||
if !matches!(opts.platform, Platform::Native) => [
|
if let Some(platform) = opts.platform => [
|
||||||
"--override-arch",
|
"--override-arch",
|
||||||
opts.platform.arch(),
|
platform.arch(),
|
||||||
|
],
|
||||||
|
if let Some(variant) = opts.platform.as_ref().and_then(Platform::variant) => [
|
||||||
|
"--override-variant",
|
||||||
|
variant,
|
||||||
],
|
],
|
||||||
"inspect",
|
"inspect",
|
||||||
format!("docker://{image_str}"),
|
format!("docker://{image_str}"),
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ pub trait BuildDriver: PrivateDriver {
|
||||||
let build_opts = BuildOpts::builder()
|
let build_opts = BuildOpts::builder()
|
||||||
.image(&opts.image)
|
.image(&opts.image)
|
||||||
.containerfile(opts.containerfile.as_ref())
|
.containerfile(opts.containerfile.as_ref())
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.squash(opts.squash)
|
.squash(opts.squash)
|
||||||
.maybe_cache_from(opts.cache_from)
|
.maybe_cache_from(opts.cache_from)
|
||||||
.maybe_cache_to(opts.cache_to)
|
.maybe_cache_to(opts.cache_to)
|
||||||
|
|
@ -286,7 +286,7 @@ pub trait RechunkDriver: RunDriver + BuildDriver + ContainerMountDriver {
|
||||||
&BuildOpts::builder()
|
&BuildOpts::builder()
|
||||||
.image(raw_image)
|
.image(raw_image)
|
||||||
.containerfile(&*opts.containerfile)
|
.containerfile(&*opts.containerfile)
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.privileged(true)
|
.privileged(true)
|
||||||
.squash(true)
|
.squash(true)
|
||||||
.host_network(true)
|
.host_network(true)
|
||||||
|
|
@ -562,7 +562,7 @@ pub trait SigningDriver: PrivateDriver {
|
||||||
let image_digest = Driver::get_metadata(
|
let image_digest = Driver::get_metadata(
|
||||||
&GetMetadataOpts::builder()
|
&GetMetadataOpts::builder()
|
||||||
.image(opts.image)
|
.image(opts.image)
|
||||||
.platform(opts.platform)
|
.maybe_platform(opts.platform)
|
||||||
.build(),
|
.build(),
|
||||||
)?
|
)?
|
||||||
.digest;
|
.digest;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ use blue_build_utils::{
|
||||||
constants::{GITHUB_ACTIONS, GITLAB_CI, IMAGE_VERSION_LABEL},
|
constants::{GITHUB_ACTIONS, GITLAB_CI, IMAGE_VERSION_LABEL},
|
||||||
get_env_var,
|
get_env_var,
|
||||||
semver::Version,
|
semver::Version,
|
||||||
|
string,
|
||||||
};
|
};
|
||||||
use clap::ValueEnum;
|
use clap::ValueEnum;
|
||||||
use log::{trace, warn};
|
use log::{trace, warn};
|
||||||
|
|
@ -20,6 +21,10 @@ use crate::drivers::{
|
||||||
podman_driver::PodmanDriver,
|
podman_driver::PodmanDriver,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod private {
|
||||||
|
pub trait Private {}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) trait DetermineDriver<T> {
|
pub(super) trait DetermineDriver<T> {
|
||||||
fn determine_driver(&mut self) -> T;
|
fn determine_driver(&mut self) -> T;
|
||||||
}
|
}
|
||||||
|
|
@ -178,30 +183,86 @@ impl DetermineDriver<CiDriverType> for Option<CiDriverType> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, ValueEnum, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq, Hash)]
|
||||||
pub enum Platform {
|
pub enum Platform {
|
||||||
#[default]
|
|
||||||
#[value(name = "native")]
|
|
||||||
Native,
|
|
||||||
#[value(name = "linux/amd64")]
|
#[value(name = "linux/amd64")]
|
||||||
LinuxAmd64,
|
LinuxAmd64,
|
||||||
|
|
||||||
|
#[value(name = "linux/amd64/v2")]
|
||||||
|
LinuxAmd64V2,
|
||||||
|
|
||||||
#[value(name = "linux/arm64")]
|
#[value(name = "linux/arm64")]
|
||||||
LinuxArm64,
|
LinuxArm64,
|
||||||
|
|
||||||
|
#[value(name = "linux/arm")]
|
||||||
|
LinuxArm,
|
||||||
|
|
||||||
|
#[value(name = "linux/arm/v6")]
|
||||||
|
LinuxArmV6,
|
||||||
|
|
||||||
|
#[value(name = "linux/arm/v7")]
|
||||||
|
LinuxArmV7,
|
||||||
|
|
||||||
|
#[value(name = "linux/386")]
|
||||||
|
Linux386,
|
||||||
|
|
||||||
|
#[value(name = "linux/loong64")]
|
||||||
|
LinuxLoong64,
|
||||||
|
|
||||||
|
#[value(name = "linux/mips")]
|
||||||
|
LinuxMips,
|
||||||
|
|
||||||
|
#[value(name = "linux/mipsle")]
|
||||||
|
LinuxMipsle,
|
||||||
|
|
||||||
|
#[value(name = "linux/mips64")]
|
||||||
|
LinuxMips64,
|
||||||
|
|
||||||
|
#[value(name = "linux/mips64le")]
|
||||||
|
LinuxMips64le,
|
||||||
|
|
||||||
|
#[value(name = "linux/ppc64")]
|
||||||
|
LinuxPpc64,
|
||||||
|
|
||||||
|
#[value(name = "linux/ppc64le")]
|
||||||
|
LinuxPpc64le,
|
||||||
|
|
||||||
|
#[value(name = "linux/riscv64")]
|
||||||
|
LinuxRiscv64,
|
||||||
|
|
||||||
|
#[value(name = "linux/s390x")]
|
||||||
|
LinuxS390x,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform {
|
impl Platform {
|
||||||
/// The architecture of the platform.
|
/// The architecture of the platform.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn arch(&self) -> &str {
|
pub const fn arch(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Self::Native => match std::env::consts::ARCH {
|
Self::LinuxAmd64 | Self::LinuxAmd64V2 => "amd64",
|
||||||
"x86_64" => "amd64",
|
|
||||||
"aarch64" => "arm64",
|
|
||||||
arch => unimplemented!("Arch {arch} is unsupported"),
|
|
||||||
},
|
|
||||||
Self::LinuxAmd64 => "amd64",
|
|
||||||
Self::LinuxArm64 => "arm64",
|
Self::LinuxArm64 => "arm64",
|
||||||
|
Self::LinuxArm | Self::LinuxArmV6 | Self::LinuxArmV7 => "arm",
|
||||||
|
Self::Linux386 => "386",
|
||||||
|
Self::LinuxLoong64 => "loong64",
|
||||||
|
Self::LinuxMips => "mips",
|
||||||
|
Self::LinuxMipsle => "mipsle",
|
||||||
|
Self::LinuxMips64 => "mips64",
|
||||||
|
Self::LinuxMips64le => "mips64le",
|
||||||
|
Self::LinuxPpc64 => "ppc64",
|
||||||
|
Self::LinuxPpc64le => "ppc64le",
|
||||||
|
Self::LinuxRiscv64 => "riscv64",
|
||||||
|
Self::LinuxS390x => "s390x",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The variant of the platform.
|
||||||
|
#[must_use]
|
||||||
|
pub const fn variant(&self) -> Option<&str> {
|
||||||
|
match *self {
|
||||||
|
Self::LinuxAmd64V2 => Some("v2"),
|
||||||
|
Self::LinuxArmV6 => Some("v6"),
|
||||||
|
Self::LinuxArmV7 => Some("v7"),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,18 +273,65 @@ impl std::fmt::Display for Platform {
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match *self {
|
||||||
Self::Native => match std::env::consts::ARCH {
|
|
||||||
"x86_64" => "linux/amd64",
|
|
||||||
"aarch64" => "linux/arm64",
|
|
||||||
arch => unimplemented!("Arch {arch} is unsupported"),
|
|
||||||
},
|
|
||||||
Self::LinuxAmd64 => "linux/amd64",
|
Self::LinuxAmd64 => "linux/amd64",
|
||||||
|
Self::LinuxAmd64V2 => "linux/amd64/v2",
|
||||||
Self::LinuxArm64 => "linux/arm64",
|
Self::LinuxArm64 => "linux/arm64",
|
||||||
|
Self::LinuxArm => "linux/arm",
|
||||||
|
Self::LinuxArmV6 => "linux/arm/v6",
|
||||||
|
Self::LinuxArmV7 => "linux/arm/v7",
|
||||||
|
Self::Linux386 => "linux/386",
|
||||||
|
Self::LinuxLoong64 => "linux/loong64",
|
||||||
|
Self::LinuxMips => "linux/mips",
|
||||||
|
Self::LinuxMipsle => "linux/mipsle",
|
||||||
|
Self::LinuxMips64 => "linux/mips64",
|
||||||
|
Self::LinuxMips64le => "linux/mips64le",
|
||||||
|
Self::LinuxPpc64 => "linux/ppc64",
|
||||||
|
Self::LinuxPpc64le => "linux/ppc64le",
|
||||||
|
Self::LinuxRiscv64 => "linux/riscv64",
|
||||||
|
Self::LinuxS390x => "linux/s390x",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl private::Private for Option<Platform> {}
|
||||||
|
|
||||||
|
pub trait PlatformInfo: private::Private {
|
||||||
|
/// The string representation of the platform.
|
||||||
|
///
|
||||||
|
/// If `None`, then the native architecture will be used.
|
||||||
|
fn to_string(&self) -> String;
|
||||||
|
|
||||||
|
/// The string representation of the architecture.
|
||||||
|
///
|
||||||
|
/// If `None`, then the native architecture will be used.
|
||||||
|
fn arch(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PlatformInfo for Option<Platform> {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.map_or_else(
|
||||||
|
|| match std::env::consts::ARCH {
|
||||||
|
"x86_64" => string!("linux/amd64"),
|
||||||
|
"aarch64" => string!("linux/arm64"),
|
||||||
|
arch => unimplemented!("Arch {arch} is unsupported"),
|
||||||
|
},
|
||||||
|
|platform| format!("{platform}"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn arch(&self) -> &str {
|
||||||
|
self.as_ref().map_or_else(
|
||||||
|
|| match std::env::consts::ARCH {
|
||||||
|
"x86_64" => "amd64",
|
||||||
|
"aarch64" => "arm64",
|
||||||
|
arch => unimplemented!("Arch {arch} is unsupported"),
|
||||||
|
},
|
||||||
|
Platform::arch,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
#[serde(rename_all = "PascalCase")]
|
#[serde(rename_all = "PascalCase")]
|
||||||
pub struct ImageMetadata {
|
pub struct ImageMetadata {
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,8 @@ pub struct BuildCommand {
|
||||||
/// than your hardware will require installing
|
/// than your hardware will require installing
|
||||||
/// qemu. Build times will be much greater when
|
/// qemu. Build times will be much greater when
|
||||||
/// building for a non-native architecture.
|
/// building for a non-native architecture.
|
||||||
#[arg(long, default_value = "native")]
|
#[arg(long)]
|
||||||
#[builder(default)]
|
platform: Option<Platform>,
|
||||||
platform: Platform,
|
|
||||||
|
|
||||||
/// The compression format the images
|
/// The compression format the images
|
||||||
/// will be pushed in.
|
/// will be pushed in.
|
||||||
|
|
@ -198,7 +197,7 @@ impl BlueBuildCommand for BuildCommand {
|
||||||
PathBuf::from(CONTAINER_FILE)
|
PathBuf::from(CONTAINER_FILE)
|
||||||
}))
|
}))
|
||||||
.skip_validation(self.skip_validation)
|
.skip_validation(self.skip_validation)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.recipe(recipe)
|
.recipe(recipe)
|
||||||
.drivers(self.drivers)
|
.drivers(self.drivers)
|
||||||
.build()
|
.build()
|
||||||
|
|
@ -249,7 +248,7 @@ impl BuildCommand {
|
||||||
&GenerateTagsOpts::builder()
|
&GenerateTagsOpts::builder()
|
||||||
.oci_ref(&recipe.base_image_ref()?)
|
.oci_ref(&recipe.base_image_ref()?)
|
||||||
.maybe_alt_tags(recipe.alt_tags.as_ref().map(CowCollecter::collect_cow_vec))
|
.maybe_alt_tags(recipe.alt_tags.as_ref().map(CowCollecter::collect_cow_vec))
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.build(),
|
.build(),
|
||||||
)?;
|
)?;
|
||||||
let image_name = self.image_name(&recipe)?;
|
let image_name = self.image_name(&recipe)?;
|
||||||
|
|
@ -283,7 +282,7 @@ impl BuildCommand {
|
||||||
BuildTagPushOpts::builder()
|
BuildTagPushOpts::builder()
|
||||||
.image(&image)
|
.image(&image)
|
||||||
.containerfile(containerfile)
|
.containerfile(containerfile)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.tags(tags.collect_cow_vec())
|
.tags(tags.collect_cow_vec())
|
||||||
.push(self.push)
|
.push(self.push)
|
||||||
.retry_push(self.retry_push)
|
.retry_push(self.retry_push)
|
||||||
|
|
@ -298,7 +297,7 @@ impl BuildCommand {
|
||||||
|archive_dir| {
|
|archive_dir| {
|
||||||
BuildTagPushOpts::builder()
|
BuildTagPushOpts::builder()
|
||||||
.containerfile(containerfile)
|
.containerfile(containerfile)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.image(PathBuf::from(format!(
|
.image(PathBuf::from(format!(
|
||||||
"{}/{}.{ARCHIVE_SUFFIX}",
|
"{}/{}.{ARCHIVE_SUFFIX}",
|
||||||
archive_dir.to_string_lossy().trim_end_matches('/'),
|
archive_dir.to_string_lossy().trim_end_matches('/'),
|
||||||
|
|
@ -319,7 +318,7 @@ impl BuildCommand {
|
||||||
.image(&image)
|
.image(&image)
|
||||||
.retry_push(self.retry_push)
|
.retry_push(self.retry_push)
|
||||||
.retry_count(self.retry_count)
|
.retry_count(self.retry_count)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.build(),
|
.build(),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
@ -346,14 +345,14 @@ impl BuildCommand {
|
||||||
&RechunkOpts::builder()
|
&RechunkOpts::builder()
|
||||||
.image(image_name)
|
.image(image_name)
|
||||||
.containerfile(containerfile)
|
.containerfile(containerfile)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.tags(tags.collect_cow_vec())
|
.tags(tags.collect_cow_vec())
|
||||||
.push(self.push)
|
.push(self.push)
|
||||||
.version(format!(
|
.version(format!(
|
||||||
"{version}.<date>",
|
"{version}.<date>",
|
||||||
version = Driver::get_os_version()
|
version = Driver::get_os_version()
|
||||||
.oci_ref(&recipe.base_image_ref()?)
|
.oci_ref(&recipe.base_image_ref()?)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.call()?,
|
.call()?,
|
||||||
))
|
))
|
||||||
.retry_push(self.retry_push)
|
.retry_push(self.retry_push)
|
||||||
|
|
@ -363,7 +362,7 @@ impl BuildCommand {
|
||||||
Driver::get_metadata(
|
Driver::get_metadata(
|
||||||
&GetMetadataOpts::builder()
|
&GetMetadataOpts::builder()
|
||||||
.image(&base_image)
|
.image(&base_image)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.build(),
|
.build(),
|
||||||
)?
|
)?
|
||||||
.digest,
|
.digest,
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,7 @@ pub struct GenerateCommand {
|
||||||
/// Inspect the image for a specific platform
|
/// Inspect the image for a specific platform
|
||||||
/// when retrieving the version.
|
/// when retrieving the version.
|
||||||
#[arg(long, default_value = "native")]
|
#[arg(long, default_value = "native")]
|
||||||
#[builder(default)]
|
platform: Option<Platform>,
|
||||||
platform: Platform,
|
|
||||||
|
|
||||||
/// Skips validation of the recipe file.
|
/// Skips validation of the recipe file.
|
||||||
#[arg(long, env = BB_SKIP_VALIDATION)]
|
#[arg(long, env = BB_SKIP_VALIDATION)]
|
||||||
|
|
@ -148,7 +147,7 @@ impl GenerateCommand {
|
||||||
.os_version(
|
.os_version(
|
||||||
Driver::get_os_version()
|
Driver::get_os_version()
|
||||||
.oci_ref(&recipe.base_image_ref()?)
|
.oci_ref(&recipe.base_image_ref()?)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.call()?,
|
.call()?,
|
||||||
)
|
)
|
||||||
.build_id(Driver::get_build_id())
|
.build_id(Driver::get_build_id())
|
||||||
|
|
@ -161,7 +160,7 @@ impl GenerateCommand {
|
||||||
Driver::get_metadata(
|
Driver::get_metadata(
|
||||||
&GetMetadataOpts::builder()
|
&GetMetadataOpts::builder()
|
||||||
.image(&base_image)
|
.image(&base_image)
|
||||||
.platform(self.platform)
|
.maybe_platform(self.platform)
|
||||||
.build(),
|
.build(),
|
||||||
)?
|
)?
|
||||||
.digest,
|
.digest,
|
||||||
|
|
@ -186,14 +185,14 @@ impl GenerateCommand {
|
||||||
|
|
||||||
#[cached(
|
#[cached(
|
||||||
result = true,
|
result = true,
|
||||||
key = "Platform",
|
key = "Option<Platform>",
|
||||||
convert = r#"{ platform }"#,
|
convert = r#"{ platform }"#,
|
||||||
sync_writes = "by_key"
|
sync_writes = "by_key"
|
||||||
)]
|
)]
|
||||||
fn determine_scripts_tag(platform: Platform) -> Result<Reference> {
|
fn determine_scripts_tag(platform: Option<Platform>) -> Result<Reference> {
|
||||||
trace!("determine_scripts_tag({platform:?})");
|
trace!("determine_scripts_tag({platform:?})");
|
||||||
|
|
||||||
let opts = GetMetadataOpts::builder().platform(platform);
|
let opts = GetMetadataOpts::builder().maybe_platform(platform);
|
||||||
format!("{BUILD_SCRIPTS_IMAGE_REF}:{}", shadow::COMMIT_HASH)
|
format!("{BUILD_SCRIPTS_IMAGE_REF}:{}", shadow::COMMIT_HASH)
|
||||||
.parse()
|
.parse()
|
||||||
.into_diagnostic()
|
.into_diagnostic()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue