Add scripts/run-qemu.sh
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env bash
|
||||
# ───────────────────────────────────────────────────────────
|
||||
# run-qemu.sh — Launch the Ansible Control Node VM
|
||||
#
|
||||
# Boots the minimal Alpine Linux VM with:
|
||||
# • Machine: pc-q35-10.0
|
||||
# • TTY: ttyS0, xterm-256color (serial console)
|
||||
# • Keyboard: PS/2 (atkbd via QEMU default)
|
||||
# • Network: user-mode NAT with port forwards:
|
||||
# localhost:2222 → VM:22 (SSH)
|
||||
# localhost:8080 → VM:8080 (custom services)
|
||||
# • Disk: virtio-blk, read from output/
|
||||
# • Init: OpenRC (no systemd)
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/run-qemu.sh # serial console (default)
|
||||
# ./scripts/run-qemu.sh --gui # graphical (GTK) window
|
||||
# ./scripts/run-qemu.sh --vnc :0 # VNC on display :0
|
||||
# ./scripts/run-qemu.sh --debug # verbose kernel boot
|
||||
#
|
||||
# Environment:
|
||||
# QEMU_MEMORY — RAM size (default: 1024M)
|
||||
# QEMU_SMP — CPU count (default: 2)
|
||||
# SSH_PORT — host port for SSH forward (default: 2222)
|
||||
#
|
||||
# Access the VM:
|
||||
# ssh -p 2222 ansible@localhost # password: ansible
|
||||
# ssh -p 2222 root@localhost # password: ansible
|
||||
#
|
||||
# Stop the VM:
|
||||
# Press Ctrl-A then X (in -nographic mode)
|
||||
# Or: sudo shutdown -h now (inside VM)
|
||||
# ───────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR/../output}"
|
||||
|
||||
# ── Configuration (env-overridable) ─────────────────────────
|
||||
QEMU_BIN="${QEMU_BIN:-qemu-system-x86_64}"
|
||||
QEMU_MACHINE="${QEMU_MACHINE:-pc-q35-10.0}"
|
||||
QEMU_MEMORY="${QEMU_MEMORY:-1024M}"
|
||||
QEMU_SMP="${QEMU_SMP:-2}"
|
||||
SSH_PORT="${SSH_PORT:-2222}"
|
||||
EXTRA_PORT="${EXTRA_PORT:-8090}"
|
||||
|
||||
# ── Colour helpers ──────────────────────────────────────────
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'; BOLD='\033[1m'; NC='\033[0m'
|
||||
info() { echo -e "${BLUE}[*]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[✓]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||
|
||||
# ── Find build artifacts ────────────────────────────────────
|
||||
# Prefer qcow2 over raw
|
||||
if [ -f "$OUTPUT_DIR/ansible-node.qcow2" ]; then
|
||||
DISK="$OUTPUT_DIR/ansible-node.qcow2"
|
||||
DISK_FMT="qcow2"
|
||||
elif [ -f "$OUTPUT_DIR/ansible-node.raw" ]; then
|
||||
DISK="$OUTPUT_DIR/ansible-node.raw"
|
||||
DISK_FMT="raw"
|
||||
else
|
||||
echo -e "${RED}[✗]${NC} No disk image found in ${OUTPUT_DIR}"
|
||||
echo " Run ./scripts/build-qemu.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KERNEL="$OUTPUT_DIR/vmlinuz-virt"
|
||||
INITRD="$OUTPUT_DIR/initramfs-virt"
|
||||
|
||||
for f in "$DISK" "$KERNEL" "$INITRD"; do
|
||||
if [ ! -f "$f" ]; then
|
||||
echo -e "${RED}[✗]${NC} Missing: $f"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Parse arguments ─────────────────────────────────────────
|
||||
DISPLAY_MODE="nographic"
|
||||
KERNEL_APPEND="root=/dev/vda console=ttyS0 TERM=xterm-256color quiet modules=virtio_blk,ext4 rootflags=rw"
|
||||
EXTRA_QEMU_ARGS=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--gui|-g)
|
||||
DISPLAY_MODE="gtk"
|
||||
;;
|
||||
--vnc)
|
||||
DISPLAY_MODE="vnc"
|
||||
VNC_DISPLAY="${2:-:0}"
|
||||
shift
|
||||
;;
|
||||
--debug)
|
||||
# Remove 'quiet', add verbose/delay for debugging
|
||||
KERNEL_APPEND="${KERNEL_APPEND// quiet/} debug_init rootdelay=3"
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--gui|--vnc :N|--debug] [extra qemu args...]"
|
||||
echo ""
|
||||
echo "Modes:"
|
||||
echo " (default) Serial console (-nographic), Ctrl-A X to exit"
|
||||
echo " --gui Graphical GTK window with keyboard support"
|
||||
echo " --vnc :N VNC server on display N"
|
||||
echo " --debug Verbose kernel boot messages"
|
||||
echo ""
|
||||
echo "Environment:"
|
||||
echo " QEMU_MEMORY=1024M RAM size"
|
||||
echo " QEMU_SMP=2 CPU count"
|
||||
echo " SSH_PORT=2222 Host SSH port"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
EXTRA_QEMU_ARGS+=("$1")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# ── Display mode flags ──────────────────────────────────────
|
||||
case "$DISPLAY_MODE" in
|
||||
nographic)
|
||||
DISPLAY_FLAG="-nographic"
|
||||
;;
|
||||
gtk)
|
||||
DISPLAY_FLAG="-display gtk"
|
||||
# QEMU's GTK display includes keyboard support via PS/2 emulation
|
||||
# which covers the CONFIG_KEYBOARD_ATKBD kernel requirement
|
||||
;;
|
||||
vnc)
|
||||
DISPLAY_FLAG="-vnc ${VNC_DISPLAY} -vga virtio"
|
||||
KERNEL_APPEND="$KERNEL_APPEND video=1024x768"
|
||||
;;
|
||||
esac
|
||||
|
||||
# ── Launch ──────────────────────────────────────────────────
|
||||
echo ""
|
||||
echo -e "${BOLD}══════════════════════════════════════════════${NC}"
|
||||
echo -e "${BOLD} Ansible Control Node${NC}"
|
||||
echo -e "${BOLD}══════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e " Machine: ${GREEN}${QEMU_MACHINE}${NC}"
|
||||
echo -e " Memory: ${GREEN}${QEMU_MEMORY}${NC}"
|
||||
echo -e " CPUs: ${GREEN}${QEMU_SMP}${NC}"
|
||||
echo -e " Disk: ${GREEN}${DISK_FMT}:${DISK}${NC}"
|
||||
echo -e " Display: ${GREEN}${DISPLAY_MODE}${NC}"
|
||||
echo -e " Kernel: ${KERNEL_APPEND}"
|
||||
echo ""
|
||||
echo -e " SSH: ${YELLOW}ssh -p ${SSH_PORT} ansible@localhost${NC}"
|
||||
echo -e " Password: ${YELLOW}ansible${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}Ctrl-A X${NC} to quit (serial mode)"
|
||||
echo -e " ${BOLD}Ctrl-C${NC} to force-quit (any mode)"
|
||||
echo ""
|
||||
|
||||
# Build netdev string, skipping extra port if already in use
|
||||
NETDEV_FORWARDS="hostfwd=tcp::${SSH_PORT}-:22"
|
||||
if ! ss -tlnp 2>/dev/null | grep -q ":${EXTRA_PORT} "; then
|
||||
NETDEV_FORWARDS="${NETDEV_FORWARDS},hostfwd=tcp::${EXTRA_PORT}-:8080"
|
||||
else
|
||||
warn "Port ${EXTRA_PORT} already in use — skipping extra forward"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
exec "$QEMU_BIN" \
|
||||
-machine "$QEMU_MACHINE" \
|
||||
-m "$QEMU_MEMORY" \
|
||||
-smp "$QEMU_SMP" \
|
||||
-enable-kvm \
|
||||
-kernel "$KERNEL" \
|
||||
-initrd "$INITRD" \
|
||||
-append "$KERNEL_APPEND" \
|
||||
-drive "file=$DISK,if=virtio,format=$DISK_FMT" \
|
||||
-netdev "user,id=net0,${NETDEV_FORWARDS}" \
|
||||
-device virtio-net,netdev=net0 \
|
||||
$DISPLAY_FLAG \
|
||||
"${EXTRA_QEMU_ARGS[@]}"
|
||||
Reference in New Issue
Block a user