#!/bin/sh set -eu umask 077 : "${NORDVPN_PACKAGE_PATH:?Set NORDVPN_PACKAGE_PATH to the package under test.}" : "${OPNSENSE_VM_IMAGE:?Set OPNSENSE_VM_IMAGE to the OPNsense qcow2 base image.}" : "${OPNSENSE_TRANSFER_IMAGE:?Set OPNSENSE_TRANSFER_IMAGE to the OPNsense transfer disk.}" script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) runtime_dir="$script_dir/.runtime" ui_port=${OPNSENSE_UI_PORT:-18443} test -r "$NORDVPN_PACKAGE_PATH" test -r "$OPNSENSE_VM_IMAGE" test -r "$OPNSENSE_TRANSFER_IMAGE" mkdir -p "$runtime_dir" rm -f "$runtime_dir/opnsense.qcow2" "$runtime_dir/serial.in" "$runtime_dir/serial.out" \ "$runtime_dir/serial.log" "$runtime_dir/transfer.img" mkfifo "$runtime_dir/serial.in" "$runtime_dir/serial.out" qemu-img create -q -f qcow2 -F qcow2 -b "$OPNSENSE_VM_IMAGE" "$runtime_dir/opnsense.qcow2" cp "$OPNSENSE_TRANSFER_IMAGE" "$runtime_dir/transfer.img" mcopy -o -i "$runtime_dir/transfer.img" "$NORDVPN_PACKAGE_PATH" ::os-nordvpn.pkg mcopy -o -i "$runtime_dir/transfer.img" "$script_dir/guest-setup.php" ::guest-setup.php cleanup() { set +e [ -n "${qemu_pid:-}" ] && kill "$qemu_pid" 2>/dev/null } trap cleanup EXIT INT TERM qemu-system-x86_64 \ -machine q35,accel=tcg \ -smp 2 \ -m 2048 \ -display none \ -monitor none \ -drive file="$runtime_dir/opnsense.qcow2",if=virtio,format=qcow2 \ -drive file="$runtime_dir/transfer.img",if=virtio,format=raw,readonly=on \ -netdev user,id=wan,net=192.168.1.0/24,dhcpstart=192.168.1.100,host=192.168.1.254,hostfwd=tcp:127.0.0.1:"$ui_port"-192.168.1.1:443 \ -device virtio-net-pci,netdev=wan \ -chardev pipe,id=console,path="$runtime_dir/serial" \ -serial chardev:console & qemu_pid=$! cat "$runtime_dir/serial.out" >> "$runtime_dir/serial.log" & wait_for() { pattern=$1 attempts=${2:-300} while ! grep -Fq "$pattern" "$runtime_dir/serial.log" 2>/dev/null; do attempts=$((attempts - 1)) [ "$attempts" -gt 0 ] || { echo "timed out waiting for: $pattern" >&2 exit 1 } sleep 1 done } send() { printf '%b' "$1" > "$runtime_dir/serial.in" } wait_for 'Autoboot in' 180 send ' ' sleep 1 send '2\n' wait_for 'Enter full pathname of shell' 180 send '\n' wait_for '# ' 60 send "mount -uw /\n" sleep 2 send "sh /etc/rc\n" wait_for 'root@OPNsense:/ #' 300 send "mount -o ro -t msdosfs /dev/vtbd1 /mnt && pkg add -f /mnt/os-nordvpn.pkg && php /mnt/guest-setup.php && umount /mnt && pfctl -d && echo UI_VM_READY\n" wait_for 'UI_VM_READY' 120 printf '%s\n' "OPNSENSE_UI_BASE_URL=https://127.0.0.1:$ui_port" wait "$qemu_pid"