91 lines
4.0 KiB
Bash
Executable File
91 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# Test virtual machine for the built image (build/acpc2026.qcow2).
|
|
#
|
|
# tests/check_vm.sh start [--wrong-clock] [--usb] boot a throwaway copy
|
|
# tests/check_vm.sh stop power it off, delete the copy
|
|
#
|
|
# The copy (tests/work/check.qcow2) opens SSH for the tests: password login,
|
|
# no DenyGroups, and the firewall accepts tcp 22. The built image itself is
|
|
# not modified. --wrong-clock starts with the hardware clock 3 hours behind
|
|
# (as on a lab machine running Windows), --usb adds a USB controller so that
|
|
# USB devices can be plugged in with tests/usb.sh.
|
|
set -eu
|
|
cd "$(dirname "$0")/.."
|
|
W=tests/work
|
|
MON=$W/monitor.sock
|
|
BUILT=$(realpath build/acpc2026.qcow2)
|
|
running() { pgrep -f "^qemu-system-x86_64 -name acpc2026-check" >/dev/null; }
|
|
|
|
case "${1:-}" in
|
|
start)
|
|
shift
|
|
running && { echo "The test VM is already running." >&2; exit 1; }
|
|
mkdir -p "$W"
|
|
qemu-img create -q -f qcow2 -b "$BUILT" -F qcow2 "$W/check.qcow2"
|
|
for d in /usr/share/edk2/x64 /usr/share/OVMF /usr/share/edk2/ovmf; do
|
|
for c in OVMF_CODE.4m.fd OVMF_CODE_4M.fd OVMF_CODE.fd; do
|
|
[ -f "$d/$c" ] && { CODE=$d/$c; VARS=$d/${c/CODE/VARS}; break 2; }
|
|
done
|
|
done
|
|
cp "$VARS" "$W/vars.fd"
|
|
# Open SSH in the copy, offline
|
|
touch "$W/fuse.raw"
|
|
qemu-storage-daemon --blockdev driver=file,node-name=f,filename="$W/check.qcow2" \
|
|
--blockdev driver=qcow2,node-name=q,file=f \
|
|
--export type=fuse,id=e,node-name=q,mountpoint="$W/fuse.raw",writable=on > "$W/qsd.log" 2>&1 &
|
|
for _ in $(seq 1 20); do mountpoint -q "$W/fuse.raw" && break; sleep 0.5; done
|
|
start=$(sfdisk -J "$W/fuse.raw" | python3 -I -c 'import json,sys; p=json.load(sys.stdin)["partitiontable"]["partitions"]; print(max(p,key=lambda x:x["size"])["start"])')
|
|
D="$W/fuse.raw?offset=$((start * 512))"
|
|
printf 'PasswordAuthentication yes\n' > "$W/00-test.conf"
|
|
w() { debugfs -w -R "$1" "$D" >/dev/null 2>&1 || true; }
|
|
w "rm /etc/ssh/sshd_config.d/icpc.conf"
|
|
w "write $W/00-test.conf /etc/ssh/sshd_config.d/00-test.conf"
|
|
w "mkdir /etc/systemd/system/firewall.service.d"
|
|
w "write tests/test-ssh.conf /etc/systemd/system/firewall.service.d/test-ssh.conf"
|
|
for f in /etc/ssh/sshd_config.d/00-test.conf /etc/systemd/system/firewall.service.d/test-ssh.conf; do
|
|
for x in "mode 0100644" "uid 0" "gid 0"; do w "set_inode_field $f $x"; done
|
|
done
|
|
for x in "mode 040755" "uid 0" "gid 0"; do w "set_inode_field /etc/systemd/system/firewall.service.d $x"; done
|
|
fusermount3 -u "$W/fuse.raw"
|
|
pkill -f "^qemu-storage-daemon .*$W/check.qcow2" || true
|
|
sleep 1
|
|
EXTRA=()
|
|
for a in "$@"; do
|
|
case "$a" in
|
|
--wrong-clock) EXTRA+=(-rtc "base=$(date -u -d '-3 hours' +%Y-%m-%dT%H:%M:%S)") ;;
|
|
--usb) EXTRA+=(-device qemu-xhci,id=xhci) ;;
|
|
esac
|
|
done
|
|
setsid qemu-system-x86_64 -name acpc2026-check -machine q35,accel=kvm -cpu host -m 6144 -smp 4 \
|
|
-drive if=pflash,format=raw,readonly=on,file="$CODE" \
|
|
-drive if=pflash,format=raw,file="$W/vars.fd" \
|
|
-drive id=disk0,file="$W/check.qcow2",format=qcow2,if=none \
|
|
-device virtio-blk-pci,drive=disk0,bootindex=1 \
|
|
-netdev user,id=net0,hostfwd=tcp:127.0.0.1:2222-:22 -device virtio-net-pci,netdev=net0 \
|
|
-vga virtio -display none -monitor unix:"$MON",server,nowait \
|
|
-serial file:"$W/serial.log" "${EXTRA[@]}" > "$W/qemu.log" 2>&1 &
|
|
for _ in $(seq 1 120); do
|
|
tests/vssh.sh team true 2>/dev/null && break
|
|
sleep 3
|
|
done
|
|
# Wait for the desktop session of the team account
|
|
for _ in $(seq 1 60); do
|
|
tests/vssh.sh team 'loginctl list-sessions --no-legend' 2>/dev/null | grep -q seat0 && break
|
|
sleep 2
|
|
done
|
|
echo "Test VM ready (SSH 127.0.0.1:2222, monitor $MON)."
|
|
;;
|
|
stop)
|
|
if running; then
|
|
python3 -I tests/monitor.py "$MON" quit || true
|
|
for _ in $(seq 1 30); do running || break; sleep 1; done
|
|
fi
|
|
rm -rf "$W"
|
|
echo "Test VM stopped."
|
|
;;
|
|
*)
|
|
sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'
|
|
exit 2
|
|
;;
|
|
esac
|