180 lines
4.7 KiB
Bash
Executable File
180 lines
4.7 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
: "${KUBE_IMG_CACHE:?KUBE_IMG_CACHE is required}"
|
|
: "${KUBE_VERSION:?KUBE_VERSION is required}"
|
|
: "${ARCH:?ARCH is required}"
|
|
: "${ROOTFS:?ROOTFS is required}"
|
|
|
|
OS=linux
|
|
|
|
# IMPORTANT:
|
|
# This must match what the target system will use at runtime.
|
|
# If your target CRI-O uses overlay, leave this as overlay.
|
|
# If overlay seeding fails in your build environment, fix the build env;
|
|
# do not silently switch to vfs unless the target will also use vfs.
|
|
STORAGE_DRIVER="${STORAGE_DRIVER:-overlay}"
|
|
|
|
# Optional. Needed by many overlay-in-container setups.
|
|
FUSE_OVERLAYFS="${FUSE_OVERLAYFS:-/usr/bin/fuse-overlayfs}"
|
|
|
|
# Optional extra images to include in addition to kubeadm's required images.
|
|
# Example:
|
|
# EXTRA_IMAGES=(
|
|
# "docker.io/library/busybox:1.36"
|
|
# "quay.io/cilium/cilium:v1.17.2"
|
|
# )
|
|
EXTRA_IMAGES=(
|
|
"${EXTRA_IMAGES[@]:-}"
|
|
"docker-daemon:monok8s/control-agent:$TAG"
|
|
)
|
|
|
|
# Keep archive cache version/arch scoped so downloads do not get mixed.
|
|
ARCHIVE_DIR="${KUBE_IMG_CACHE}/archives/${ARCH}/${KUBE_VERSION}"
|
|
|
|
# Seed directly into the target rootfs image store.
|
|
TARGET_GRAPHROOT="${ROOTFS}/usr/lib/monok8s/imagestore"
|
|
|
|
# Build-host temporary runtime state for containers/storage.
|
|
TMPDIR="$(mktemp -d)"
|
|
RUNROOT="${TMPDIR}/runroot"
|
|
STORAGE_CONF="${TMPDIR}/storage.conf"
|
|
|
|
cleanup() {
|
|
rm -rf "${TMPDIR}"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
mkdir -p "${ARCHIVE_DIR}"
|
|
mkdir -p "${TARGET_GRAPHROOT}"
|
|
mkdir -p "${RUNROOT}"
|
|
|
|
echo "============================================================"
|
|
echo "Preparing Kubernetes CRI-O image store"
|
|
echo " KUBE_VERSION = ${KUBE_VERSION}"
|
|
echo " ARCH = ${ARCH}"
|
|
echo " ARCHIVE_DIR = ${ARCHIVE_DIR}"
|
|
echo " TARGET_GRAPHROOT = ${TARGET_GRAPHROOT}"
|
|
echo " STORAGE_DRIVER = ${STORAGE_DRIVER}"
|
|
echo "============================================================"
|
|
|
|
# Build a temporary containers/storage config that writes directly into
|
|
# the target rootfs image store.
|
|
if [ "${STORAGE_DRIVER}" = "overlay" ]; then
|
|
cat > "${STORAGE_CONF}" <<EOF
|
|
[storage]
|
|
driver = "overlay"
|
|
runroot = "${RUNROOT}"
|
|
graphroot = "${TARGET_GRAPHROOT}"
|
|
|
|
[storage.options]
|
|
mount_program = "${FUSE_OVERLAYFS}"
|
|
EOF
|
|
else
|
|
cat > "${STORAGE_CONF}" <<EOF
|
|
[storage]
|
|
driver = "${STORAGE_DRIVER}"
|
|
runroot = "${RUNROOT}"
|
|
graphroot = "${TARGET_GRAPHROOT}"
|
|
EOF
|
|
fi
|
|
|
|
export CONTAINERS_STORAGE_CONF="${STORAGE_CONF}"
|
|
|
|
# Get kubeadm-required images.
|
|
mapfile -t kubeadm_images < <(
|
|
qemu-aarch64-static \
|
|
"${ROOTFS}/usr/local/bin/kubeadm" \
|
|
config images list \
|
|
--kubernetes-version "${KUBE_VERSION}"
|
|
)
|
|
|
|
if [ "${#kubeadm_images[@]}" -eq 0 ] && [ "${#EXTRA_IMAGES[@]}" -eq 0 ]; then
|
|
echo "No images to seed"
|
|
exit 1
|
|
fi
|
|
|
|
# Merge kubeadm images + EXTRA_IMAGES, preserving order and removing duplicates.
|
|
images=()
|
|
declare -A seen=()
|
|
|
|
for img in "${kubeadm_images[@]}" "${EXTRA_IMAGES[@]}"; do
|
|
[ -n "${img}" ] || continue
|
|
if [ -z "${seen[$img]+x}" ]; then
|
|
images+=("${img}")
|
|
seen["$img"]=1
|
|
fi
|
|
done
|
|
|
|
echo "Images to seed:"
|
|
for img in "${images[@]}"; do
|
|
echo " ${img}"
|
|
done
|
|
echo
|
|
|
|
for img in "${images[@]}"; do
|
|
[ -n "${img}" ] || continue
|
|
|
|
case "$img" in
|
|
docker-daemon:*)
|
|
SRC="$img"
|
|
IMG_REF="${img#docker-daemon:}"
|
|
USE_ARCHIVE=0
|
|
;;
|
|
docker://*)
|
|
SRC="$img"
|
|
IMG_REF="${img#docker://}"
|
|
USE_ARCHIVE=1
|
|
;;
|
|
oci-archive:*)
|
|
SRC="$img"
|
|
IMG_REF="${img#oci-archive:}"
|
|
USE_ARCHIVE=0
|
|
;;
|
|
*)
|
|
# Default behavior for non-prefixed refs:
|
|
# treat as remote registry image.
|
|
SRC="docker://${img}"
|
|
IMG_REF="$img"
|
|
USE_ARCHIVE=1
|
|
;;
|
|
esac
|
|
|
|
safe_name="$(printf '%s' "${IMG_REF}" | sed 's#/#_#g; s#:#__#g')"
|
|
archive="${ARCHIVE_DIR}/${safe_name}.tar"
|
|
|
|
if [ "${USE_ARCHIVE}" = "1" ]; then
|
|
if [ ! -f "${archive}" ]; then
|
|
echo "Caching archive: ${IMG_REF}"
|
|
skopeo copy \
|
|
--override-os "${OS}" \
|
|
--override-arch "${ARCH}" \
|
|
"${SRC}" \
|
|
"oci-archive:${archive}"
|
|
else
|
|
echo "Archive hit: ${IMG_REF}"
|
|
fi
|
|
SRC_FINAL="oci-archive:${archive}"
|
|
else
|
|
echo "Using direct source: ${SRC}"
|
|
SRC_FINAL="${SRC}"
|
|
fi
|
|
|
|
if skopeo inspect "containers-storage:${IMG_REF}" >/dev/null 2>&1; then
|
|
echo "Store hit: ${IMG_REF}"
|
|
continue
|
|
fi
|
|
|
|
echo "Seeding CRI-O store: ${IMG_REF}"
|
|
skopeo copy \
|
|
--override-os "${OS}" \
|
|
--override-arch "${ARCH}" \
|
|
"${SRC_FINAL}" \
|
|
"containers-storage:${IMG_REF}"
|
|
done
|
|
|
|
echo
|
|
echo "Done."
|
|
echo "Archives: ${ARCHIVE_DIR}"
|
|
echo "CRI-O storage: ${TARGET_GRAPHROOT}"
|