fix: Run image as fallback for version retrieval
This commit is contained in:
parent
37a69df832
commit
20d1950530
6 changed files with 91 additions and 52 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -351,6 +351,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"blue-build-utils",
|
||||
"bon",
|
||||
"cached",
|
||||
"chrono",
|
||||
"clap",
|
||||
"colored",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6,17 +6,19 @@
|
|||
|
||||
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};
|
||||
|
|
@ -24,6 +26,8 @@ use opts::{GenerateImageNameOpts, GenerateTagsOpts};
|
|||
use sigstore_driver::SigstoreDriver;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::logging::Logger;
|
||||
|
||||
use self::{
|
||||
buildah_driver::BuildahDriver,
|
||||
cosign_driver::CosignDriver,
|
||||
|
|
@ -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
|
||||
|
|
@ -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 {
|
||||
|
|
@ -264,6 +227,78 @@ 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 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()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_build_driver {
|
||||
($func:ident($($args:expr),*)) => {
|
||||
match Self::get_build_driver() {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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));
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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));
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue