mirror of
https://github.com/sergi0g/cup.git
synced 2025-11-16 17:13:46 -05:00
Add debug option to CLI
This commit is contained in:
@@ -4,6 +4,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
|
debug,
|
||||||
docker::get_images_from_docker_daemon,
|
docker::get_images_from_docker_daemon,
|
||||||
http::Client,
|
http::Client,
|
||||||
registry::{check_auth, get_token},
|
registry::{check_auth, get_token},
|
||||||
@@ -13,6 +14,7 @@ use crate::{
|
|||||||
/// Returns a list of updates for all images passed in.
|
/// Returns a list of updates for all images passed in.
|
||||||
pub async fn get_updates(references: &Option<Vec<String>>, config: &Config) -> Vec<Image> {
|
pub async fn get_updates(references: &Option<Vec<String>>, config: &Config) -> Vec<Image> {
|
||||||
// Get images
|
// Get images
|
||||||
|
debug!(config.debug, "Retrieving images to be checked");
|
||||||
let mut images = get_images_from_docker_daemon(config, references).await;
|
let mut images = get_images_from_docker_daemon(config, references).await;
|
||||||
let extra_images = match references {
|
let extra_images = match references {
|
||||||
Some(refs) => {
|
Some(refs) => {
|
||||||
@@ -35,6 +37,11 @@ pub async fn get_updates(references: &Option<Vec<String>>, config: &Config) -> V
|
|||||||
if let Some(extra_imgs) = extra_images {
|
if let Some(extra_imgs) = extra_images {
|
||||||
images.extend_from_slice(&extra_imgs);
|
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.
|
// 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
|
let registries: Vec<&String> = images
|
||||||
@@ -75,6 +82,8 @@ pub async fn get_updates(references: &Option<Vec<String>>, config: &Config) -> V
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug!(config.debug, "Tokens: {:?}", tokens);
|
||||||
|
|
||||||
// Create a Vec to store futures so we can await them all at once.
|
// Create a Vec to store futures so we can await them all at once.
|
||||||
let mut handles = Vec::with_capacity(images.len());
|
let mut handles = Vec::with_capacity(images.len());
|
||||||
// Loop through images and get the latest digest for each
|
// Loop through images and get the latest digest for each
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ pub struct Config {
|
|||||||
pub theme: Theme,
|
pub theme: Theme,
|
||||||
pub insecure_registries: Vec<String>,
|
pub insecure_registries: Vec<String>,
|
||||||
pub socket: Option<String>,
|
pub socket: Option<String>,
|
||||||
|
pub debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -29,6 +30,7 @@ impl Config {
|
|||||||
theme: Theme::Default,
|
theme: Theme::Default,
|
||||||
insecure_registries: Vec::with_capacity(0),
|
insecure_registries: Vec::with_capacity(0),
|
||||||
socket: None,
|
socket: None,
|
||||||
|
debug: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Reads the config from the file path provided and returns the parsed result.
|
/// Reads the config from the file path provided and returns the parsed result.
|
||||||
@@ -125,6 +127,7 @@ impl Config {
|
|||||||
theme,
|
theme,
|
||||||
insecure_registries,
|
insecure_registries,
|
||||||
socket,
|
socket,
|
||||||
|
debug: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ struct Cli {
|
|||||||
config_path: String,
|
config_path: String,
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Commands>,
|
command: Option<Commands>,
|
||||||
|
#[arg(short, long)]
|
||||||
|
debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
Check {
|
Check {
|
||||||
#[arg(name = "Images", default_value = None)]
|
#[arg(name = "images", default_value = None)]
|
||||||
references: Option<Vec<String>>,
|
references: Option<Vec<String>>,
|
||||||
#[arg(short, long, default_value_t = false, help = "Enable icons")]
|
#[arg(short, long, default_value_t = false, help = "Enable icons")]
|
||||||
icons: bool,
|
icons: bool,
|
||||||
@@ -71,6 +73,7 @@ async fn main() {
|
|||||||
if let Some(socket) = cli.socket {
|
if let Some(socket) = cli.socket {
|
||||||
config.socket = Some(socket)
|
config.socket = Some(socket)
|
||||||
}
|
}
|
||||||
|
config.debug = cli.debug;
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
Some(Commands::Check {
|
Some(Commands::Check {
|
||||||
@@ -79,7 +82,7 @@ async fn main() {
|
|||||||
raw,
|
raw,
|
||||||
}) => {
|
}) => {
|
||||||
let start = timestamp();
|
let start = timestamp();
|
||||||
match raw {
|
match *raw || config.debug {
|
||||||
true => {
|
true => {
|
||||||
let updates = get_updates(references, &config).await;
|
let updates = get_updates(references, &config).await;
|
||||||
print_raw_updates(&updates);
|
print_raw_updates(&updates);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use itertools::Itertools;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
error,
|
debug, error,
|
||||||
http::Client,
|
http::Client,
|
||||||
structs::{
|
structs::{
|
||||||
image::{DigestInfo, Image, VersionInfo},
|
image::{DigestInfo, Image, VersionInfo},
|
||||||
@@ -46,6 +46,10 @@ pub async fn get_latest_digest(
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
) -> Image {
|
) -> Image {
|
||||||
|
debug!(
|
||||||
|
config.debug,
|
||||||
|
"Checking for digest update to {}", image.reference
|
||||||
|
);
|
||||||
let start = timestamp();
|
let start = timestamp();
|
||||||
let protocol = get_protocol(&image.registry, &config.insecure_registries);
|
let protocol = get_protocol(&image.registry, &config.insecure_registries);
|
||||||
let url = format!(
|
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 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 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 {
|
match response {
|
||||||
Ok(res) => match res.headers().get("docker-content-digest") {
|
Ok(res) => match res.headers().get("docker-content-digest") {
|
||||||
Some(digest) => {
|
Some(digest) => {
|
||||||
@@ -68,7 +77,7 @@ pub async fn get_latest_digest(
|
|||||||
remote_digest: Some(digest.to_str().unwrap().to_string()),
|
remote_digest: Some(digest.to_str().unwrap().to_string()),
|
||||||
local_digests,
|
local_digests,
|
||||||
}),
|
}),
|
||||||
time_ms: image.time_ms + (timestamp() - start),
|
time_ms: image.time_ms + time,
|
||||||
..image.clone()
|
..image.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +88,7 @@ pub async fn get_latest_digest(
|
|||||||
},
|
},
|
||||||
Err(error) => Image {
|
Err(error) => Image {
|
||||||
error: Some(error),
|
error: Some(error),
|
||||||
time_ms: image.time_ms + (timestamp() - start),
|
time_ms: image.time_ms + time,
|
||||||
..image.clone()
|
..image.clone()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -113,6 +122,10 @@ pub async fn get_latest_tag(
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
) -> Image {
|
) -> Image {
|
||||||
|
debug!(
|
||||||
|
config.debug,
|
||||||
|
"Checking for tag update to {}", image.reference
|
||||||
|
);
|
||||||
let start = timestamp();
|
let start = timestamp();
|
||||||
let protocol = get_protocol(&image.registry, &config.insecure_registries);
|
let protocol = get_protocol(&image.registry, &config.insecure_registries);
|
||||||
let url = format!(
|
let url = format!(
|
||||||
@@ -129,6 +142,12 @@ pub async fn get_latest_tag(
|
|||||||
let mut next_url = Some(url);
|
let mut next_url = Some(url);
|
||||||
|
|
||||||
while next_url.is_some() {
|
while next_url.is_some() {
|
||||||
|
debug!(
|
||||||
|
config.debug,
|
||||||
|
"{} has extra tags! Current number of valid tags: {}",
|
||||||
|
image.reference,
|
||||||
|
tags.len()
|
||||||
|
);
|
||||||
let (new_tags, next) =
|
let (new_tags, next) =
|
||||||
match get_extra_tags(&next_url.unwrap(), headers.clone(), base, client).await {
|
match get_extra_tags(&next_url.unwrap(), headers.clone(), base, client).await {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
@@ -148,6 +167,11 @@ pub async fn get_latest_tag(
|
|||||||
Some(data) => data.current_tag.clone(),
|
Some(data) => data.current_tag.clone(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
let time = timestamp() - start;
|
||||||
|
debug!(
|
||||||
|
config.debug,
|
||||||
|
"Checked for tag update to {} in {}ms", image.reference, time
|
||||||
|
);
|
||||||
match tag {
|
match tag {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
if t == base && image.digest_info.is_some() {
|
if t == base && image.digest_info.is_some() {
|
||||||
@@ -158,7 +182,7 @@ pub async fn get_latest_tag(
|
|||||||
current_tag,
|
current_tag,
|
||||||
latest_remote_tag: Some(t.clone()),
|
latest_remote_tag: Some(t.clone()),
|
||||||
}),
|
}),
|
||||||
time_ms: image.time_ms + (timestamp() - start),
|
time_ms: image.time_ms + time,
|
||||||
..image.clone()
|
..image.clone()
|
||||||
},
|
},
|
||||||
token,
|
token,
|
||||||
@@ -172,7 +196,7 @@ pub async fn get_latest_tag(
|
|||||||
current_tag,
|
current_tag,
|
||||||
latest_remote_tag: Some(t.clone()),
|
latest_remote_tag: Some(t.clone()),
|
||||||
}),
|
}),
|
||||||
time_ms: image.time_ms + (timestamp() - start),
|
time_ms: image.time_ms + time,
|
||||||
..image.clone()
|
..image.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! error {
|
macro_rules! error {
|
||||||
($($arg:tt)*) => ({
|
($($arg:tt)*) => ({
|
||||||
eprintln!("\x1b[38:5:204mERROR \x1b[0m {}", format!($($arg)*));
|
eprintln!("\x1b[31;1mERROR \x1b[0m {}", format!($($arg)*));
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -13,20 +13,22 @@ macro_rules! error {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! warn {
|
macro_rules! warn {
|
||||||
($($arg:tt)*) => ({
|
($($arg:tt)*) => ({
|
||||||
eprintln!("\x1b[38:5:192mWARN \x1b[0m {}", format!($($arg)*));
|
eprintln!("\x1b[33;1mWARN \x1b[0m {}", format!($($arg)*));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! info {
|
macro_rules! info {
|
||||||
($($arg:tt)*) => ({
|
($($arg:tt)*) => ({
|
||||||
println!("\x1b[38:5:86mINFO \x1b[0m {}", format!($($arg)*));
|
println!("\x1b[36;1mINFO \x1b[0m {}", format!($($arg)*));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! debug {
|
macro_rules! debug {
|
||||||
($($arg:tt)*) => ({
|
($debg:expr, $($arg:tt)*) => ({
|
||||||
println!("\x1b[38:5:63mDEBUG \x1b[0m {}", format!($($arg)*));
|
if $debg {
|
||||||
|
println!("\x1b[35;1mDEBUG \x1b[0m {}", format!($($arg)*));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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("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")));
|
assert_eq!(split("portainer/portainer:latest"), (String::from(DEFAULT_REGISTRY), String::from("portainer/portainer"), String::from("latest")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user