From dfc8cf88e72956679e8bb199832c61abe8702a5b Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Fri, 30 Oct 2026 23:12:25 +0100 Subject: [PATCH] fix(cache): re-check every unpinned OCI tag on pull Only :latest was treated as floating; any other unpinned tag skipped the registry digest check, so a moved :v1.2 kept booting stale. Tags are mutable pointers, that is what digest pins exist for; the pin skip stays, the tag skip goes. --- crates/ecrou/src/cache.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/ecrou/src/cache.rs b/crates/ecrou/src/cache.rs index 59e4104..7185abe 100644 --- a/crates/ecrou/src/cache.rs +++ b/crates/ecrou/src/cache.rs @@ -17,10 +17,10 @@ use crate::progress::Progress; use crate::registry::fetch_oci_digest; use crate::Result; -/// Whether an OCI image with a floating tag (":latest") has moved since -/// it was cached: fetch the current manifest digest from the registry -/// and compare it against the digest stored from the last download. -/// Pinned tags are assumed immutable; a network error keeps the cache +/// Whether an OCI image with an unpinned tag has moved since it was +/// cached: fetch the current manifest digest from the registry and +/// compare it against the digest stored from the last download. A +/// digest pin is never checked; a network error keeps the cache /// rather than hard-failing; anything else is simply current. pub(crate) fn oci_freshness_changed(source: &ImageSource, cache_path: &Path) -> bool { if !cache_path.exists() { @@ -36,8 +36,10 @@ pub(crate) fn oci_freshness_changed(source: &ImageSource, cache_path: &Path) -> else { return false; }; - // A digest pin is immutable by definition; so is any non-latest tag. - if digest.is_some() || tag != "latest" { + // A digest pin is immutable by definition: the pin names the + // manifest. An unpinned tag is a mutable pointer — every one of + // them, not just ":latest" — so a pull re-checks them all. + if digest.is_some() { return false; } match fetch_oci_digest(registry, repository, tag) {