fix(deploy): let a pinning failure explain itself
ci / lint-compose (push) Successful in 3s
ci / lint-actionlint (push) Successful in 1s
ci / lint-shellcheck (push) Successful in 2s
ci / lint-prettier (push) Successful in 3s
ci / lint-ruff (push) Successful in 1s
ci / lint-yaml (push) Successful in 3s
ci / lint-dockerfiles (push) Successful in 2s
ci / scan-deps (push) Successful in 15s
ci / test-backend (push) Successful in 6s
ci / test-frontend (push) Successful in 10s
ci / validate (push) Successful in 2s
renovate-ci / validate-renovate (push) Successful in 26s
ci / build (push) Successful in 1s

registry_digest was written to return an empty string for a ref the registry
does not have, so render_pinned could print "cannot resolve <ref>" and stop.
It could not do that. Every caller runs under set -euo pipefail, pipefail
reports the rightmost non-zero stage, and the failed docker manifest inspect
made the assignment itself fail, which set -e turns into an immediate exit.

render_pinned therefore died silently on the first unresolvable ref: nothing on
stderr, nothing on stdout, exit 1. The apply loop piped that empty stream into
kubectl, so the whole deploy stopped with "error: no objects passed to apply" -
kubectl guessing at a cause, with the actual reason nowhere in the log. The
missing message is the reason the f54589a run looked like a network death.

Reproduced against the old file with a docker stub that always fails: identical
to the ac0f845 log. The || true makes the empty string reachable, and the apply
loop now names the file that failed instead of letting kubectl speak.
This commit is contained in:
forust committed 2026-09-27 16:33:37 +02:00
1 parent ac0f845da6
commit 6a9a460769
1 file changed
+14 -4
+14 -4
View File
@@ -227,15 +227,19 @@ owned_registry_workloads() {
# mark every workload stale forever and restart the whole cluster on every deploy. # mark every workload stale forever and restart the whole cluster on every deploy.
registry_digest() { registry_digest() {
local arch local arch
arch="$(kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.architecture}' 2>/dev/null)" arch="$(kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.architecture}' 2>/dev/null || true)"
[ -n "$arch" ] || arch=amd64 [ -n "$arch" ] || arch=amd64
# The || true is load-bearing. Every caller runs under set -euo pipefail, and
# pipefail reports the rightmost non-zero stage, so a ref the registry does not
# have would abort the caller at the assignment instead of yielding an empty
# string. The callers check for empty themselves and report it by name.
docker manifest inspect "$1" 2>/dev/null \ docker manifest inspect "$1" 2>/dev/null \
| jq -r --arg arch "$arch" ' | jq -r --arg arch "$arch" '
.manifests[]? .manifests[]?
| select(.platform.os == "linux" and .platform.architecture == $arch) | select(.platform.os == "linux" and .platform.architecture == $arch)
| .digest | .digest
' 2>/dev/null \ ' 2>/dev/null \
| head -1 | head -1 || true
} }
# Rewrites our own images to immutable digests on the way into the cluster. # Rewrites our own images to immutable digests on the way into the cluster.
@@ -644,12 +648,18 @@ stage_apply_k8s() {
if [ "${#other_files[@]}" -gt 0 ]; then if [ "${#other_files[@]}" -gt 0 ]; then
log "Applying resources (${#other_files[@]} files, our images pinned to digests)" log "Applying resources (${#other_files[@]} files, our images pinned to digests)"
for m in "${other_files[@]}"; do for m in "${other_files[@]}"; do
render_pinned <"$m" | kubectl apply "${prune_opts[@]}" -f - if ! render_pinned <"$m" | kubectl apply "${prune_opts[@]}" -f -; then
echo "ERROR: apply failed for ${m#"$REPO"/}" >&2
exit 1
fi
done done
fi fi
for k in ${KUSTOMIZE_APPS[@]+"${KUSTOMIZE_APPS[@]}"}; do for k in ${KUSTOMIZE_APPS[@]+"${KUSTOMIZE_APPS[@]}"}; do
log "Applying kustomize app: ${k#"$REPO"/} (our images pinned to digests)" log "Applying kustomize app: ${k#"$REPO"/} (our images pinned to digests)"
kubectl kustomize "$k" | render_pinned | kubectl apply -f - if ! kubectl kustomize "$k" | render_pinned | kubectl apply -f -; then
echo "ERROR: apply failed for kustomize app ${k#"$REPO"/}" >&2
exit 1
fi
done done
if [ -f "$REPO/userbot/k8s/active" ]; then if [ -f "$REPO/userbot/k8s/active" ]; then
log "userbot panel hook" log "userbot panel hook"