fix(bootstrap): mirror the image batch under ONE docker start/stop
Live re-run: the per-image systemctl start/stop docker cycles tripped systemd's start rate limit after three fast pushes — "Start request repeated too quickly / start-limit-hit" — and the fourth image (the paper base) silently never reached the registry while the installer aborted. docker.service is socket-triggered, so every cycle counts against the burst limit twice. push_images_to_registry now starts docker once for the whole batch and stops it once at the end; push_image_to_registry itself no longer touches systemd. bootstrap_test.sh pins the wrap (exactly one start, one stop, four pushes).
This commit is contained in:
2 files changed
+26
-2
No files matched your search
+8
-2
@@ -2395,24 +2395,30 @@ push_image_to_registry() {
|
|||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
systemctl start docker
|
|
||||||
log "mirroring ${ref} into the internal registry"
|
log "mirroring ${ref} into the internal registry"
|
||||||
docker tag "$ref" "$push_ref" || die "could not tag ${ref} as ${push_ref} — is docker healthy?"
|
docker tag "$ref" "$push_ref" || die "could not tag ${ref} as ${push_ref} — is docker healthy?"
|
||||||
docker push "$push_ref" || die "could not mirror ${ref} into the internal registry — check the registry Deployment/pod and its PVC"
|
docker push "$push_ref" || die "could not mirror ${ref} into the internal registry — check the registry Deployment/pod and its PVC"
|
||||||
docker rmi "$push_ref" >/dev/null 2>&1 || true
|
docker rmi "$push_ref" >/dev/null 2>&1 || true
|
||||||
systemctl stop docker docker.socket 2>/dev/null || true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Every image this installer builds is hosted in the registry, so the copies it
|
# Every image this installer builds is hosted in the registry, so the copies it
|
||||||
# imported into containerd are a first-boot cache, not the only copy: kubelet
|
# imported into containerd are a first-boot cache, not the only copy: kubelet
|
||||||
# re-pulls from the registry after any image GC. Runs AFTER deploy_bundle — the
|
# re-pulls from the registry after any image GC. Runs AFTER deploy_bundle — the
|
||||||
# registry it pushes into does not exist before that.
|
# registry it pushes into does not exist before that.
|
||||||
|
#
|
||||||
|
# Docker is started once for the whole batch and stopped once at the end. A
|
||||||
|
# start/stop pair per image trips systemd's start rate limit — observed live on
|
||||||
|
# a re-run: three fast pushes, then "Start request repeated too quickly /
|
||||||
|
# start-limit-hit" and the fourth image never got mirrored. docker.service is
|
||||||
|
# socket-triggered, so each cycle counts twice against the burst limit.
|
||||||
push_images_to_registry() {
|
push_images_to_registry() {
|
||||||
local img
|
local img
|
||||||
|
systemctl start docker
|
||||||
for img in "$FELIS_IMAGE" "$FELIS_LIMBO_IMAGE" "$FELIS_LOBBY_IMAGE" "$FELIS_PAPER_IMAGE"; do
|
for img in "$FELIS_IMAGE" "$FELIS_LIMBO_IMAGE" "$FELIS_LOBBY_IMAGE" "$FELIS_PAPER_IMAGE"; do
|
||||||
[ -n "$img" ] || continue
|
[ -n "$img" ] || continue
|
||||||
push_image_to_registry "$img"
|
push_image_to_registry "$img"
|
||||||
done
|
done
|
||||||
|
systemctl stop docker docker.socket 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
# The login/lobby images use mutable :demo tags. Importing/pushing a replacement
|
# The login/lobby images use mutable :demo tags. Importing/pushing a replacement
|
||||||
|
|||||||
@@ -704,6 +704,24 @@ esac
|
|||||||
out="$(run_push registry.felis.svc:5000/felis/felis:demo 1)"
|
out="$(run_push registry.felis.svc:5000/felis/felis:demo 1)"
|
||||||
expect "a failed push fails the install loudly" "DIE: could not mirror" "$out"
|
expect "a failed push fails the install loudly" "DIE: could not mirror" "$out"
|
||||||
|
|
||||||
|
# docker must be started ONCE for the whole batch: a start/stop pair per image trips
|
||||||
|
# systemd's start rate limit ("start-limit-hit" — observed live; the 4th image was never
|
||||||
|
# mirrored because docker.service is socket-triggered and each cycle counts twice).
|
||||||
|
wiblock="$(awk '/^push_images_to_registry\(\) \{/,/^}/' "$BS")"
|
||||||
|
[ -n "$wiblock" ] || { echo "FAIL: no push_images_to_registry found in $BS"; exit 1; }
|
||||||
|
out="$(
|
||||||
|
FELIS_IMAGE=a FELIS_LIMBO_IMAGE=b FELIS_LOBBY_IMAGE=c FELIS_PAPER_IMAGE=d bash -c '
|
||||||
|
systemctl() { printf "SYSTEMCTL %s\n" "$*"; }
|
||||||
|
push_image_to_registry() { printf "PUSH %s\n" "$1"; }
|
||||||
|
'"$wiblock"'
|
||||||
|
push_images_to_registry'
|
||||||
|
)"
|
||||||
|
starts="$(printf '%s\n' "$out" | grep -c 'SYSTEMCTL start docker')"
|
||||||
|
stops="$(printf '%s\n' "$out" | grep -c 'SYSTEMCTL stop docker')"
|
||||||
|
[ "$starts" = 1 ] && [ "$stops" = 1 ] && [ "$(printf '%s\n' "$out" | grep -c '^PUSH')" = 4 ] \
|
||||||
|
&& echo "PASS the batch wraps all four pushes in ONE docker start/stop" \
|
||||||
|
|| { echo "FAIL: expected 1 start / 1 stop / 4 pushes, got:"; printf '%s\n' "$out"; fails=$((fails + 1)); }
|
||||||
|
|
||||||
# --- the registry's own image must not be re-pulled on every run --------------------------
|
# --- the registry's own image must not be re-pulled on every run --------------------------
|
||||||
iblock="$(awk '/^import_registry_image\(\) \{/,/^}/' "$BS")"
|
iblock="$(awk '/^import_registry_image\(\) \{/,/^}/' "$BS")"
|
||||||
[ -n "$iblock" ] || { echo "FAIL: no import_registry_image found in $BS"; exit 1; }
|
[ -n "$iblock" ] || { echo "FAIL: no import_registry_image found in $BS"; exit 1; }
|
||||||
|
|||||||
Reference in new issue
Block a user