Skip to content

Commit

Permalink
feat: Include base image information in labels
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Nov 14, 2024
1 parent 3674f83 commit e3b246e
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 185 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

137 changes: 68 additions & 69 deletions process/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use clap::Args;
use colored::Colorize;
use indicatif::{ProgressBar, ProgressStyle};
use log::{info, trace, warn};
use miette::{miette, IntoDiagnostic, Report, Result};
use miette::{miette, IntoDiagnostic, Result};
use oci_distribution::Reference;
use once_cell::sync::Lazy;
use opts::{GenerateImageNameOpts, GenerateTagsOpts};
Expand Down Expand Up @@ -202,6 +202,8 @@ impl Driver {
#[builder(default)]
platform: Platform,
) -> Result<u64> {
trace!("Driver::get_os_version({oci_ref:#?})");

#[cfg(test)]
{
let _ = oci_ref; // silence lint
Expand All @@ -211,8 +213,33 @@ impl Driver {
}
}

trace!("Driver::get_os_version({oci_ref:#?})");
get_version(oci_ref, platform)
info!("Retrieving OS version from {oci_ref}");

let inspect_opts = GetMetadataOpts::builder()
.image(format!(
"{}/{}",
oci_ref.resolve_registry(),
oci_ref.repository()
))
.tag(oci_ref.tag().unwrap_or("latest"))
.platform(platform)
.build();

let os_version = Self::get_metadata(&inspect_opts)
.and_then(|inspection| {
inspection.get_version().ok_or_else(|| {
miette!(
"Failed to parse version from metadata for {}",
oci_ref.to_string().bold()
)
})
})
.or_else(|err| {
warn!("Unable to get version via image inspection due to error:\n{err:?}");
get_version_run_image(oci_ref)
})?;
trace!("os_version: {os_version}");
Ok(os_version)
}

fn get_build_driver() -> BuildDriverType {
Expand All @@ -239,74 +266,46 @@ impl Driver {
#[cached(
result = true,
key = "String",
convert = r#"{ format!("{oci_ref}-{platform}") }"#,
convert = r#"{ oci_ref.to_string() }"#,
sync_writes = true
)]
fn get_version(oci_ref: &Reference, platform: Platform) -> Result<u64> {
info!("Retrieving OS version from {oci_ref}. This might take a bit");
let inspect_opts = GetMetadataOpts::builder()
.image(format!(
"{}/{}",
oci_ref.resolve_registry(),
oci_ref.repository()
))
.tag(oci_ref.tag().unwrap_or("latest"))
.platform(platform)
.build();
let os_version = Driver::get_metadata(&inspect_opts)
.and_then(|inspection| {
inspection.get_version().ok_or_else(|| {
miette!(
"Failed to parse version from metadata for {}",
oci_ref.to_string().bold()
)
})
})
.or_else(get_version_run_image(oci_ref))?;
trace!("os_version: {os_version}");
Ok(os_version)
}

fn get_version_run_image(oci_ref: &Reference) -> impl FnOnce(Report) -> Result<u64> + '_ {
|err: Report| -> Result<u64> {
warn!("Unable to get version via image inspection due to error:\n{err:?}");
warn!(concat!(
"Pulling and running the image to retrieve the version. ",
"This will take a while..."
));

let progress = Logger::multi_progress().add(
ProgressBar::new_spinner()
.with_style(ProgressStyle::default_spinner())
.with_message(format!(
"Pulling image {} to get version",
oci_ref.to_string().bold()
)),
);
progress.enable_steady_tick(Duration::from_millis(100));

let output = Driver::run_output(
&RunOpts::builder()
.image(oci_ref.to_string())
.args(bon::vec![
"/bin/bash",
"-c",
"grep -Po '(?<=VERSION_ID=)\\d+' /usr/lib/os-release",
])
.pull(true)
.remove(true)
.build(),
)
.into_diagnostic()?;

progress.finish_and_clear();
Logger::multi_progress().remove(&progress);

String::from_utf8_lossy(&output.stdout)
.trim()
.parse()
.into_diagnostic()
}
fn get_version_run_image(oci_ref: &Reference) -> Result<u64> {
warn!(concat!(
"Pulling and running the image to retrieve the version. ",
"This will take a while..."
));

let progress = Logger::multi_progress().add(
ProgressBar::new_spinner()
.with_style(ProgressStyle::default_spinner())
.with_message(format!(
"Pulling image {} to get version",
oci_ref.to_string().bold()
)),
);
progress.enable_steady_tick(Duration::from_millis(100));

let output = Driver::run_output(
&RunOpts::builder()
.image(oci_ref.to_string())
.args(bon::vec![
"/bin/bash",
"-c",
"grep -Po '(?<=VERSION_ID=)\\d+' /usr/lib/os-release",
])
.pull(true)
.remove(true)
.build(),
)
.into_diagnostic()?;

progress.finish_and_clear();
Logger::multi_progress().remove(&progress);

String::from_utf8_lossy(&output.stdout)
.trim()
.parse()
.into_diagnostic()
}

macro_rules! impl_build_driver {
Expand Down
77 changes: 44 additions & 33 deletions process/drivers/docker_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use blue_build_utils::{
credentials::Credentials,
string_vec,
};
use cached::proc_macro::cached;
use log::{debug, info, trace, warn};
use miette::{bail, IntoDiagnostic, Result};
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -346,44 +347,54 @@ impl BuildDriver for DockerDriver {

impl InspectDriver for DockerDriver {
fn get_metadata(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
trace!("DockerDriver::get_metadata({opts:#?})");

let url = opts.tag.as_ref().map_or_else(
|| format!("{}", opts.image),
|tag| format!("{}:{tag}", opts.image),
);
get_metadata_cache(opts)
}
}

let mut command = cmd!(
"docker",
"buildx",
|command|? {
if !env::var(DOCKER_HOST).is_ok_and(|dh| !dh.is_empty()) {
Self::setup()?;
cmd!(command, "--builder=bluebuild");
}
},
"imagetools",
"inspect",
"--format",
"{{json .}}",
&url
);
trace!("{command:?}");
#[cached(
result = true,
key = "String",
convert = r#"{ format!("{}-{:?}-{}", &*opts.image, opts.tag.as_ref(), opts.platform)}"#,
sync_writes = true
)]
fn get_metadata_cache(opts: &GetMetadataOpts) -> Result<ImageMetadata> {
trace!("DockerDriver::get_metadata({opts:#?})");

let url = opts.tag.as_ref().map_or_else(
|| format!("{}", opts.image),
|tag| format!("{}:{tag}", opts.image),
);

let output = command.output().into_diagnostic()?;
let mut command = cmd!(
"docker",
"buildx",
|command|? {
if !env::var(DOCKER_HOST).is_ok_and(|dh| !dh.is_empty()) {
DockerDriver::setup()?;
cmd!(command, "--builder=bluebuild");
}
},
"imagetools",
"inspect",
"--format",
"{{json .}}",
&url
);
trace!("{command:?}");

if output.status.success() {
info!("Successfully inspected image {url}!");
} else {
bail!("Failed to inspect image {url}")
}
let output = command.output().into_diagnostic()?;

serde_json::from_slice::<DockerImageMetadata>(&output.stdout)
.into_diagnostic()
.inspect(|metadata| trace!("{metadata:#?}"))
.map(ImageMetadata::from)
.inspect(|metadata| trace!("{metadata:#?}"))
if output.status.success() {
info!("Successfully inspected image {url}!");
} else {
bail!("Failed to inspect image {url}")
}

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

impl RunDriver for DockerDriver {
Expand Down
2 changes: 1 addition & 1 deletion process/drivers/opts/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bon::Builder;

use crate::drivers::types::Platform;

#[derive(Debug, Clone, Builder)]
#[derive(Debug, Clone, Builder, Hash)]
#[builder(derive(Clone))]
pub struct GetMetadataOpts<'scope> {
#[builder(into)]
Expand Down
Loading

0 comments on commit e3b246e

Please sign in to comment.