summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock122
-rw-r--r--Cargo.toml3
-rw-r--r--src/db.rs67
-rw-r--r--src/main.rs30
-rw-r--r--src/registry.rs12
-rw-r--r--src/updater.rs100
6 files changed, 121 insertions, 213 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 77b91a8..6a355ad 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 64288cf..f2bf17d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/src/db.rs b/src/db.rs
index 6a4d732..e319fd6 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -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 &registry_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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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, &reg, &files, &mut outcomes);
+ update_images(now, &db, &reg, &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");