From 178acfb2f64ff2f8d51ba8c82530f4068004e18d Mon Sep 17 00:00:00 2001 From: Sergio <77530549+sergi0g@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:13:53 +0200 Subject: [PATCH] Add debug option to CLI --- src/check.rs | 9 +++++++++ src/config.rs | 3 +++ src/main.rs | 7 +++++-- src/registry.rs | 34 +++++++++++++++++++++++++++++----- src/utils/logging.rs | 12 +++++++----- src/utils/reference.rs | 2 +- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/check.rs b/src/check.rs index d60beae..425ebfd 100644 --- a/src/check.rs +++ b/src/check.rs @@ -4,6 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use crate::{ config::Config, + debug, docker::get_images_from_docker_daemon, http::Client, registry::{check_auth, get_token}, @@ -13,6 +14,7 @@ use crate::{ /// Returns a list of updates for all images passed in. pub async fn get_updates(references: &Option>, config: &Config) -> Vec { // Get images + debug!(config.debug, "Retrieving images to be checked"); let mut images = get_images_from_docker_daemon(config, references).await; let extra_images = match references { Some(refs) => { @@ -35,6 +37,11 @@ pub async fn get_updates(references: &Option>, config: &Config) -> V if let Some(extra_imgs) = extra_images { images.extend_from_slice(&extra_imgs); } + debug!( + config.debug, + "Checking {:?}", + images.iter().map(|image| &image.reference).collect_vec() + ); // Get a list of unique registries our images belong to. We are unwrapping the registry because it's guaranteed to be there. let registries: Vec<&String> = images @@ -75,6 +82,8 @@ pub async fn get_updates(references: &Option>, config: &Config) -> V } } + debug!(config.debug, "Tokens: {:?}", tokens); + // Create a Vec to store futures so we can await them all at once. let mut handles = Vec::with_capacity(images.len()); // Loop through images and get the latest digest for each diff --git a/src/config.rs b/src/config.rs index 8bbb5d0..2717553 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,6 +18,7 @@ pub struct Config { pub theme: Theme, pub insecure_registries: Vec, pub socket: Option, + pub debug: bool, } impl Config { @@ -29,6 +30,7 @@ impl Config { theme: Theme::Default, insecure_registries: Vec::with_capacity(0), socket: None, + debug: false, } } /// Reads the config from the file path provided and returns the parsed result. @@ -125,6 +127,7 @@ impl Config { theme, insecure_registries, socket, + debug: false, } } } diff --git a/src/main.rs b/src/main.rs index 019ff17..e60bb64 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,13 +30,15 @@ struct Cli { config_path: String, #[command(subcommand)] command: Option, + #[arg(short, long)] + debug: bool, } #[derive(Subcommand)] enum Commands { #[cfg(feature = "cli")] Check { - #[arg(name = "Images", default_value = None)] + #[arg(name = "images", default_value = None)] references: Option>, #[arg(short, long, default_value_t = false, help = "Enable icons")] icons: bool, @@ -71,6 +73,7 @@ async fn main() { if let Some(socket) = cli.socket { config.socket = Some(socket) } + config.debug = cli.debug; match &cli.command { #[cfg(feature = "cli")] Some(Commands::Check { @@ -79,7 +82,7 @@ async fn main() { raw, }) => { let start = timestamp(); - match raw { + match *raw || config.debug { true => { let updates = get_updates(references, &config).await; print_raw_updates(&updates); diff --git a/src/registry.rs b/src/registry.rs index b2e85e1..dd87b4d 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use crate::{ config::Config, - error, + debug, error, http::Client, structs::{ image::{DigestInfo, Image, VersionInfo}, @@ -46,6 +46,10 @@ pub async fn get_latest_digest( config: &Config, client: &Client, ) -> Image { + debug!( + config.debug, + "Checking for digest update to {}", image.reference + ); let start = timestamp(); let protocol = get_protocol(&image.registry, &config.insecure_registries); let url = format!( @@ -56,6 +60,11 @@ pub async fn get_latest_digest( let headers = vec![("Accept", Some("application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.docker.distribution.manifest.v2+json, application/vnd.oci.image.index.v1+json")), ("Authorization", authorization.as_deref())]; let response = client.head(&url, headers).await; + let time = timestamp() - start; + debug!( + config.debug, + "Checked for digest update to {} in {}ms", image.reference, time + ); match response { Ok(res) => match res.headers().get("docker-content-digest") { Some(digest) => { @@ -68,7 +77,7 @@ pub async fn get_latest_digest( remote_digest: Some(digest.to_str().unwrap().to_string()), local_digests, }), - time_ms: image.time_ms + (timestamp() - start), + time_ms: image.time_ms + time, ..image.clone() } } @@ -79,7 +88,7 @@ pub async fn get_latest_digest( }, Err(error) => Image { error: Some(error), - time_ms: image.time_ms + (timestamp() - start), + time_ms: image.time_ms + time, ..image.clone() }, } @@ -113,6 +122,10 @@ pub async fn get_latest_tag( config: &Config, client: &Client, ) -> Image { + debug!( + config.debug, + "Checking for tag update to {}", image.reference + ); let start = timestamp(); let protocol = get_protocol(&image.registry, &config.insecure_registries); let url = format!( @@ -129,6 +142,12 @@ pub async fn get_latest_tag( let mut next_url = Some(url); while next_url.is_some() { + debug!( + config.debug, + "{} has extra tags! Current number of valid tags: {}", + image.reference, + tags.len() + ); let (new_tags, next) = match get_extra_tags(&next_url.unwrap(), headers.clone(), base, client).await { Ok(t) => t, @@ -148,6 +167,11 @@ pub async fn get_latest_tag( Some(data) => data.current_tag.clone(), _ => unreachable!(), }; + let time = timestamp() - start; + debug!( + config.debug, + "Checked for tag update to {} in {}ms", image.reference, time + ); match tag { Some(t) => { if t == base && image.digest_info.is_some() { @@ -158,7 +182,7 @@ pub async fn get_latest_tag( current_tag, latest_remote_tag: Some(t.clone()), }), - time_ms: image.time_ms + (timestamp() - start), + time_ms: image.time_ms + time, ..image.clone() }, token, @@ -172,7 +196,7 @@ pub async fn get_latest_tag( current_tag, latest_remote_tag: Some(t.clone()), }), - time_ms: image.time_ms + (timestamp() - start), + time_ms: image.time_ms + time, ..image.clone() } } diff --git a/src/utils/logging.rs b/src/utils/logging.rs index 8b03550..80463bc 100644 --- a/src/utils/logging.rs +++ b/src/utils/logging.rs @@ -4,7 +4,7 @@ #[macro_export] macro_rules! error { ($($arg:tt)*) => ({ - eprintln!("\x1b[38:5:204mERROR \x1b[0m {}", format!($($arg)*)); + eprintln!("\x1b[31;1mERROR \x1b[0m {}", format!($($arg)*)); std::process::exit(1); }) } @@ -13,20 +13,22 @@ macro_rules! error { #[macro_export] macro_rules! warn { ($($arg:tt)*) => ({ - eprintln!("\x1b[38:5:192mWARN \x1b[0m {}", format!($($arg)*)); + eprintln!("\x1b[33;1mWARN \x1b[0m {}", format!($($arg)*)); }) } #[macro_export] macro_rules! info { ($($arg:tt)*) => ({ - println!("\x1b[38:5:86mINFO \x1b[0m {}", format!($($arg)*)); + println!("\x1b[36;1mINFO \x1b[0m {}", format!($($arg)*)); }) } #[macro_export] macro_rules! debug { - ($($arg:tt)*) => ({ - println!("\x1b[38:5:63mDEBUG \x1b[0m {}", format!($($arg)*)); + ($debg:expr, $($arg:tt)*) => ({ + if $debg { + println!("\x1b[35;1mDEBUG \x1b[0m {}", format!($($arg)*)); + } }) } diff --git a/src/utils/reference.rs b/src/utils/reference.rs index 435f949..346ccab 100644 --- a/src/utils/reference.rs +++ b/src/utils/reference.rs @@ -66,4 +66,4 @@ mod tests { assert_eq!(split("docker.example.com:5000/examplerepo/alpine:latest"), (String::from("docker.example.com:5000"), String::from("examplerepo/alpine"), String::from("latest"))); assert_eq!(split("portainer/portainer:latest"), (String::from(DEFAULT_REGISTRY), String::from("portainer/portainer"), String::from("latest"))); } -} \ No newline at end of file +}