summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesper Jensen <jesper@jnsn.dev>2026-02-08 00:42:32 +0100
committerJesper Jensen <jesper@jnsn.dev>2026-02-08 00:42:32 +0100
commit8d1a7d1fd90a359eee553774655c9b7fc3e41233 (patch)
tree513af4d4bbb9d2ff3bc5f7531142793e4f2f3640
parent6f66f51a234b845308106ac303f87a884bfc1ecd (diff)
Automatically run at expire times
-rw-r--r--src/main.rs39
-rw-r--r--src/metrics.rs7
2 files changed, 41 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 7c62521..8c7f5d8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -124,7 +124,10 @@ fn update_images(now: &chrono::DateTime<chrono::Utc>, db: &dyn Db, reg: &dyn Reg
Ok((fetched_tags, None))
}
- None => Err(format!("image not found: {}", image_name)),
+ None => {
+ db.update_last_checked(image_id, now);
+ Err(format!("image not found: {}", image_name))
+ }
}
} else {
println!("Valid in cache");
@@ -302,7 +305,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>, overwrite: bool) {
+fn run_tool(db: &dyn Db, reg: &dyn Registries, repos: &Vec<Repository>, mut infile_paths: Vec<std::path::PathBuf>, overwrite: bool) -> chrono::DateTime<chrono::Utc> {
for repo in repos {
if repo.dest.exists() {
let mut gitcmd = std::process::Command::new("git");
@@ -492,6 +495,30 @@ 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);
+ for file in &file_inputs {
+ for image_range in &file.images {
+ let img = DockerRef::parse(&file.content, image_range);
+ let registry = img.registry.as_ref()
+ .map(|x| &file.content[x.clone()])
+ .unwrap_or("registry.hub.docker.com");
+ let image_name = &file.content[img.image.clone()];
+
+ if let Some((_, last_checked)) = db.get_image(registry, image_name) {
+ let cache_ttl = reg.get_cache_ttl(registry);
+ let expiry = last_checked + cache_ttl;
+ if expiry < min_expiry {
+ min_expiry = expiry;
+ }
+ }
+ }
+ }
+ if min_expiry < now {
+ min_expiry = now;
+ }
+ return min_expiry;
}
fn main() {
@@ -874,15 +901,17 @@ fn main() {
metrics::get().state.set(metrics::STATE_ACTIVE);
let run_start = std::time::Instant::now();
- run_tool(&sqlite_db, &registry, &repos, infile_paths.clone(), overwrite);
+ let next_wakeup = run_tool(&sqlite_db, &registry, &repos, infile_paths.clone(), overwrite);
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().state.set(metrics::STATE_IDLE);
if !continuous { break; }
- println!("Waiting for next run");
- std::thread::sleep(std::time::Duration::from_hours(24));
+ 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());
}
}
diff --git a/src/metrics.rs b/src/metrics.rs
index a7e8f11..9ae8ead 100644
--- a/src/metrics.rs
+++ b/src/metrics.rs
@@ -23,6 +23,7 @@ pub struct Metrics {
pub http_request: CounterVec,
pub http_request_duration: HistogramVec,
pub run_duration: Gauge,
+ pub next_wakeup: Gauge,
pub git_operations: CounterVec,
pub db_query_duration: Histogram,
registry: Registry,
@@ -70,6 +71,11 @@ impl Metrics {
).unwrap();
registry.register(Box::new(run_duration.clone())).unwrap();
+ let next_wakeup = Gauge::with_opts(
+ Opts::new("vbump_next_wakeup_seconds", "Unix timestamp of next scheduled wakeup"),
+ ).unwrap();
+ registry.register(Box::new(next_wakeup.clone())).unwrap();
+
let git_operations = CounterVec::new(
Opts::new("vbump_git_operations_total", "Git commits/pushes (success/failure)"),
&["operation", "outcome"],
@@ -92,6 +98,7 @@ impl Metrics {
http_request,
http_request_duration,
run_duration,
+ next_wakeup,
git_operations,
db_query_duration,
registry,