fix(deploy): identify agent images by build stamp, not image ID
The post-transfer verification added in bb34ef1 failed every deploy: it
compared `.Id` between build host and target, and a BuildKit image on the
build host carries attestation manifests that `docker save | docker load`
does not reproduce. The same build legitimately arrives with a different
Id and a different reported Size — tank had agent-base:dev at 28 MB /
363f23b7, gw-04 at 74 MB / edd46f95, both from the identical build.
`.Created` comes from the config blob, survives the round trip unchanged,
and is what actually answers "is the new build here". Both hosts reported
2026-08-02T16:43:00.599937575-07:00, which is how the false positive was
identified rather than assumed.
The verification itself stays — the truncation it guards against is real.
This corrects what it compares.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ec85f6c8da
commit
2380c2cb0b
+15
-8
@@ -51,24 +51,31 @@ load() {
|
|||||||
# truncated stream can still leave a partially-populated image, and shipping a
|
# truncated stream can still leave a partially-populated image, and shipping a
|
||||||
# corrupt agent image to every fleet node is worse than failing the deploy.
|
# corrupt agent image to every fleet node is worse than failing the deploy.
|
||||||
# One retry, because the observed failure is a transient stream stall.
|
# One retry, because the observed failure is a transient stream stall.
|
||||||
|
#
|
||||||
|
# Identity is the image's `Created` stamp, NOT its `Id`. A BuildKit image on
|
||||||
|
# the build host carries attestation manifests that `docker save | docker load`
|
||||||
|
# does not reproduce, so the same build legitimately arrives with a different
|
||||||
|
# Id and a different reported Size — comparing Ids fails every transfer of a
|
||||||
|
# correctly-shipped image. `Created` comes from the config blob, survives the
|
||||||
|
# round trip, and is what actually answers "is the new build here".
|
||||||
load_if_changed() {
|
load_if_changed() {
|
||||||
local lid rid attempt
|
local lts rts attempt
|
||||||
lid=$(ssh "$BUILD_HOST" "docker image inspect -f '{{.Id}}' $1 2>/dev/null" || true)
|
lts=$(ssh "$BUILD_HOST" "docker image inspect -f '{{.Created}}' $1 2>/dev/null" || true)
|
||||||
rid=$(ssh "$2" "docker image inspect -f '{{.Id}}' $1 2>/dev/null" || true)
|
rts=$(ssh "$2" "docker image inspect -f '{{.Created}}' $1 2>/dev/null" || true)
|
||||||
if [ -n "$lid" ] && [ "$lid" = "$rid" ]; then
|
if [ -n "$lts" ] && [ "$lts" = "$rts" ]; then
|
||||||
echo " (unchanged — skip)"
|
echo " (unchanged — skip)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
for attempt in 1 2; do
|
for attempt in 1 2; do
|
||||||
load "$1" "$2" || echo " (transfer attempt $attempt failed)"
|
load "$1" "$2" || echo " (transfer attempt $attempt failed)"
|
||||||
rid=$(ssh "$2" "docker image inspect -f '{{.Id}}' $1 2>/dev/null" || true)
|
rts=$(ssh "$2" "docker image inspect -f '{{.Created}}' $1 2>/dev/null" || true)
|
||||||
if [ -n "$lid" ] && [ "$lid" = "$rid" ]; then
|
if [ -n "$lts" ] && [ "$lts" = "$rts" ]; then
|
||||||
[ "$attempt" -gt 1 ] && echo " (recovered on attempt $attempt)"
|
[ "$attempt" -gt 1 ] && echo " (recovered on attempt $attempt)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
echo " (image ID mismatch after attempt $attempt — retrying)" >&2
|
echo " (build stamp mismatch after attempt $attempt — retrying)" >&2
|
||||||
done
|
done
|
||||||
echo " ✗ $1 did not land on $2 (wanted ${lid:0:19}, got ${rid:0:19})" >&2
|
echo " ✗ $1 did not land on $2 (wanted $lts, got ${rts:-nothing})" >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user