- autoinstall: dead mirror + fallback offline-install, so the installed base is exactly the ISO's; late-commands run offline-apt-install.sh on CIDATA packages/ (local apt repo, one transaction, errors fail the install, log /var/log/offline-apt-install.log); first boot no longer runs dpkg -i; real archive sources written back at the end. - download-packages.sh --iso: unpacks the ISO's default install source into a docker image (pxe-iso-base:<version>) and downloads there: all updates of the base, the explicit list (zip included) and the newest pool packages with their closure; writes Packages + explicit.list and checks the set offline in a fresh base container (--network none). - offline-apt-install.sh: new; also used by that check (--simulate). - build-usb.sh: ships Packages, explicit.list and the script; refuses a set without them. - tests/vm: pxetest-client-nosb (Secure Boot off, e1000e, SATA), one client at a time.
119 lines
4.9 KiB
Bash
Executable File
119 lines
4.9 KiB
Bash
Executable File
# shellcheck shell=bash disable=SC2034
|
|
# Shared settings for the pxetest VM harness. Sourced, not run.
|
|
#
|
|
# Everything this harness creates is named pxetest-*: the two domains, the
|
|
# isolated network, and the volumes in the libvirt 'default' pool. Nothing
|
|
# else is touched.
|
|
|
|
set -euo pipefail
|
|
|
|
VM_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$VM_DIR/../.." && pwd)"
|
|
|
|
export LIBVIRT_DEFAULT_URI="${LIBVIRT_DEFAULT_URI:-qemu:///system}"
|
|
|
|
# Download / build cache (ISO, USB image, extracted helper tools).
|
|
PXETEST_CACHE="${PXETEST_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/pxetest}"
|
|
|
|
# Where the gitignored payload dirs (offline-packages/, pip-wheels/,
|
|
# boot-files/, boot-tools/, enrollment/, ...) live. Defaults to this repo;
|
|
# point it at the main checkout when running from a worktree.
|
|
PXETEST_PAYLOAD_ROOT="${PXETEST_PAYLOAD_ROOT:-$REPO_ROOT}"
|
|
|
|
# Ubuntu ISO
|
|
UBUNTU_SERIES="${UBUNTU_SERIES:-24.04}"
|
|
UBUNTU_ISO_NAME="${UBUNTU_ISO_NAME:-ubuntu-24.04.5-live-server-amd64.iso}"
|
|
UBUNTU_RELEASE_URL="${UBUNTU_RELEASE_URL:-https://releases.ubuntu.com/$UBUNTU_SERIES}"
|
|
UBUNTU_ISO="$PXETEST_CACHE/$UBUNTU_ISO_NAME"
|
|
|
|
USB_IMAGE="$PXETEST_CACHE/pxetest-usb.img"
|
|
|
|
# libvirt objects
|
|
POOL="default"
|
|
SERVER_VM="pxetest-server"
|
|
CLIENT_VM="pxetest-client"
|
|
IMAGING_NET="pxetest-imaging"
|
|
IMAGING_BRIDGE="virbr-pxetest"
|
|
GE_NET="default" # libvirt NAT, 192.168.122.0/24 = "GE/corp"
|
|
SERVER_DISK_VOL="pxetest-server.qcow2"
|
|
SERVER_DISK_SIZE="${SERVER_DISK_SIZE:-60G}"
|
|
USB_VOL="pxetest-usb.img"
|
|
CLIENT_DISK_VOL="pxetest-client.qcow2"
|
|
|
|
SERVER_MEM_MIB="${SERVER_MEM_MIB:-4096}"
|
|
CLIENT_MEM_MIB="${CLIENT_MEM_MIB:-2048}"
|
|
|
|
# Fixed MACs so the playbook's NIC pins can be written once for this site.
|
|
SERVER_GE_MAC="52:54:00:9e:10:01" # on 'default' NAT (GE/corp side)
|
|
SERVER_IMAGING_MAC="52:54:00:9e:10:02" # on pxetest-imaging (imaging side)
|
|
CLIENT_MAC="52:54:00:9e:10:03" # on pxetest-imaging only
|
|
# Second client: Secure Boot OFF, e1000e NIC and SATA disk (in-box WinPE
|
|
# drivers), so WinPE gets a network and startnet can map the shares.
|
|
CLIENT2_VM="pxetest-client-nosb"
|
|
CLIENT2_DISK_VOL="pxetest-client-nosb.qcow2"
|
|
CLIENT2_MAC="52:54:00:9e:10:04" # on pxetest-imaging only
|
|
|
|
log() { printf '[pxetest] %s\n' "$*"; }
|
|
die() { printf '[pxetest] ERROR: %s\n' "$*" >&2; exit 1; }
|
|
|
|
dom_exists() { virsh dominfo "$1" >/dev/null 2>&1; }
|
|
dom_state() { virsh domstate "$1" 2>/dev/null | head -1; }
|
|
net_exists() { virsh net-info "$1" >/dev/null 2>&1; }
|
|
# No "| grep -q" under pipefail: grep exits early, the writer gets SIGPIPE
|
|
# and the pipeline reads as failed even on a match.
|
|
net_active() { [ "$(virsh net-info "$1" 2>/dev/null | awk '/^Active:/{print $2}')" = "yes" ]; }
|
|
vol_exists() { virsh vol-info --pool "$POOL" "$1" >/dev/null 2>&1; }
|
|
|
|
# sfdisk and mtools are needed for image mode. If the host lacks them,
|
|
# extract the Ubuntu debs into the cache (no root, no install).
|
|
ensure_image_tools() {
|
|
local troot="$PXETEST_CACHE/tools/root"
|
|
if [ -d "$troot" ]; then
|
|
export PATH="$troot/usr/sbin:$troot/usr/bin:$PATH"
|
|
export LD_LIBRARY_PATH="$troot/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
fi
|
|
if command -v sfdisk >/dev/null 2>&1 && command -v mcopy >/dev/null 2>&1 \
|
|
&& sfdisk --version >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
log "sfdisk/mtools missing: extracting fdisk, libfdisk1, mtools debs into $troot"
|
|
mkdir -p "$PXETEST_CACHE/tools/debs" "$troot"
|
|
(cd "$PXETEST_CACHE/tools/debs" && apt-get download fdisk libfdisk1 mtools) \
|
|
|| die "apt-get download fdisk libfdisk1 mtools failed; install fdisk + mtools"
|
|
local d
|
|
for d in "$PXETEST_CACHE/tools/debs"/*.deb; do
|
|
dpkg-deb -x "$d" "$troot"
|
|
done
|
|
export PATH="$troot/usr/sbin:$troot/usr/bin:$PATH"
|
|
export LD_LIBRARY_PATH="$troot/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
|
|
if ! sfdisk --version >/dev/null || ! command -v mcopy >/dev/null; then
|
|
die "extracted sfdisk/mcopy do not run"
|
|
fi
|
|
}
|
|
|
|
# The imaging network must be fully isolated: no <forward>, no <ip>
|
|
# (so the host has no address on it and libvirt runs no DHCP there).
|
|
assert_imaging_isolated() {
|
|
local xml
|
|
xml=$(virsh net-dumpxml "$IMAGING_NET")
|
|
if grep -q '<forward' <<<"$xml" || grep -q '<ip' <<<"$xml"; then
|
|
die "$IMAGING_NET has a <forward> or <ip> element: NOT isolated. Run destroy.sh and create.sh."
|
|
fi
|
|
local v4
|
|
v4=$(ip -4 -o addr show dev "$IMAGING_BRIDGE" 2>/dev/null || true)
|
|
if [ -n "$v4" ]; then
|
|
die "host has an IPv4 address on $IMAGING_BRIDGE: NOT isolated"
|
|
fi
|
|
# The bridge must hold only libvirt tap devices (vnetN), never a
|
|
# physical port.
|
|
local port
|
|
for port in /sys/class/net/"$IMAGING_BRIDGE"/brif/*; do
|
|
[ -e "$port" ] || continue
|
|
port=$(basename "$port")
|
|
case "$port" in
|
|
vnet*) ;;
|
|
*) die "$IMAGING_BRIDGE has non-tap port $port: NOT isolated" ;;
|
|
esac
|
|
done
|
|
}
|