Skip to content

Commit

Permalink
Merge branch main into improve-logging
Browse files Browse the repository at this point in the history
  • Loading branch information
sergi0g committed Sep 15, 2024
2 parents ba08950 + 0c9ad61 commit 06469e0
Show file tree
Hide file tree
Showing 8 changed files with 837 additions and 308 deletions.
769 changes: 646 additions & 123 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ edition = "2021"
[dependencies]
clap = { version = "4.5.7", features = ["derive"] }
indicatif = { version = "0.17.8", optional = true }
tokio = {version = "1.38.0", features = ["rt", "rt-multi-thread", "macros"]}
ureq = { version = "2.9.7", features = ["tls"] }
rayon = "1.10.0"
tokio = {version = "1.38.0", features = ["macros"]}
xitca-web = { version = "0.5.0", optional = true, features = ["logger"] }
liquid = { version = "0.26.6", optional = true }
bollard = "0.16.1"
once_cell = "1.19.0"
http-auth = { version = "0.1.9", features = [] }
http-auth = { version = "0.1.9", default-features = false, features = [] }
termsize = { version = "0.1.8", optional = true }
regex = "1.10.5"
chrono = { version = "0.4.38", default-features = false, features = ["std", "alloc", "clock"], optional = true }
json = "0.12.4"
reqwest = "0.12.7"
futures = "0.3.30"
reqwest-retry = "0.6.1"
reqwest-middleware = "0.3.3"

[features]
default = ["server", "cli"]
Expand Down
59 changes: 28 additions & 31 deletions src/check.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
use std::{
collections::{HashMap, HashSet},
sync::Mutex,
};
use std::collections::{HashMap, HashSet};

use chrono::Local;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};

use crate::{
debug,
docker::get_images_from_docker_daemon,
image::Image,
info,
registry::{check_auth, get_latest_digests, get_token},
utils::{unsplit_image, CliConfig},
utils::{new_reqwest_client, unsplit_image, CliConfig},
};

#[cfg(feature = "cli")]
Expand All @@ -37,60 +33,60 @@ where

pub async fn get_all_updates(options: &CliConfig) -> Vec<(String, Option<bool>)> {
let start = Local::now().timestamp_millis();
let image_map_mutex: Mutex<HashMap<String, &Option<String>>> = Mutex::new(HashMap::new());
let local_images = get_images_from_docker_daemon(options).await;
local_images.par_iter().for_each(|image| {
let mut image_map: HashMap<String, Option<String>> = HashMap::with_capacity(local_images.len());
for image in &local_images {
let img = unsplit_image(image);
image_map_mutex.lock().unwrap().insert(img, &image.digest);
});
let image_map = image_map_mutex.lock().unwrap().clone();
let mut registries: Vec<&String> = local_images
.par_iter()
.map(|image| &image.registry)
.collect();
image_map.insert(img, image.digest.clone());
}
let mut registries: Vec<&String> = local_images.iter().map(|image| &image.registry).collect();
registries.unique();
let mut remote_images: Vec<Image> = Vec::new();
let mut remote_images: Vec<Image> = Vec::with_capacity(local_images.len());
let client = new_reqwest_client();
for registry in registries {
if options.verbose {
debug!("Checking images from registry {}", registry)
}
let images: Vec<&Image> = local_images
.par_iter()
.iter()
.filter(|image| &image.registry == registry)
.collect();
let credentials = options.config["authentication"][registry]
.clone()
.take_string()
.or(None);
let mut latest_images = match check_auth(registry, options) {
let mut latest_images = match check_auth(registry, options, &client).await {
Some(auth_url) => {
let token = get_token(images.clone(), &auth_url, &credentials, options);
let token = get_token(images.clone(), &auth_url, &credentials, &client).await;
if options.verbose {
debug!("Using token {}", token);
}
get_latest_digests(images, Some(&token), options)
get_latest_digests(images, Some(&token), options, &client).await
}
None => get_latest_digests(images, None, options),
None => get_latest_digests(images, None, options, &client).await,
};
remote_images.append(&mut latest_images);
}
if options.verbose {
debug!("Collecting results")
}
let result_mutex: Mutex<Vec<(String, Option<bool>)>> = Mutex::new(Vec::new());
remote_images.par_iter().for_each(|image| {
let mut result: Vec<(String, Option<bool>)> = Vec::new();
remote_images.iter().for_each(|image| {
let img = unsplit_image(image);
match &image.digest {
Some(d) => {
let r = d != image_map.get(&img).unwrap().as_ref().unwrap();
result_mutex.lock().unwrap().push((img, Some(r)))
result.push((img, Some(r)))
}
None => result_mutex.lock().unwrap().push((img, None)),
None => result.push((img, None)),
}
});
let result = result_mutex.lock().unwrap().clone();
let end = Local::now().timestamp_millis();
info!("✨ Checked {} images in {}ms", local_images.len(), end - start);
info!(
"✨ Checked {} images in {}ms",
local_images.len(),
end - start
);
result
}

Expand All @@ -101,16 +97,17 @@ pub async fn get_update(image: &str, options: &CliConfig) -> Option<bool> {
.clone()
.take_string()
.or(None);
let token = match check_auth(&local_image.registry, options) {
Some(auth_url) => get_token(vec![&local_image], &auth_url, &credentials, options),
let client = new_reqwest_client();
let token = match check_auth(&local_image.registry, options, &client).await {
Some(auth_url) => get_token(vec![&local_image], &auth_url, &credentials, &client).await,
None => String::new(),
};
if options.verbose {
debug!("Using token {}", token);
};
let remote_image = match token.as_str() {
"" => get_latest_digest(&local_image, None, options),
_ => get_latest_digest(&local_image, Some(&token), options),
"" => get_latest_digest(&local_image, None, options, &client).await,
_ => get_latest_digest(&local_image, Some(&token), options, &client).await,
};
match &remote_image.digest {
Some(d) => Some(d != &local_image.digest.unwrap()),
Expand Down
35 changes: 10 additions & 25 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use bollard::{secret::ImageSummary, ClientVersion, Docker};

#[cfg(feature = "cli")]
use bollard::secret::ImageInspect;
use futures::future::join_all;

use crate::{
debug, error,
error,
image::Image,
utils::{split_image, CliConfig},
};
Expand Down Expand Up @@ -36,32 +37,16 @@ pub async fn get_images_from_docker_daemon(options: &CliConfig) -> Vec<Image> {
error!("Failed to retrieve list of images available!\n{}", e)
}
};
let mut result: Vec<Image> = Vec::new();
let mut handles = Vec::new();
for image in images {
if !image.repo_tags.is_empty() && !image.repo_digests.is_empty() {
for t in &image.repo_tags {
let (registry, repository, tag) = split_image(t);
result.push(Image {
registry,
repository,
tag,
digest: Some(
image.repo_digests[0]
.clone()
.split('@')
.collect::<Vec<&str>>()[1]
.to_string(),
),
});
}
} else if options.verbose {
debug!(
"Skipped an image\nTags: {:#?}\nDigests: {:#?}",
image.repo_tags, image.repo_digests
)
}
handles.push(Image::from(image, options))
}
result
join_all(handles)
.await
.iter()
.filter(|img| img.is_some())
.map(|img| img.clone().unwrap())
.collect()
}

#[cfg(feature = "cli")]
Expand Down
34 changes: 34 additions & 0 deletions src/image.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
use bollard::secret::ImageSummary;

use crate::{
debug,
utils::{split_image, CliConfig},
};

#[derive(Clone, Debug)]
pub struct Image {
pub registry: String,
pub repository: String,
pub tag: String,
pub digest: Option<String>,
}

impl Image {
pub async fn from(image: ImageSummary, options: &CliConfig) -> Option<Self> {
if !image.repo_tags.is_empty() && !image.repo_digests.is_empty() {
let (registry, repository, tag) = split_image(&image.repo_tags[0]);
let image = Image {
registry,
repository,
tag,
digest: Some(
image.repo_digests[0]
.clone()
.split('@')
.collect::<Vec<&str>>()[1]
.to_string(),
),
};
return Some(image);
} else if options.verbose {
debug!(
"Skipped an image\nTags: {:#?}\nDigests: {:#?}",
image.repo_tags, image.repo_digests
)
}
None
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ async fn main() {
};
}
None => {
match raw || cli.verbose {
match *raw || cli.verbose {
true => print_raw_updates(&get_all_updates(&cli_config).await),
false => {
let spinner = Spinner::new();
Expand Down
Loading

0 comments on commit 06469e0

Please sign in to comment.