Skip to content

Commit

Permalink
fix: Run image as fallback for version retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpinder committed Sep 29, 2024
1 parent 37a69df commit c1071c8
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 52 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.

1 change: 1 addition & 0 deletions process/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ tempdir.workspace = true
bon.workspace = true
users.workspace = true
uuid.workspace = true
cached = "0.53.1"

[dev-dependencies]
rstest.workspace = true
Expand Down
122 changes: 76 additions & 46 deletions process/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,28 @@
use std::{
borrow::Borrow,
collections::{hash_map::Entry, HashMap},
fmt::Debug,
process::{ExitStatus, Output},
sync::{Mutex, RwLock},
time::Duration,
};

use blue_build_utils::constants::IMAGE_VERSION_LABEL;
use bon::Builder;
use cached::proc_macro::cached;
use clap::Args;
use log::{debug, info, trace};
use miette::{miette, Result};
use colored::Colorize;
use indicatif::{ProgressBar, ProgressStyle};
use log::{info, trace, warn};
use miette::{miette, IntoDiagnostic, Report, Result};
use oci_distribution::Reference;
use once_cell::sync::Lazy;
use opts::{GenerateImageNameOpts, GenerateTagsOpts};
#[cfg(feature = "sigstore")]
use sigstore_driver::SigstoreDriver;
use uuid::Uuid;

use crate::logging::Logger;

use self::{
buildah_driver::BuildahDriver,
cosign_driver::CosignDriver,
Expand Down Expand Up @@ -75,9 +79,6 @@ static SELECTED_CI_DRIVER: Lazy<RwLock<Option<CiDriverType>>> = Lazy::new(|| RwL
/// UUID used to mark the current builds
static BUILD_ID: Lazy<Uuid> = Lazy::new(Uuid::new_v4);

/// The cached os versions
static OS_VERSION: Lazy<Mutex<HashMap<String, u64>>> = Lazy::new(|| Mutex::new(HashMap::new()));

/// Args for selecting the various drivers to use for runtime.
///
/// If the args are left uninitialized, the program will determine
Expand Down Expand Up @@ -202,45 +203,7 @@ impl Driver {
}

trace!("Driver::get_os_version({oci_ref:#?})");
let mut os_version_lock = OS_VERSION.lock().expect("Should lock");

let entry = os_version_lock.get(&oci_ref.to_string());

let os_version = match entry {
None => {
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"))
.build();
let inspection = Self::get_metadata(&inspect_opts)?;

let os_version = inspection.get_version().ok_or_else(|| {
miette!(
help = format!("Please check with the image author about using '{IMAGE_VERSION_LABEL}' to report the os version."),
"Unable to get the OS version from the labels"
)
})?;
trace!("os_version: {os_version}");

os_version
}
Some(os_version) => {
debug!("Found cached {os_version} for {oci_ref}");
*os_version
}
};

if let Entry::Vacant(entry) = os_version_lock.entry(oci_ref.to_string()) {
trace!("Caching version {os_version} for {oci_ref}");
entry.insert(os_version);
}
drop(os_version_lock);
Ok(os_version)
get_version(oci_ref)
}

fn get_build_driver() -> BuildDriverType {
Expand All @@ -264,6 +227,73 @@ impl Driver {
}
}

#[cached(
result = true,
key = "String",
convert = "{ oci_ref.to_string() }",
sync_writes = true
)]
fn get_version(oci_ref: &Reference) -> 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"))
.build();
let inspection = Driver::get_metadata(&inspect_opts)?;
let os_version = inspection
.get_version()
.ok_or_else(|| miette!("Inspect failed"))
.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 {err:?}");
warn!(concat!(
"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 {
($func:ident($($args:expr),*)) => {
match Self::get_build_driver() {
Expand Down
5 changes: 3 additions & 2 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 colored::Colorize;
use indicatif::{ProgressBar, ProgressStyle};
use log::{debug, info, trace, warn};
use miette::{bail, IntoDiagnostic, Result};
Expand Down Expand Up @@ -317,7 +318,7 @@ impl InspectDriver for DockerDriver {
let progress = Logger::multi_progress().add(
ProgressBar::new_spinner()
.with_style(ProgressStyle::default_spinner())
.with_message(format!("Inspecting metadata for {url}")),
.with_message(format!("Inspecting metadata for {}", url.bold())),
);
progress.enable_steady_tick(Duration::from_millis(100));

Expand All @@ -330,7 +331,7 @@ impl InspectDriver for DockerDriver {
)
.into_diagnostic()?;

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

if output.status.success() {
Expand Down
4 changes: 2 additions & 2 deletions process/drivers/podman_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ impl InspectDriver for PodmanDriver {
let progress = Logger::multi_progress().add(
ProgressBar::new_spinner()
.with_style(ProgressStyle::default_spinner())
.with_message(format!("Inspecting metadata for {url}")),
.with_message(format!("Inspecting metadata for {}", url.bold())),
);
progress.enable_steady_tick(Duration::from_millis(100));

Expand All @@ -207,7 +207,7 @@ impl InspectDriver for PodmanDriver {
)
.into_diagnostic()?;

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

if output.status.success() {
Expand Down
5 changes: 3 additions & 2 deletions process/drivers/skopeo_driver.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{process::Stdio, time::Duration};

use blue_build_utils::cmd;
use colored::Colorize;
use indicatif::{ProgressBar, ProgressStyle};
use log::{debug, trace};
use miette::{bail, IntoDiagnostic, Result};
Expand All @@ -24,7 +25,7 @@ impl InspectDriver for SkopeoDriver {
let progress = Logger::multi_progress().add(
ProgressBar::new_spinner()
.with_style(ProgressStyle::default_spinner())
.with_message(format!("Inspecting metadata for {url}")),
.with_message(format!("Inspecting metadata for {}", url.bold())),
);
progress.enable_steady_tick(Duration::from_millis(100));

Expand All @@ -34,7 +35,7 @@ impl InspectDriver for SkopeoDriver {
.output()
.into_diagnostic()?;

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

if output.status.success() {
Expand Down

0 comments on commit c1071c8

Please sign in to comment.