diff options
| -rw-r--r-- | Cargo.lock | 122 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | src/db.rs | 67 | ||||
| -rw-r--r-- | src/main.rs | 30 | ||||
| -rw-r--r-- | src/registry.rs | 12 | ||||
| -rw-r--r-- | src/updater.rs | 100 |
6 files changed, 121 insertions, 213 deletions
@@ -18,15 +18,6 @@ dependencies = [ ] [[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] name = "arraydeque" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -39,12 +30,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" [[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -85,31 +70,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] -name = "chrono" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-link", -] - -[[package]] name = "chunked_transfer" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] name = "crc32fast" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -271,30 +237,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] -name = "iana-time-zone" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -376,15 +318,6 @@ dependencies = [ ] [[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -591,7 +524,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1c93dd1c9683b438c392c492109cb702b8090b2bfc8fed6f6e4eb4523f17af3" dependencies = [ "bitflags", - "chrono", "fallible-iterator", "fallible-streaming-iterator", "hashlink 0.11.0", @@ -836,7 +768,6 @@ name = "version-bumper" version = "0.1.0" dependencies = [ "base64", - "chrono", "json-event-parser", "prometheus", "rand", @@ -919,65 +850,12 @@ dependencies = [ ] [[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11,12 +11,11 @@ panic="abort" [dependencies] base64 = "0.22.1" -chrono = "0.4.43" json-event-parser = "0.2.2" prometheus = "0.14.0" rand = "0.9.2" regex = "1.12.2" -rusqlite = { version = "0.38.0", features = ["chrono"] } +rusqlite = { version = "0.38.0" } tinyjson = "2.5.1" tiny_http = "0.12" ureq = "3.1.4" @@ -1,13 +1,41 @@ -use chrono::{DateTime, Utc}; +use std::time::{Duration, UNIX_EPOCH}; use rusqlite::Connection; use rusqlite::OptionalExtension; +use rusqlite::types::{FromSql, FromSqlResult, ToSql, ToSqlOutput, ValueRef}; +use crate::time::{Timestamp, secs_to_ymd_hms, ymd_hms_to_secs}; + +impl ToSql for Timestamp { + fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> { + let d = self.0.duration_since(UNIX_EPOCH).unwrap(); + let secs = d.as_secs(); + let millis = d.subsec_millis(); + let (y, mo, day, h, min, s) = secs_to_ymd_hms(secs); + let ts = format!("{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}", y, mo, day, h, min, s, millis); + Ok(ToSqlOutput::from(ts)) + } +} + +impl FromSql for Timestamp { + fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { + let ts = value.as_str()?; + let y: u64 = ts[0..4].parse().unwrap(); + let mo: u64 = ts[5..7].parse().unwrap(); + let d: u64 = ts[8..10].parse().unwrap(); + let h: u64 = ts[11..13].parse().unwrap(); + let min: u64 = ts[14..16].parse().unwrap(); + let s: u64 = ts[17..19].parse().unwrap(); + let ms: u64 = if ts.len() >= 23 { ts[20..23].parse().unwrap_or(0) } else { 0 }; + let secs = ymd_hms_to_secs(y, mo, d, h, min, s); + Ok(Timestamp(UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_millis(ms))) + } +} #[derive(Debug, Clone)] pub struct Image { pub id: i64, pub registry: String, pub image: String, - pub expires_at: DateTime<Utc>, + pub expires_at: Timestamp, } #[derive(Debug, Clone)] @@ -20,7 +48,7 @@ pub struct Tag { pub trait Db { fn get_image(&self, registry: &str, image: &str) -> Option<Image>; - fn get_expired_images(&self, now: &DateTime<Utc>) -> Vec<Image>; + fn get_expired_images(&self, now: Timestamp) -> Vec<Image>; fn insert_images(&self, images: &mut [Image]); fn update_images(&self, images: &[Image]); @@ -161,7 +189,7 @@ impl Db for SqliteDb { } } - fn get_expired_images(&self, now: &DateTime<Utc>) -> Vec<Image> { + fn get_expired_images(&self, now: Timestamp) -> Vec<Image> { let _timer = crate::metrics::get().db_query_duration.start_timer(); let mut stmt = self.conn.prepare(" SELECT id, registry, image, expires_at FROM images WHERE expires_at <= ?1 @@ -275,10 +303,10 @@ impl Db for StubDb { } } - fn get_expired_images(&self, now: &DateTime<Utc>) -> Vec<Image> { + fn get_expired_images(&self, now: Timestamp) -> Vec<Image> { let mut result = vec![]; for img in self.images.borrow().iter() { - if img.expires_at <= *now { + if img.expires_at <= now { result.push(Image { id: img.id, registry: img.registry.clone(), @@ -331,10 +359,9 @@ impl Db for StubDb { #[cfg(test)] mod tests { use super::*; - use chrono::TimeZone; fn test_insert_images_returns_incrementing_ids(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [ Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }, Image { id: 0, registry: "docker.io".into(), image: "redis".into(), expires_at: now }, @@ -348,7 +375,7 @@ mod tests { } fn test_get_image_returns_inserted(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); let got = db.get_image("docker.io", "nginx").unwrap(); @@ -357,14 +384,14 @@ mod tests { } fn test_get_tags_returns_empty_for_no_tags(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); assert!(db.get_tags_sorted(images[0].id).is_empty()); } fn test_get_tags_returns_sorted(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); db.insert_tags(&mut [ @@ -377,7 +404,7 @@ mod tests { } fn test_delete_tags_removes_tags(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); let mut tags = [ @@ -391,8 +418,8 @@ mod tests { } fn test_update_images(db: &dyn Db) { - let t1 = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); - let t2 = Utc.with_ymd_and_hms(2000, 1, 1, 1, 0, 0).unwrap(); + let t1 = Timestamp::ZERO; + let t2 = Timestamp::ZERO + Duration::from_secs(3600); let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: t1 }]; db.insert_images(&mut images); images[0].expires_at = t2; @@ -401,7 +428,7 @@ mod tests { } fn test_tag_digest_none_when_unset(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); db.insert_tags(&mut [Tag { id: 0, image_id: images[0].id, tag: "1.0".into(), digest: None }]); @@ -409,7 +436,7 @@ mod tests { } fn test_update_tags(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let mut images = [Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: now }]; db.insert_images(&mut images); let mut tags = [Tag { id: 0, image_id: images[0].id, tag: "1.0".into(), digest: None }]; @@ -420,15 +447,15 @@ mod tests { } fn test_get_expired_images(db: &dyn Db) { - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); - let past = now - chrono::Duration::days(1); - let future = now + chrono::Duration::days(1); + let now = Timestamp::ZERO + Duration::from_secs(86400 * 30); + let past = now - Duration::from_secs(86400); + let future = now + Duration::from_secs(86400); let mut images = [ Image { id: 0, registry: "docker.io".into(), image: "nginx".into(), expires_at: past }, Image { id: 0, registry: "docker.io".into(), image: "redis".into(), expires_at: future }, ]; db.insert_images(&mut images); - let result = db.get_expired_images(&now); + let result = db.get_expired_images(now); assert_eq!(result.len(), 1); assert_eq!(result[0].id, images[0].id); assert_eq!(result[0].image, "nginx"); diff --git a/src/main.rs b/src/main.rs index c4366ca..c1888ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,19 +4,23 @@ mod docker; mod manifest; mod dockerfile; mod metrics; +mod time; mod db; mod registry; mod updater; +mod refresher; use crate::docker::DockerRef; use crate::manifest::ManifestFile; use crate::dockerfile::DockerfileFile; use crate::db::{Db, SqliteDb}; +use crate::time::Timestamp; use crate::registry::{Registries, HttpRegistry, Config, Credentials}; use crate::updater::{FileInput, FilePatch, update_images}; use rand::distr::{Alphanumeric, SampleString}; use std::io::Write; +use std::time::Duration; struct Repository { url: String, @@ -56,7 +60,7 @@ fn is_yaml(path: &std::path::Path) -> bool { return false; } -fn run_tool(db: &dyn Db, reg: &dyn Registries, repos: &Vec<Repository>, mut infile_paths: Vec<std::path::PathBuf>) -> chrono::DateTime<chrono::Utc> { +fn run_tool(db: &dyn Db, reg: &dyn Registries, repos: &Vec<Repository>, mut infile_paths: Vec<std::path::PathBuf>) -> Timestamp { for repo in repos { if repo.dest.exists() { let mut gitcmd = std::process::Command::new("git"); @@ -166,9 +170,9 @@ fn run_tool(db: &dyn Db, reg: &dyn Registries, repos: &Vec<Repository>, mut infi file_inputs.push(FileInput { path, content, images }); } - let now = chrono::offset::Utc::now(); + let now = Timestamp::now(); let mut outcomes: Vec<Result<Vec<FilePatch>, String>> = Vec::with_capacity(file_inputs.len()); - update_images(&now, db, reg, &file_inputs, &mut outcomes); + update_images(now, db, reg, &file_inputs, &mut outcomes); for i in 0..file_inputs.len() { let file = &file_inputs[i]; @@ -245,8 +249,8 @@ fn run_tool(db: &dyn Db, reg: &dyn Registries, repos: &Vec<Repository>, mut infi metrics::get().git_operations.with_label_values(&["push", "success"]).inc(); } - let now = chrono::offset::Utc::now(); - let mut min_expiry = now + chrono::Duration::hours(24); + let now = Timestamp::now(); + let mut min_expiry = now + Duration::from_secs(86400); for file in &file_inputs { for image_range in &file.images { let img = DockerRef::parse(&file.content, image_range); @@ -279,7 +283,7 @@ fn main() { let mut repos = vec![]; let mut auths = vec![]; let mut docker_auths: Vec<(String, Credentials)> = vec![]; - let mut registry_ttls: Vec<(String, chrono::Duration)> = vec![]; + let mut registry_ttls: Vec<(String, Duration)> = vec![]; let workdir = std::env::current_dir().unwrap(); if config_path.is_dir() { @@ -479,8 +483,8 @@ fn main() { match reader.parse_next() { Ok(json_event_parser::JsonEvent::Number(n)) => { - let minutes: i64 = n.parse().unwrap(); - registry_ttls.push((host, chrono::Duration::minutes(minutes))); + let minutes: u64 = n.parse().unwrap(); + registry_ttls.push((host, Duration::from_secs(minutes * 60))); }, _ => panic!("Invalid registry config json"), } @@ -512,7 +516,7 @@ fn main() { // Merge docker_auths and registry_ttls into final configs for (host, creds) in docker_auths { - let mut ttl = chrono::Duration::minutes(1440); + let mut ttl = Duration::from_secs(86400); for (h, t) in ®istry_ttls { if h == &host { ttl = *t; @@ -554,11 +558,11 @@ fn main() { let run_duration = run_start.elapsed().as_secs_f64(); metrics::get().run_duration.set(run_duration); - metrics::get().next_wakeup.set(next_wakeup.timestamp() as f64); + metrics::get().next_wakeup.set(next_wakeup.duration_since(Timestamp::ZERO).unwrap().as_secs() as f64); metrics::get().state.set(metrics::STATE_IDLE); - let sleep_duration = next_wakeup - chrono::offset::Utc::now(); - println!("Waiting {} seconds for next run", sleep_duration.num_seconds()); - std::thread::sleep(sleep_duration.to_std().unwrap()); + let sleep_duration = next_wakeup.duration_since(Timestamp::now()).unwrap_or(Duration::ZERO); + println!("Waiting {} seconds for next run", sleep_duration.as_secs()); + std::thread::sleep(sleep_duration); } } diff --git a/src/registry.rs b/src/registry.rs index c1ab4b7..c4eefdd 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; pub trait Registries { fn get_tags(&self, registry: &str, image: &str) -> Option<Vec<String>>; fn get_digest(&self, registry: &str, image: &str, tag: &str) -> Option<String>; - fn get_cache_ttl(&self, registry: &str) -> chrono::Duration; + fn get_cache_ttl(&self, registry: &str) -> std::time::Duration; } #[derive(Debug)] @@ -48,7 +48,7 @@ pub enum Credentials { pub struct Config { pub host: String, pub credentials: Credentials, - pub cache_ttl: chrono::Duration, + pub cache_ttl: std::time::Duration, } enum AuthStage { @@ -314,12 +314,12 @@ impl Registries for HttpRegistry { return Some(digest); } - fn get_cache_ttl(&self, registry: &str) -> chrono::Duration { + fn get_cache_ttl(&self, registry: &str) -> std::time::Duration { let auth = self.auth.borrow(); if let Some(state) = auth.get(registry) { return state.config.cache_ttl; } - return chrono::Duration::minutes(1440); + return std::time::Duration::from_secs(86400); } } @@ -389,8 +389,8 @@ impl Registries for StubRegistry { return None; } - fn get_cache_ttl(&self, _registry: &str) -> chrono::Duration { - return chrono::Duration::minutes(1440); + fn get_cache_ttl(&self, _registry: &str) -> std::time::Duration { + return std::time::Duration::from_secs(86400); } } diff --git a/src/updater.rs b/src/updater.rs index 689aa57..938bc52 100644 --- a/src/updater.rs +++ b/src/updater.rs @@ -1,9 +1,9 @@ use crate::version::{VersionPattern, CompareOutcome}; use crate::docker::DockerRef; use crate::db::{Db, Image, Tag}; +use crate::time::Timestamp; use crate::registry::Registries; use crate::metrics; -use chrono::{DateTime, Utc}; use std::ops::Range; #[derive(Debug)] @@ -18,7 +18,7 @@ pub struct FileInput { pub images: Vec<Range<usize>>, } -pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, files: &[FileInput], outcomes: &mut Vec<Result<Vec<FilePatch>, String>>) { +pub fn update_images(now: Timestamp, db: &dyn Db, reg: &dyn Registries, files: &[FileInput], outcomes: &mut Vec<Result<Vec<FilePatch>, String>>) { let mut file_idxs: Vec<usize> = vec![]; let mut parsed: Vec<DockerRef> = vec![]; let mut images: Vec<Image> = vec![]; @@ -38,7 +38,7 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil id: 0, registry: registry.to_string(), image: image_name.to_string(), - expires_at: DateTime::<Utc>::UNIX_EPOCH, + expires_at: Timestamp::ZERO, }]; db.insert_images(&mut new_images); new_images[0].clone() @@ -80,11 +80,11 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil } db.delete_tags(&to_delete); db.insert_tags(&mut to_insert); - expired.expires_at = *now + cache_max_age; + expired.expires_at = now + cache_max_age; db.update_images(&[expired]); } None => { - expired.expires_at = *now + cache_max_age; + expired.expires_at = now + cache_max_age; db.update_images(&[expired]); } } @@ -114,7 +114,7 @@ pub fn update_images(now: &DateTime<Utc>, db: &dyn Db, reg: &dyn Registries, fil let tags = db.get_tags_sorted(image_record.id); - if image_record.expires_at <= *now && tags.is_empty() { + if image_record.expires_at <= now && tags.is_empty() { file_errors[file_idx] = Some(format!("{}/{} was not refreshed", image_record.registry, image_record.image)); continue; } @@ -148,7 +148,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 { + let cached_digest = if image_record.expires_at > now { tags.iter().find(|t| t.tag == tag_for_digest).and_then(|t| t.digest.clone()) } else { None @@ -204,19 +204,19 @@ mod tests { use super::*; use crate::db::StubDb; use crate::registry::{StubRegistry, StubTag}; - use chrono::TimeZone; + use std::time::Duration; #[test] fn stale_cache_fetches_from_registry() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.22".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000002".into() }, ]); - let past_expiry = now - chrono::Duration::days(1); + let past_expiry = Timestamp::ZERO - Duration::from_secs(86400); let mut images = [Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry }]; db.insert_images(&mut images); db.insert_tags(&mut [ @@ -230,7 +230,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let tags: Vec<String> = db.get_tags_sorted(images[0].id).into_iter().map(|t| t.tag).collect(); assert_eq!(tags, vec!["1.21", "1.22"]); @@ -241,11 +241,11 @@ mod tests { #[test] fn fresh_cache_uses_cached_tags() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![]); - let future_expiry = now + chrono::Duration::minutes(30); + let future_expiry = Timestamp::ZERO + Duration::from_secs(1800); let mut images = [Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry }]; db.insert_images(&mut images); db.insert_tags(&mut [Tag { id: 0, image_id: images[0].id, tag: "1.21".into(), digest: None }]); @@ -256,7 +256,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].as_ref().unwrap().is_empty()); } @@ -264,7 +264,7 @@ mod tests { #[test] fn no_patch_when_at_highest() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -276,7 +276,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].as_ref().unwrap().is_empty()); } @@ -284,7 +284,7 @@ mod tests { #[test] fn patch_to_higher_version() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -297,7 +297,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert_eq!(outcomes[0].as_ref().unwrap()[0].content, "1.22"); } @@ -305,7 +305,7 @@ mod tests { #[test] fn picks_highest_of_multiple() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -319,7 +319,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert_eq!(outcomes[0].as_ref().unwrap()[0].content, "1.25"); } @@ -327,7 +327,7 @@ mod tests { #[test] fn no_tag_skips_comparison() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "latest".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -339,7 +339,7 @@ mod tests { images: vec![7..84] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 1); @@ -349,11 +349,11 @@ mod tests { #[test] fn uses_cached_digest_when_fresh() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![]); - let future_expiry = now + chrono::Duration::minutes(30); + let future_expiry = Timestamp::ZERO + Duration::from_secs(1800); let mut images = [Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: future_expiry }]; db.insert_images(&mut images); db.insert_tags(&mut [Tag { id: 0, image_id: images[0].id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]); @@ -364,7 +364,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 1); @@ -374,7 +374,7 @@ mod tests { #[test] fn fetches_digest_when_not_cached() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000004".into() }, @@ -386,7 +386,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 1); @@ -396,7 +396,7 @@ mod tests { #[test] fn no_patch_when_digest_matches() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000002".into() }, @@ -408,7 +408,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].as_ref().unwrap().is_empty()); } @@ -416,7 +416,7 @@ mod tests { #[test] fn patch_when_digest_differs() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000002".into() }, @@ -428,7 +428,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 1); @@ -438,7 +438,7 @@ mod tests { #[test] fn digest_uses_updated_tag() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -451,7 +451,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 2); @@ -462,7 +462,7 @@ mod tests { #[test] fn error_when_image_not_found() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![]); @@ -472,7 +472,7 @@ mod tests { images: vec![7..17] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].is_err()); let got = db.get_image("registry.hub.docker.com", "nginx").unwrap(); @@ -482,7 +482,7 @@ mod tests { #[test] fn error_when_digest_not_found() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -494,7 +494,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].is_err()); } @@ -502,7 +502,7 @@ mod tests { #[test] fn multiple_images_produce_patches() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -517,7 +517,7 @@ mod tests { images: vec![7..17, 25..34] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches.len(), 2); @@ -526,7 +526,7 @@ mod tests { #[test] fn patches_sorted_by_position() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -541,7 +541,7 @@ mod tests { images: vec![7..17, 25..34] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert!(patches[0].position.start < patches[1].position.start); @@ -550,7 +550,7 @@ mod tests { #[test] fn multiple_files_independent() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -570,7 +570,7 @@ mod tests { }, ]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].is_err()); assert!(outcomes[1].is_ok()); @@ -580,13 +580,13 @@ mod tests { #[test] fn stale_cache_ignores_cached_digest() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000005".into() }, ]); - let past_expiry = now - chrono::Duration::days(1); + let past_expiry = Timestamp::ZERO - Duration::from_secs(86400); let mut images = [Image { id: 0, registry: "registry.hub.docker.com".into(), image: "nginx".into(), expires_at: past_expiry }]; db.insert_images(&mut images); db.insert_tags(&mut [Tag { id: 0, image_id: images[0].id, tag: "1.21".into(), digest: Some("sha256:0000000000000000000000000000000000000000000000000000000000000003".into()) }]); @@ -597,7 +597,7 @@ mod tests { images: vec![7..89] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); let patches = outcomes[0].as_ref().unwrap(); assert_eq!(patches[0].content, "sha256:0000000000000000000000000000000000000000000000000000000000000005"); @@ -606,7 +606,7 @@ mod tests { #[test] fn error_in_first_image_skips_remaining() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "redis".into(), tag: "6.0".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -619,7 +619,7 @@ mod tests { images: vec![7..17, 25..34] }]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert!(outcomes[0].is_err()); assert!(db.get_image("registry.hub.docker.com", "redis").is_some()); @@ -631,7 +631,7 @@ mod tests { #[test] fn same_image_multiple_files_fetches_twice() { crate::metrics::init(); - let now = Utc.with_ymd_and_hms(2000, 1, 1, 0, 0, 0).unwrap(); + let now = Timestamp::ZERO; let db = StubDb::default(); let reg = StubRegistry::new(vec![ StubTag { registry: "registry.hub.docker.com".into(), image: "nginx".into(), tag: "1.21".into(), digest: "sha256:0000000000000000000000000000000000000000000000000000000000000001".into() }, @@ -643,7 +643,7 @@ mod tests { FileInput { path: "/b".into(), content: "image: nginx:1.21".into(), images: vec![7..17] }, ]; let mut outcomes = vec![]; - update_images(&now, &db, ®, &files, &mut outcomes); + update_images(now, &db, ®, &files, &mut outcomes); assert_eq!(outcomes[0].as_ref().unwrap()[0].content, "1.22"); assert_eq!(outcomes[1].as_ref().unwrap()[0].content, "1.22"); |
