110 lines
4.1 KiB
Bash
Executable File
110 lines
4.1 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
PRE15_LIB_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/lib" && pwd -P)
|
|
PRE15_QEMU_SCRIPT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)/run-qemu.sh
|
|
export PRE15_LIB_DIR PRE15_QEMU_SCRIPT
|
|
. "$PRE15_LIB_DIR/runner.sh"
|
|
. "$PRE15_LIB_DIR/manifest.sh"
|
|
|
|
pre15_pick_port()
|
|
{
|
|
python3 - <<'PY'
|
|
import socket
|
|
|
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
|
sock.bind(("127.0.0.1", 0))
|
|
print(sock.getsockname()[1])
|
|
PY
|
|
}
|
|
|
|
pre15_wait_for_ssh()
|
|
{
|
|
pre15_ssh_wait=0
|
|
while test "$pre15_ssh_wait" -lt "${PRE15_QEMU_BOOT_TIMEOUT:-180}"; do
|
|
if ! kill -0 "$PRE15_QEMU_PID" 2>/dev/null; then
|
|
pre15_infra_blocked 'QEMU exited before SSH became ready'
|
|
fi
|
|
if pre15_guest_ssh true >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
pre15_ssh_wait=$((pre15_ssh_wait + 1))
|
|
done
|
|
pre15_infra_blocked 'guest SSH did not become ready before the boot deadline'
|
|
}
|
|
|
|
pre15_qemu_worker()
|
|
{
|
|
pre15_qemu_case=$1
|
|
pre15_require_paths
|
|
pre15_qemu_case_script=$(pre15_find_case "$pre15_qemu_case")
|
|
: "${PRE15_QEMU_BASE_IMAGE:?PRE15_QEMU_BASE_IMAGE is required}"
|
|
: "${PRE15_QEMU_SSH_KEY:?PRE15_QEMU_SSH_KEY is required}"
|
|
PRE15_QEMU_SSH_USER=${PRE15_QEMU_SSH_USER:-root}
|
|
PRE15_QEMU_BASE_FORMAT=${PRE15_QEMU_BASE_FORMAT:-qcow2}
|
|
export PRE15_QEMU_SSH_USER PRE15_QEMU_BASE_FORMAT
|
|
for pre15_qemu_tool in qemu-img qemu-system-x86_64 ssh; do
|
|
command -v "$pre15_qemu_tool" >/dev/null 2>&1 || \
|
|
pre15_infra_blocked "missing QEMU runner tool: $pre15_qemu_tool"
|
|
done
|
|
test -f "$PRE15_QEMU_SSH_KEY" || \
|
|
pre15_infra_blocked "SSH key is absent: $PRE15_QEMU_SSH_KEY"
|
|
pre15_own_base_image "$PRE15_QEMU_BASE_IMAGE"
|
|
pre15_qemu_overlay=$PRE15_RUN_DIR/guest-overlay.qcow2
|
|
qemu-img create -f qcow2 -F "$PRE15_QEMU_BASE_FORMAT" \
|
|
-b "$PRE15_QEMU_BASE_IMAGE" "$pre15_qemu_overlay"
|
|
pre15_own_path "$pre15_qemu_overlay" 'QEMU overlay'
|
|
PRE15_QEMU_SSH_PORT=$(pre15_pick_port)
|
|
export PRE15_QEMU_SSH_PORT
|
|
pre15_own_port "$PRE15_QEMU_SSH_PORT" 'QEMU SSH forwarding'
|
|
PRE15_QEMU_CONTROL_PATH=$PRE15_RUN_DIR/ssh-control
|
|
PRE15_QEMU_SERIAL=$PRE15_RUN_DIR/serial.log
|
|
PRE15_QEMU_DEBUG=$PRE15_RUN_DIR/qemu.log
|
|
export PRE15_QEMU_CONTROL_PATH PRE15_QEMU_SERIAL PRE15_QEMU_DEBUG
|
|
pre15_write_argv_json "$PRE15_RUN_DIR/qemu-argv.json" \
|
|
qemu-system-x86_64 -accel tcg,thread=multi -cpu qemu64 \
|
|
-m "${PRE15_QEMU_MEMORY_MB:-6144}" -smp "${PRE15_QEMU_CPUS:-4}" \
|
|
-drive "file=$pre15_qemu_overlay,if=virtio,format=qcow2" \
|
|
-netdev "user,id=net0,hostfwd=tcp:127.0.0.1:$PRE15_QEMU_SSH_PORT-:22" \
|
|
-device virtio-net-pci,netdev=net0 -display none \
|
|
-serial "file:$PRE15_QEMU_SERIAL" -monitor none
|
|
qemu-system-x86_64 -accel tcg,thread=multi -cpu qemu64 \
|
|
-m "${PRE15_QEMU_MEMORY_MB:-6144}" -smp "${PRE15_QEMU_CPUS:-4}" \
|
|
-drive "file=$pre15_qemu_overlay,if=virtio,format=qcow2" \
|
|
-netdev "user,id=net0,hostfwd=tcp:127.0.0.1:$PRE15_QEMU_SSH_PORT-:22" \
|
|
-device virtio-net-pci,netdev=net0 -display none \
|
|
-serial "file:$PRE15_QEMU_SERIAL" -monitor none &
|
|
PRE15_QEMU_PID=$!
|
|
export PRE15_QEMU_PID
|
|
pre15_own_pid "$PRE15_QEMU_PID" QEMU
|
|
pre15_wait_for_ssh
|
|
if ssh -MNf -o BatchMode=yes -o StrictHostKeyChecking=no \
|
|
-o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 \
|
|
-o ControlMaster=yes -o "ControlPath=$PRE15_QEMU_CONTROL_PATH" \
|
|
-i "$PRE15_QEMU_SSH_KEY" -p "$PRE15_QEMU_SSH_PORT" \
|
|
"$PRE15_QEMU_SSH_USER@127.0.0.1"; then
|
|
pre15_own_ssh_control "$PRE15_QEMU_CONTROL_PATH" 'QEMU SSH ControlMaster'
|
|
else
|
|
pre15_infra_blocked 'could not establish SSH ControlMaster'
|
|
fi
|
|
pre15_guest_ssh_bounded uname -a > "$PRE15_RUN_DIR/guest-uname.txt"
|
|
pre15_guest_ssh_bounded kldstat > "$PRE15_RUN_DIR/guest-kldstat-before.txt"
|
|
pre15_guest_ssh_bounded dmesg > "$PRE15_RUN_DIR/guest-dmesg-before.txt"
|
|
/bin/sh "$pre15_qemu_case_script"
|
|
pre15_guest_ssh_bounded dmesg > "$PRE15_RUN_DIR/guest-dmesg-after.txt"
|
|
}
|
|
|
|
if test "${1:-}" = --worker; then
|
|
shift
|
|
test "$#" -eq 1 || pre15_fail_usage 'internal QEMU worker requires one case'
|
|
pre15_qemu_worker "$1"
|
|
exit 0
|
|
fi
|
|
|
|
test "$#" -eq 1 || pre15_fail_usage 'usage: run-qemu.sh CASE'
|
|
pre15_require_paths
|
|
pre15_find_case "$1" >/dev/null
|
|
pre15_run_command qemu "$1" "${PRE15_QEMU_TIMEOUT:-1200}" \
|
|
"$PRE15_QEMU_SCRIPT" --worker "$1"
|