#!/usr/bin/env bash # Pre-pull images to all cluster nodes. # # Reads image references from stdin, one per line. Empty lines and lines # starting with '#' are ignored. # # Some workloads (OVN raft, LINSTOR, cert-manager) are sensitive to slow or # staggered pulls at install time: a HelmRelease can time out while one node # is still pulling. Pre-pulling eliminates the stagger. # # Distroless images (cert-manager, etc.) ship no shell or `sleep`, so we # can't just `command: ["sleep", "infinity"]`. Trick: an initContainer copies # busybox (a static binary) into a shared emptyDir, then every prepull # container execs /shared/sleep — the kernel execve's the binary from the # volume, the container's filesystem doesn't need to provide it. set -euo pipefail cleanup() { kubectl delete daemonset e2e-image-prepuller -n kube-system --ignore-not-found } trap cleanup EXIT mapfile -t images < <(grep -Ev '^[[:space:]]*(#|$)' | sort -u) if [[ ${#images[@]} -eq 0 ]]; then echo "e2e-prepull-images: no images on stdin, nothing to do" >&2 exit 0 fi echo "Pre-pulling ${#images[@]} image(s):" printf ' %s\n' "${images[@]}" containers="" i=0 for image in "${images[@]}"; do containers+=" - name: pull-${i} image: ${image} command: [\"/shared/sleep\", \"infinity\"] imagePullPolicy: IfNotPresent volumeMounts: - name: bin mountPath: /shared resources: requests: cpu: 1m memory: 1Mi" i=$((i + 1)) done kubectl apply -f - <