mirror of
https://github.com/sergi0g/cup.git
synced 2025-11-16 17:13:46 -05:00
Support checking for version updates for images that aren't available locally
This commit is contained in:
23
src/check.rs
23
src/check.rs
@@ -1,6 +1,6 @@
|
|||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
@@ -13,7 +13,24 @@ 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
|
||||||
let 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 {
|
||||||
|
Some(refs) => {
|
||||||
|
let image_refs: FxHashSet<&String> = images.iter().map(|image| &image.reference).collect();
|
||||||
|
let extra = refs.iter().filter(|&reference| !image_refs.contains(reference)).collect::<Vec<&String>>();
|
||||||
|
let mut handles = Vec::with_capacity(extra.len());
|
||||||
|
|
||||||
|
for reference in extra {
|
||||||
|
let future = Image::from_reference(reference);
|
||||||
|
handles.push(future)
|
||||||
|
}
|
||||||
|
Some(join_all(handles).await)
|
||||||
|
},
|
||||||
|
None => None
|
||||||
|
};
|
||||||
|
if let Some(extra_imgs) = extra_images {
|
||||||
|
images.extend_from_slice(&extra_imgs);
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
@@ -55,7 +72,7 @@ pub async fn get_updates(references: &Option<Vec<String>>, config: &Config) -> V
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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::new();
|
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
|
||||||
for image in &images {
|
for image in &images {
|
||||||
let token = tokens.get(image.registry.as_str()).unwrap();
|
let token = tokens.get(image.registry.as_str()).unwrap();
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ pub async fn get_latest_tag(
|
|||||||
};
|
};
|
||||||
match tag {
|
match tag {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
if t == base {
|
if t == base && image.digest_info.is_some() {
|
||||||
// Tags are equal so we'll compare digests
|
// Tags are equal so we'll compare digests
|
||||||
get_latest_digest(
|
get_latest_digest(
|
||||||
&Image {
|
&Image {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use json::{object, JsonValue};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
|
error,
|
||||||
http::Client,
|
http::Client,
|
||||||
registry::{get_latest_digest, get_latest_tag},
|
registry::{get_latest_digest, get_latest_tag},
|
||||||
structs::{status::Status, version::Version},
|
structs::{status::Status, version::Version},
|
||||||
@@ -40,7 +41,7 @@ pub struct Image {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Image {
|
impl Image {
|
||||||
/// Creates an populates the fields of an Image object based on the ImageSummary from the Docker daemon
|
/// Creates and populates the fields of an Image object based on the ImageSummary from the Docker daemon
|
||||||
pub async fn from_inspect_data<T: InspectData>(image: T) -> Option<Self> {
|
pub async fn from_inspect_data<T: InspectData>(image: T) -> Option<Self> {
|
||||||
let tags = image.tags().unwrap();
|
let tags = image.tags().unwrap();
|
||||||
let digests = image.digests().unwrap();
|
let digests = image.digests().unwrap();
|
||||||
@@ -61,8 +62,8 @@ impl Image {
|
|||||||
local_digests,
|
local_digests,
|
||||||
remote_digest: None,
|
remote_digest: None,
|
||||||
}),
|
}),
|
||||||
version_info: version_tag.map(|stag| VersionInfo {
|
version_info: version_tag.map(|vtag| VersionInfo {
|
||||||
current_tag: stag,
|
current_tag: vtag,
|
||||||
latest_remote_tag: None,
|
latest_remote_tag: None,
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -72,6 +73,29 @@ impl Image {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates and populates the fields of an Image object based on a reference. If the tag is not recognized as a version string, exits the program with an error.
|
||||||
|
pub async fn from_reference(reference: &str) -> Self {
|
||||||
|
let (registry, repository, tag) = split(&reference);
|
||||||
|
let version_tag = Version::from_tag(&tag);
|
||||||
|
match version_tag {
|
||||||
|
Some(version) => Self {
|
||||||
|
reference: reference.to_string(),
|
||||||
|
registry,
|
||||||
|
repository,
|
||||||
|
tag,
|
||||||
|
version_info: Some(VersionInfo {
|
||||||
|
current_tag: version,
|
||||||
|
latest_remote_tag: None,
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
None => error!(
|
||||||
|
"Image {} is not available locally and does not have a recognizable tag format!",
|
||||||
|
reference
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compares remote digest of the image with its local digests to determine if it has an update or not
|
/// Compares remote digest of the image with its local digests to determine if it has an update or not
|
||||||
pub fn has_update(&self) -> Status {
|
pub fn has_update(&self) -> Status {
|
||||||
if self.error.is_some() {
|
if self.error.is_some() {
|
||||||
|
|||||||
Reference in New Issue
Block a user