[multipass] add cloud-init feed available (enable rpios repo)
This commit is contained in:
parent
293e35a4bf
commit
2049944eaf
|
|
@ -7,7 +7,6 @@
|
|||
# --clean Stop+delete+purge target VMs (by BASE-<number>, regardless of COUNT)
|
||||
# Distro selection:
|
||||
# --debian-13 Debian 13 only (sets IMAGE=$DEBIAN13_IMAGE_URL and BASE=deb13)
|
||||
# --debian-13 Debian 13 only (sets IMAGE=$DEBIAN13_IMAGE_URL and BASE=deb13)
|
||||
# --both-distros Run Ubuntu + Debian 13 in parallel: COUNT=N => 2N VMs (default order: interleaved)
|
||||
# --first-ubuntu (with --both-distros) order: all Ubuntu first, then all Debian
|
||||
# --first-debian (with --both-distros) order: all Debian first, then all Ubuntu
|
||||
|
|
@ -16,6 +15,11 @@
|
|||
# --pr 4122 (repeatable) add PR numbers passed to install.txt
|
||||
# --run-pr 4122 same as --pr but also forces --run (alias: --test-pr)
|
||||
#
|
||||
# Cloud-init:
|
||||
# --cloud-init FILE Apply cloud-init FILE to all VMs (Ubuntu + Debian)
|
||||
# --cloud-init-rpios Apply RaspberryPiOS-style cloud-init only to Debian side
|
||||
# (alias of --debian-13, but sets Debian BASE=rpios-d13)
|
||||
#
|
||||
# Env vars:
|
||||
# IIAB_PR="4122 4191" Space-separated PRs
|
||||
# (compat) IIAB_INSTALL_ARGS If set, used as fallback for IIAB_PR
|
||||
|
|
@ -34,12 +38,21 @@
|
|||
set -euo pipefail
|
||||
|
||||
DPKG_ARCH="$(dpkg --print-architecture)"
|
||||
|
||||
# Resolve paths relative to this script (so cloud-init files work from any cwd)
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Debian 13 (Trixie) official cloud image (qcow2). Multipass can launch from URL/file:// on Linux.
|
||||
# Source: Debian cloud images live under cloud.debian.org/images/cloud/ ('genericcloud' includes cloud-init).
|
||||
DEBIAN13_IMAGE_URL="${DEBIAN13_IMAGE_URL:-https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-${DPKG_ARCH}.qcow2}"
|
||||
|
||||
IMAGE="${IMAGE:-24.04}"
|
||||
BASE="${BASE:-ubu2404}"
|
||||
# cloud-init controls
|
||||
CLOUD_INIT_FILE="${CLOUD_INIT_FILE:-}"
|
||||
RPIOS_CLOUD_INIT_FILE="${RPIOS_CLOUD_INIT_FILE:-$SCRIPT_DIR/cloud-init-rpios-like-arm64.yaml}"
|
||||
DEB_CLOUD_INIT_FILE="${DEB_CLOUD_INIT_FILE:-}"
|
||||
RPIOS_MODE=0
|
||||
COUNT="${COUNT:-1}"
|
||||
[ "$DPKG_ARCH" = "arm64" ] && CPUS="${CPUS:-2}" # SBC don't have spare CPUs.
|
||||
[ "$DPKG_ARCH" = "amd64" ] && CPUS="${CPUS:-3}"
|
||||
|
|
@ -91,6 +104,10 @@ Image shortcuts:
|
|||
--first-ubuntu With --both-distros: run all Ubuntu first, then Debian
|
||||
--first-debian With --both-distros: run all Debian first, then Ubuntu
|
||||
|
||||
Cloud-init:
|
||||
--cloud-init FILE Apply FILE to all VMs
|
||||
--cloud-init-rpios Apply rpios cloud-init only to Debian side; BASE=rpios-d13 (Debian)
|
||||
|
||||
PR options:
|
||||
--pr N Add PR number (repeatable)
|
||||
--run-pr N Add PR number and force --run
|
||||
|
|
@ -111,12 +128,25 @@ while [[ $# -gt 0 ]]; do
|
|||
--first-ubuntu) FIRST_UBUNTU=1; shift ;;
|
||||
--first-debian) FIRST_DEBIAN=1; shift ;;
|
||||
|
||||
--cloud-init)
|
||||
[[ $# -lt 2 ]] && { echo "[ERROR] --cloud-init needs a file path"; exit 2; }
|
||||
CLOUD_INIT_FILE="$2"; shift 2 ;;
|
||||
|
||||
--debian-13)
|
||||
DEBIAN13_ONLY=1
|
||||
IMAGE="$DEBIAN13_IMAGE_URL"
|
||||
BASE="deb13"
|
||||
shift ;;
|
||||
|
||||
--cloud-init-rpios)
|
||||
# Debian-only rpios flavor: also implies Debian 13 selection
|
||||
DEBIAN13_ONLY=1
|
||||
RPIOS_MODE=1
|
||||
IMAGE="$DEBIAN13_IMAGE_URL"
|
||||
BASE="rpios-d13"
|
||||
DEB_CLOUD_INIT_FILE="$RPIOS_CLOUD_INIT_FILE"
|
||||
shift ;;
|
||||
|
||||
--module)
|
||||
[[ $# -lt 2 ]] && { echo "[ERROR] --module needs a value"; exit 2; }
|
||||
modules+=("$2"); shift 2 ;;
|
||||
|
|
@ -139,7 +169,7 @@ while [[ $# -gt 0 ]]; do
|
|||
esac
|
||||
done
|
||||
|
||||
# ---- Incoherency checks (fail fast) ----
|
||||
# Incoherency checks (fail fast)
|
||||
if [[ "$FIRST_UBUNTU" == "1" && "$FIRST_DEBIAN" == "1" ]]; then
|
||||
echo "[ERROR] Incoherent options: --first-ubuntu and --first-debian cannot be used together."
|
||||
exit 2
|
||||
|
|
@ -149,7 +179,31 @@ if [[ ( "$FIRST_UBUNTU" == "1" || "$FIRST_DEBIAN" == "1" ) && "$BOTH_DISTROS" !=
|
|||
echo "[ERROR] --first-ubuntu/--first-debian requires --both-distros."
|
||||
exit 2
|
||||
fi
|
||||
# ----
|
||||
|
||||
if (( COUNT < 1 )); then
|
||||
echo "[ERROR] COUNT must be >= 1" >&2
|
||||
exit 2
|
||||
fi
|
||||
# ---
|
||||
|
||||
# Fail-fast validation for cloud-init files
|
||||
if [[ -n "${CLOUD_INIT_FILE:-}" && ! -f "$CLOUD_INIT_FILE" ]]; then
|
||||
echo "[ERROR] --cloud-init file not found on host: $CLOUD_INIT_FILE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ -n "${DEB_CLOUD_INIT_FILE:-}" && ! -f "$DEB_CLOUD_INIT_FILE" ]]; then
|
||||
echo "[ERROR] Debian cloud-init file not found on host: $DEB_CLOUD_INIT_FILE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# RPiOS flavor is meant for arm64 (rpios-like). Fail fast to avoid surprising runs.
|
||||
if [[ "$RPIOS_MODE" == "1" && "$DPKG_ARCH" != "arm64" ]]; then
|
||||
echo "[ERROR] --cloud-init-rpios is intended for arm64 hosts (detected: $DPKG_ARCH)." >&2
|
||||
echo " If you really want to run it on non-arm64, pass a normal --cloud-init FILE instead." >&2
|
||||
exit 2
|
||||
fi
|
||||
# ---
|
||||
|
||||
# Default module
|
||||
if [[ "${#modules[@]}" -eq 0 ]]; then
|
||||
|
|
@ -169,6 +223,7 @@ if [[ "$BOTH_DISTROS" == "1" ]]; then
|
|||
UBU_BASE="$UBU_BASE_ORIG"
|
||||
DEB_IMAGE="$DEBIAN13_IMAGE_URL"
|
||||
DEB_BASE="deb13"
|
||||
[[ "$RPIOS_MODE" == "1" ]] && DEB_BASE="rpios-d13"
|
||||
else
|
||||
UBU_IMAGE="$IMAGE"
|
||||
UBU_BASE="$BASE"
|
||||
|
|
@ -214,12 +269,13 @@ wait_all() {
|
|||
# Escape BASE for regex usage
|
||||
re_escape() { printf '%s' "$1" | sed -e 's/[].[^$*+?(){}|\\]/\\&/g'; }
|
||||
|
||||
declare -A VM_IMAGE
|
||||
declare -A VM_IMAGE VM_CLOUD_INIT
|
||||
names=()
|
||||
|
||||
build_vm_lists() {
|
||||
names=()
|
||||
VM_IMAGE=()
|
||||
VM_CLOUD_INIT=()
|
||||
|
||||
if [[ "$BOTH_DISTROS" == "1" ]]; then
|
||||
if [[ "$FIRST_UBUNTU" == "1" ]]; then
|
||||
|
|
@ -228,11 +284,13 @@ build_vm_lists() {
|
|||
local u="${UBU_BASE}-${n}"
|
||||
names+=("$u")
|
||||
VM_IMAGE["$u"]="$UBU_IMAGE"
|
||||
VM_CLOUD_INIT["$u"]="$CLOUD_INIT_FILE"
|
||||
done
|
||||
for n in $(seq 0 $((COUNT-1))); do
|
||||
local d="${DEB_BASE}-${n}"
|
||||
names+=("$d")
|
||||
VM_IMAGE["$d"]="$DEB_IMAGE"
|
||||
VM_CLOUD_INIT["$d"]="${DEB_CLOUD_INIT_FILE:-$CLOUD_INIT_FILE}"
|
||||
done
|
||||
|
||||
elif [[ "$FIRST_DEBIAN" == "1" ]]; then
|
||||
|
|
@ -241,11 +299,13 @@ build_vm_lists() {
|
|||
local d="${DEB_BASE}-${n}"
|
||||
names+=("$d")
|
||||
VM_IMAGE["$d"]="$DEB_IMAGE"
|
||||
VM_CLOUD_INIT["$d"]="${DEB_CLOUD_INIT_FILE:-$CLOUD_INIT_FILE}"
|
||||
done
|
||||
for n in $(seq 0 $((COUNT-1))); do
|
||||
local u="${UBU_BASE}-${n}"
|
||||
names+=("$u")
|
||||
VM_IMAGE["$u"]="$UBU_IMAGE"
|
||||
VM_CLOUD_INIT["$u"]="$CLOUD_INIT_FILE"
|
||||
done
|
||||
|
||||
else
|
||||
|
|
@ -256,6 +316,8 @@ build_vm_lists() {
|
|||
names+=("$u" "$d")
|
||||
VM_IMAGE["$u"]="$UBU_IMAGE"
|
||||
VM_IMAGE["$d"]="$DEB_IMAGE"
|
||||
VM_CLOUD_INIT["$u"]="$CLOUD_INIT_FILE"
|
||||
VM_CLOUD_INIT["$d"]="${DEB_CLOUD_INIT_FILE:-$CLOUD_INIT_FILE}"
|
||||
done
|
||||
fi
|
||||
else
|
||||
|
|
@ -263,6 +325,11 @@ build_vm_lists() {
|
|||
local vm="${BASE}-${n}"
|
||||
names+=("$vm")
|
||||
VM_IMAGE["$vm"]="$IMAGE"
|
||||
if [[ "$DEBIAN13_ONLY" == "1" ]]; then
|
||||
VM_CLOUD_INIT["$vm"]="${DEB_CLOUD_INIT_FILE:-$CLOUD_INIT_FILE}"
|
||||
else
|
||||
VM_CLOUD_INIT["$vm"]="$CLOUD_INIT_FILE"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
|
@ -320,14 +387,20 @@ cleanup_vms() {
|
|||
launch_one() {
|
||||
local vm="$1"
|
||||
local img="${VM_IMAGE[$vm]:-}"
|
||||
[[ -z "$img" ]] && { echo "[ERROR] No image mapping for VM '$vm'"; return 2; }
|
||||
[[ -n "$img" ]] || { echo "[ERROR] No image mapping for VM '$vm'"; return 2; }
|
||||
|
||||
# Cloud-init file to apply (already validated earlier in fail-fast checks)
|
||||
local ci="${VM_CLOUD_INIT[$vm]:-}"
|
||||
local -a ci_args=()
|
||||
[[ -n "${ci:-}" ]] && ci_args=(--cloud-init "$ci")
|
||||
|
||||
if vm_exists "$vm"; then
|
||||
echo "[INFO] VM already exists: $vm"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "[INFO] Launching $vm ..."
|
||||
multipass launch "$img" -n "$vm" -c "$CPUS" -m "$MEM" -d "$DISK" >/dev/null
|
||||
multipass launch "$img" -n "$vm" -c "$CPUS" -m "$MEM" -d "$DISK" "${ci_args[@]}" >/dev/null
|
||||
}
|
||||
|
||||
run_install_txt() {
|
||||
|
|
@ -337,6 +410,14 @@ run_install_txt() {
|
|||
log="$LOGROOT/${vm}.install.${t}.log"
|
||||
rc="$LOGROOT/${vm}.install.${t}.rc"
|
||||
|
||||
echo "[INFO] Waiting for VM readiness before install: $vm"
|
||||
if ! wait_for_vm "$vm"; then
|
||||
echo "[ERROR] VM did not become ready in time (install phase): $vm"
|
||||
echo "88" >"$rc"
|
||||
set_latest_links "$vm" "install" "$log" "$rc"
|
||||
return 88
|
||||
fi
|
||||
|
||||
echo "[INFO] install.txt in $vm (log $(basename "$log")) ..."
|
||||
|
||||
local modules_str pr_str
|
||||
|
|
@ -423,7 +504,7 @@ run_install_txt() {
|
|||
|
||||
resume_iiab() {
|
||||
local vm="$1"
|
||||
local do_long_wait="$2" # 1 => wait_for_vm (only for first auto-resume), 0 => no long wait
|
||||
local do_long_wait="$2"
|
||||
local t log rc
|
||||
t="$(stamp)"
|
||||
log="$LOGROOT/${vm}.resume.${t}.log"
|
||||
|
|
@ -432,7 +513,7 @@ resume_iiab() {
|
|||
echo "[INFO] resume (iiab -f) in $vm (log $(basename "$log")) ..."
|
||||
|
||||
set +e
|
||||
{
|
||||
(
|
||||
multipass start "$vm" >/dev/null 2>&1 || true
|
||||
|
||||
if [[ "$do_long_wait" == "1" ]]; then
|
||||
|
|
@ -445,7 +526,6 @@ resume_iiab() {
|
|||
|
||||
# Retry on rc=255 (SSH connection dropped; often reboot/network restart during apt/upgrade)
|
||||
# Also neutralize apt-listchanges/pagers to avoid "Waiting for data..." stalls.
|
||||
local attempt r
|
||||
r=1
|
||||
for attempt in $(seq 1 "$RESUME_TRIES"); do
|
||||
echo "[INFO] Resume attempt ${attempt}/${RESUME_TRIES} on $vm"
|
||||
|
|
@ -493,7 +573,7 @@ resume_iiab() {
|
|||
done
|
||||
|
||||
exit "$r"
|
||||
} >"$log" 2>&1
|
||||
) >"$log" 2>&1
|
||||
echo "$?" >"$rc"
|
||||
set -e
|
||||
|
||||
|
|
@ -510,9 +590,7 @@ summary() {
|
|||
[[ -f "$LOGROOT/latest.${vm}.install.rc" ]] && ir="$(cat "$LOGROOT/latest.${vm}.install.rc" 2>/dev/null || echo n/a)"
|
||||
[[ -f "$LOGROOT/latest.${vm}.resume.rc" ]] && rr="$(cat "$LOGROOT/latest.${vm}.resume.rc" 2>/dev/null || echo n/a)"
|
||||
|
||||
printf "%-12s %-8s %-8s %s\n" \
|
||||
"$vm" "$ir" "$rr" \
|
||||
"latest.${vm}.install.log / latest.${vm}.resume.log"
|
||||
printf "%-12s %-8s %-8s %s\n" "$vm" "$ir" "$rr" "latest.${vm}.install.log / latest.${vm}.resume.log"
|
||||
done
|
||||
|
||||
echo
|
||||
|
|
@ -561,7 +639,7 @@ pipeline_parallel_stagger() {
|
|||
run_install_txt "$vm"
|
||||
# Only Ubuntu tends to reboot during install; Debian often doesn't.
|
||||
local waitflag=1
|
||||
if [[ "${VM_IMAGE[$vm]}" == "$DEBIAN13_IMAGE_URL" ]]; then
|
||||
if [[ "$vm" == deb13-* || "$vm" == rpios-d13-* ]]; then
|
||||
waitflag=0
|
||||
fi
|
||||
resume_iiab "$vm" "$waitflag"
|
||||
|
|
|
|||
Loading…
Reference in New Issue