#!/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[@]}" # A literal `null` means the caller's yq filter matched a container that has # no `image:` field -- typically a strategic-merge pod-template fragment # inside a CR, which overrides a few fields and pulls nothing. Catch it here: # passed through, it becomes a container with an empty image and `kubectl # apply` rejects the DaemonSet by container index, naming neither the filter # nor the chart that produced it. for image in "${images[@]}"; do if [[ "$image" == "null" ]]; then echo "e2e-prepull-images: refusing a literal 'null' image reference." >&2 echo " Some container in the caller's yq filter has no 'image:' field." >&2 echo " Drop nulls at the source (see hack/e2e-install-cozystack.bats)." >&2 exit 1 fi done 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 - <