#!/bin/bash # # test-vm.sh — Create a test VM to validate the PXE server setup # # This script: # 1. Builds a CIDATA ISO with autoinstall config, packages, playbook, and webapp # 2. Creates an isolated libvirt network (pxe-test, 10.9.100.0/24) # 3. Launches an Ubuntu 24.04 Server VM that auto-installs and configures itself # # Usage: # ./test-vm.sh /path/to/ubuntu-24.04-live-server-amd64.iso # # After install completes (~10-15 min), access the webapp at: # http://10.9.100.1:9009 # # To watch progress: # virsh console pxe-test # # To clean up: # ./test-vm.sh --destroy set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" VM_NAME="pxe-test" NET_NAME="pxe-test" VM_DISK="/var/lib/libvirt/images/${VM_NAME}.qcow2" CIDATA_ISO="/tmp/${VM_NAME}-cidata.iso" VM_RAM=4096 VM_CPUS=2 VM_DISK_SIZE=40 # GB # --- Handle --destroy flag --- if [ "${1:-}" = "--destroy" ]; then echo "Destroying test environment..." virsh destroy "$VM_NAME" 2>/dev/null || true virsh undefine "$VM_NAME" 2>/dev/null || true rm -f "$VM_DISK" virsh net-destroy "$NET_NAME" 2>/dev/null || true virsh net-undefine "$NET_NAME" 2>/dev/null || true rm -f "$CIDATA_ISO" echo "Done." exit 0 fi # --- Validate Ubuntu ISO argument --- UBUNTU_ISO="${1:-}" if [ -z "$UBUNTU_ISO" ] || [ ! -f "$UBUNTU_ISO" ]; then echo "Usage: $0 /path/to/ubuntu-24.04-live-server-amd64.iso" echo "" echo "Download from: https://ubuntu.com/download/server" echo "" echo "Other commands:" echo " $0 --destroy Remove the test VM and network" exit 1 fi echo "============================================" echo "PXE Server Test VM Setup" echo "============================================" echo "" # --- Step 1: Build CIDATA ISO --- echo "[1/4] Building CIDATA ISO..." CIDATA_DIR=$(mktemp -d) # Autoinstall config cp "$SCRIPT_DIR/autoinstall/user-data" "$CIDATA_DIR/user-data" touch "$CIDATA_DIR/meta-data" # Offline .deb packages if [ -d "$SCRIPT_DIR/offline-packages" ]; then mkdir -p "$CIDATA_DIR/packages" cp "$SCRIPT_DIR/offline-packages/"*.deb "$CIDATA_DIR/packages/" 2>/dev/null || true echo " Copied $(ls -1 "$CIDATA_DIR/packages/"*.deb 2>/dev/null | wc -l) .deb packages" else echo " WARNING: No offline-packages/ directory. Run download-packages.sh first." fi # Ansible playbook mkdir -p "$CIDATA_DIR/playbook" cp "$SCRIPT_DIR/playbook/"* "$CIDATA_DIR/playbook/" 2>/dev/null || true echo " Copied playbook/" # Webapp if [ -d "$SCRIPT_DIR/webapp" ]; then mkdir -p "$CIDATA_DIR/webapp" cp "$SCRIPT_DIR/webapp/app.py" "$SCRIPT_DIR/webapp/requirements.txt" "$CIDATA_DIR/webapp/" cp -r "$SCRIPT_DIR/webapp/templates" "$SCRIPT_DIR/webapp/static" "$CIDATA_DIR/webapp/" echo " Copied webapp/" fi # Pip wheels if [ -d "$SCRIPT_DIR/pip-wheels" ]; then cp -r "$SCRIPT_DIR/pip-wheels" "$CIDATA_DIR/pip-wheels" echo " Copied pip-wheels/" fi # Boot tools if [ -d "$SCRIPT_DIR/boot-tools" ]; then cp -r "$SCRIPT_DIR/boot-tools" "$CIDATA_DIR/boot-tools" echo " Copied boot-tools/" fi # Generate the CIDATA ISO genisoimage -output "$CIDATA_ISO" -volid CIDATA -joliet -rock "$CIDATA_DIR" 2>/dev/null CIDATA_SIZE=$(du -sh "$CIDATA_ISO" | cut -f1) echo " CIDATA ISO: $CIDATA_ISO ($CIDATA_SIZE)" rm -rf "$CIDATA_DIR" # --- Step 2: Create isolated network --- echo "" echo "[2/4] Setting up isolated network ($NET_NAME)..." # Check if network already exists if virsh net-info "$NET_NAME" &>/dev/null; then echo " Network $NET_NAME already exists, reusing." else cat > /tmp/${NET_NAME}-net.xml < ${NET_NAME} NETEOF virsh net-define /tmp/${NET_NAME}-net.xml virsh net-start "$NET_NAME" rm -f /tmp/${NET_NAME}-net.xml echo " Created isolated network 10.9.100.0/24 (no DHCP, no NAT)" fi # --- Step 3: Create VM disk --- echo "" echo "[3/4] Creating VM disk (${VM_DISK_SIZE}GB)..." if [ -f "$VM_DISK" ]; then echo " Disk already exists. Destroy first with: $0 --destroy" exit 1 fi qemu-img create -f qcow2 "$VM_DISK" "${VM_DISK_SIZE}G" # --- Step 4: Extract kernel/initrd from ISO --- echo "" echo "[4/5] Extracting kernel and initrd from ISO..." ISO_MNT=$(mktemp -d) mount -o loop,ro "$UBUNTU_ISO" "$ISO_MNT" KERNEL="/tmp/${VM_NAME}-vmlinuz" INITRD="/tmp/${VM_NAME}-initrd" cp "$ISO_MNT/casper/vmlinuz" "$KERNEL" cp "$ISO_MNT/casper/initrd" "$INITRD" umount "$ISO_MNT" rmdir "$ISO_MNT" echo " Extracted vmlinuz and initrd from casper/" # --- Step 5: Launch VM --- echo "" echo "[5/5] Launching VM ($VM_NAME)..." virt-install \ --name "$VM_NAME" \ --memory "$VM_RAM" \ --vcpus "$VM_CPUS" \ --disk path="$VM_DISK",format=qcow2 \ --disk path="$UBUNTU_ISO",device=cdrom,readonly=on \ --disk path="$CIDATA_ISO",device=cdrom \ --network network="$NET_NAME" \ --os-variant ubuntu24.04 \ --graphics none \ --console pty,target_type=serial \ --install kernel="$KERNEL",initrd="$INITRD",kernel_args="console=ttyS0,115200n8 autoinstall" \ --noautoconsole echo "" echo "============================================" echo "VM launched! The autoinstall will take ~10-15 minutes." echo "============================================" echo "" echo "Watch progress:" echo " virsh console $VM_NAME" echo " (Press Ctrl+] to detach)" echo "" echo "After install + first boot:" echo " SSH: ssh pxe@10.9.100.1" echo " Webapp: http://10.9.100.1:9009" echo "" echo "Manage:" echo " virsh start $VM_NAME" echo " virsh shutdown $VM_NAME" echo " $0 --destroy (remove everything)" echo ""