summaryrefslogtreecommitdiff
path: root/src/updater.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/updater.rs')
-rw-r--r--src/updater.rs53
1 files changed, 31 insertions, 22 deletions
diff --git a/src/updater.rs b/src/updater.rs
index 9f04710..7ab6483 100644
--- a/src/updater.rs
+++ b/src/updater.rs
@@ -1,6 +1,6 @@
use crate::version::{VersionPattern, CompareOutcome};
use crate::docker::DockerRef;
-use crate::db::{Db, Image};
+use crate::db::{Db, Image, Tag};
use crate::registry::Registries;
use crate::metrics;
use chrono::{DateTime, Utc};
@@ -59,21 +59,25 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil
match reg.get_tags(&expired.registry, &expired.image) {
Some(mut fetched_tags) => {
fetched_tags.sort();
+ let mut to_delete: Vec<i64> = vec![];
+ let mut to_insert: Vec<Tag> = vec![];
let mut existing = cached_tags.iter().peekable();
for t in &fetched_tags {
- while existing.peek().is_some_and(|e| *e < t) {
+ while existing.peek().is_some_and(|e| e.tag.as_str() < t.as_str()) {
let gone = existing.next().unwrap();
- db.delete_tag(expired.id, gone);
+ to_delete.push(gone.id);
}
- if existing.peek() == Some(&t) {
+ if existing.peek().is_some_and(|e| e.tag.as_str() == t.as_str()) {
existing.next();
} else {
- db.insert_tag(expired.id, t);
+ to_insert.push(Tag { id: 0, image_id: expired.id, tag: t.clone(), digest: None });
}
}
for gone in existing {
- db.delete_tag(expired.id, gone);
+ to_delete.push(gone.id);
}
+ db.delete_tags(&to_delete);
+ db.insert_tags(&mut to_insert);
let new_expires_at = *now + cache_max_age;
db.set_expires_at(expired.id, &new_expires_at);
}
@@ -117,12 +121,12 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil
let mut current = VersionPattern::parse(&tag_str);
let mut new_tag = None;
- for candidate_str in &tags {
- let candidate = VersionPattern::parse(&candidate_str);
- match current.compare(&candidate) {
+ for candidate in &tags {
+ let candidate_pattern = VersionPattern::parse(&candidate.tag);
+ match current.compare(&candidate_pattern) {
CompareOutcome::Higher => {
- new_tag = Some(candidate_str.clone());
- current = candidate;
+ new_tag = Some(candidate.tag.clone());
+ current = candidate_pattern;
},
CompareOutcome::Lower => {},
CompareOutcome::Incompatible => {},
@@ -143,7 +147,7 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil
if let Some(ref digest) = img.digest {
let tag_for_digest = tag.as_deref().unwrap_or("latest");
let cached_digest = if image_record.expires_at > *now {
- db.get_tag_digest(image_record.id, tag_for_digest)
+ tags.iter().find(|t| t.tag == tag_for_digest).and_then(|t| t.digest.clone())
} else {
None
};
@@ -153,7 +157,10 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil
None => {
match reg.get_digest(&image_record.registry, &image_record.image, tag_for_digest) {
Some(fetched) => {
- db.update_tag_digest(image_record.id, tag_for_digest, &fetched);
+ if let Some(mut tag_record) = tags.iter().find(|t| t.tag == tag_for_digest).cloned() {
+ tag_record.digest = Some(fetched.clone());
+ db.update_tags(&[tag_record]);
+ }
Ok(fetched)
}
None => Err(format!("digest not found for {}:{}", image_record.image, tag_for_digest)),
@@ -210,8 +217,10 @@ mod tests {
let past_expiry = now - chrono::Duration::days(1);
let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry };
db.insert_image(&mut img);
- db.insert_tag(img.id, "1.20");
- db.insert_tag(img.id, "1.21");
+ db.insert_tags(&mut [
+ Tag { id: 0, image_id: img.id, tag: "1.20".into(), digest: None },
+ Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: None },
+ ]);
let files = vec![FileInput {
path: "/test".into(),
@@ -221,7 +230,8 @@ mod tests {
let mut outcomes = vec![];
update_images(&now, &db, &reg, &files, &mut outcomes);
- assert_eq!(db.get_tags_sorted(img.id), vec!["1.21", "1.22"]);
+ let tags: Vec<String> = db.get_tags_sorted(img.id).into_iter().map(|t| t.tag).collect();
+ assert_eq!(tags, vec!["1.21", "1.22"]);
let got = db.get_image("registry.hub.docker.com", "nginx").unwrap();
assert!(got.expires_at > now);
}
@@ -236,7 +246,7 @@ mod tests {
let future_expiry = now + chrono::Duration::minutes(30);
let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry };
db.insert_image(&mut img);
- db.insert_tag(img.id, "1.21");
+ db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: None }]);
let files = vec![FileInput {
path: "/test".into(),
@@ -344,8 +354,7 @@ mod tests {
let future_expiry = now + chrono::Duration::minutes(30);
let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry };
db.insert_image(&mut img);
- db.insert_tag(img.id, "1.21");
- db.update_tag_digest(img.id, "1.21", "sha256:0000000000000000000000000000000000000000000000000000000000000003");
+ db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]);
let files = vec![FileInput {
path: "/test".into(),
@@ -578,8 +587,7 @@ mod tests {
let past_expiry = now - chrono::Duration::days(1);
let mut img = Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry };
db.insert_image(&mut img);
- db.insert_tag(img.id, "1.21");
- db.update_tag_digest(img.id, "1.21", "sha256:0000000000000000000000000000000000000000000000000000000000000003");
+ db.insert_tags(&mut [Tag { id: 0, image_id: img.id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]);
let files = vec![FileInput {
path: "/test".into(),
@@ -614,7 +622,8 @@ mod tests {
assert!(outcomes[0].is_err());
assert!(db.get_image("registry.hub.docker.com", "redis").is_some());
// Redis tags ARE populated (cache refresh happens before processing), but no patches are produced
- assert_eq!(db.get_tags_sorted(2), vec!["6.0", "6.2"]);
+ let tags: Vec<String> = db.get_tags_sorted(2).into_iter().map(|t| t.tag).collect();
+ assert_eq!(tags, vec!["6.0", "6.2"]);
}
#[test]