Skip to content

Commit

Permalink
fix: Add logic for inspecting multi-manifest images
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Nov 27, 2024
1 parent 816a6a5 commit 2b7305c
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 39 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ jobs:
steps:
- uses: earthly/actions-setup@v1

- name: Earthly login
env:
EARTHLY_SAT_TOKEN: ${{ secrets.EARTHLY_SAT_TOKEN }}
if: env.EARTHLY_SAT_TOKEN != null
run: |
earthly account login --token ${{ secrets.EARTHLY_SAT_TOKEN }} >> /dev/null
earthly org s blue-build
earthly sat s pr
- uses: actions/checkout@v4
with:
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ jobs:
run: |
earthly account login --token ${{ secrets.EARTHLY_SAT_TOKEN }} >> /dev/null
earthly org s blue-build
earthly sat s pr
earthly sat s main
- uses: actions/checkout@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ validate:
FROM +test-base

RUN --no-cache bluebuild -v validate recipes/recipe.yml
RUN --no-cache bluebuild -v validate recipes/recipe-39.yml
RUN --no-cache bluebuild -v validate recipes/recipe-gts.yml
RUN --no-cache bluebuild -v validate recipes/recipe-arm64.yml
RUN --no-cache bluebuild -v validate recipes/recipe-invalid.yml && exit 1 || exit 0
RUN --no-cache bluebuild -v validate recipes/recipe-invalid-module.yml && exit 1 || exit 0
Expand Down
38 changes: 4 additions & 34 deletions process/drivers/docker_driver.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
collections::HashMap,
env,
io::Write,
path::Path,
Expand All @@ -21,6 +20,8 @@ use semver::Version;
use serde::Deserialize;
use tempfile::TempDir;

mod metadata;

use crate::{
drivers::{
opts::{
Expand All @@ -35,37 +36,6 @@ use crate::{
signal_handler::{add_cid, remove_cid, ContainerId, ContainerRuntime},
};

#[derive(Deserialize, Debug, Clone)]
struct DockerImageMetadata {
manifest: DockerImageMetadataManifest,
image: DockerImageMetadataImage,
}

#[derive(Deserialize, Debug, Clone)]
struct DockerImageMetadataManifest {
digest: String,
}

#[derive(Deserialize, Debug, Clone)]
struct DockerImageMetadataImage {
config: DockerImageConfig,
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
struct DockerImageConfig {
labels: HashMap<String, serde_json::Value>,
}

impl From<DockerImageMetadata> for ImageMetadata {
fn from(value: DockerImageMetadata) -> Self {
Self {
labels: value.image.config.labels,
digest: value.manifest.digest,
}
}
}

#[derive(Debug, Deserialize)]
struct DockerVerisonJsonClient {
#[serde(alias = "Version")]
Expand Down Expand Up @@ -396,10 +366,10 @@ fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
bail!("Failed to inspect image {url}")
}

serde_json::from_slice::<DockerImageMetadata>(&output.stdout)
serde_json::from_slice::<metadata::Metadata>(&output.stdout)
.into_diagnostic()
.inspect(|metadata| trace!("{metadata:#?}"))
.map(ImageMetadata::from)
.and_then(|metadata| ImageMetadata::try_from((metadata, opts.platform)))
.inspect(|metadata| trace!("{metadata:#?}"))
}

Expand Down
79 changes: 79 additions & 0 deletions process/drivers/docker_driver/metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use std::collections::HashMap;

use miette::{bail, Report};
use serde::Deserialize;

use crate::drivers::types::{ImageMetadata, Platform};

#[derive(Deserialize, Debug, Clone)]
pub struct Metadata {
manifest: Manifest,
image: MetadataImage,
}

#[derive(Deserialize, Debug, Clone)]
pub struct PlatformManifest {
digest: String,
platform: PlatformManifestInfo,
}

#[derive(Deserialize, Debug, Clone)]
pub struct PlatformManifestInfo {
architecture: String,
}

#[derive(Deserialize, Debug, Clone)]
pub struct Manifest {
digest: String,

#[serde(default)]
manifests: Vec<PlatformManifest>,
}

#[derive(Deserialize, Debug, Clone)]
pub struct MetadataPlatformImage {
config: Config,
}

#[derive(Deserialize, Debug, Clone)]
#[serde(untagged)]
pub enum MetadataImage {
Single(MetadataPlatformImage),
Multi(HashMap<String, MetadataPlatformImage>),
}

#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct Config {
labels: HashMap<String, serde_json::Value>,
}

impl TryFrom<(Metadata, Platform)> for ImageMetadata {
type Error = Report;

fn try_from((metadata, platform): (Metadata, Platform)) -> Result<Self, Self::Error> {
match metadata.image {
MetadataImage::Single(image) => Ok(Self {
labels: image.config.labels,
digest: metadata.manifest.digest,
}),
MetadataImage::Multi(mut platforms) => {
let Some(image) = platforms.remove(&platform.to_string()) else {
bail!("Image information does not exist for {platform}");
};
let Some(manifest) = metadata
.manifest
.manifests
.into_iter()
.find(|manifest| manifest.platform.architecture == platform.arch())
else {
bail!("Manifest does not exist for {platform}");
};
Ok(Self {
labels: image.config.labels,
digest: manifest.digest,
})
}
}
}
}
14 changes: 11 additions & 3 deletions process/drivers/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,13 @@ pub enum Platform {
impl Platform {
/// The architecture of the platform.
#[must_use]
pub const fn arch(&self) -> &str {
pub fn arch(&self) -> &str {
match *self {
Self::Native => "native",
Self::Native => match std::env::consts::ARCH {
"x86_64" => "amd64",
"aarch64" => "arm64",
arch => unimplemented!("Arch {arch} is unsupported"),
},
Self::LinuxAmd64 => "amd64",
Self::LinuxArm64 => "arm64",
}
Expand All @@ -200,7 +204,11 @@ impl std::fmt::Display for Platform {
f,
"{}",
match *self {
Self::Native => "native",
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::LinuxArm64 => "linux/arm64",
}
Expand Down

0 comments on commit 2b7305c

Please sign in to comment.