Some checks failed
Run Check Script / check (pull_request) Failing after 40s
192 lines
5.7 KiB
Bash
Executable File
192 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# --- Configuration ---
|
|
LAB_DIR="/var/lib/harmony_pxe_test"
|
|
IMG_DIR="${LAB_DIR}/images"
|
|
STATE_DIR="${LAB_DIR}/state"
|
|
VM_OPN="opnsense-pxe"
|
|
VM_PXE="pxe-node-1"
|
|
NET_HARMONYLAN="harmonylan"
|
|
|
|
# Network settings for the isolated LAN
|
|
VLAN_CIDR="192.168.150.0/24"
|
|
VLAN_GW="192.168.150.1"
|
|
VLAN_MASK="255.255.255.0"
|
|
|
|
# VM Specifications
|
|
RAM_OPN="2048"
|
|
VCPUS_OPN="2"
|
|
DISK_OPN_GB="10"
|
|
OS_VARIANT_OPN="freebsd14.0" # Updated to a more recent FreeBSD variant
|
|
|
|
RAM_PXE="4096"
|
|
VCPUS_PXE="2"
|
|
DISK_PXE_GB="40"
|
|
OS_VARIANT_LINUX="centos-stream9"
|
|
|
|
OPN_IMG_URL="https://mirror.ams1.nl.leaseweb.net/opnsense/releases/25.7/OPNsense-25.7-serial-amd64.img.bz2"
|
|
OPN_IMG_PATH="${IMG_DIR}/OPNsense-25.7-serial-amd64.img"
|
|
CENTOS_ISO_URL="https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/images/boot.iso"
|
|
CENTOS_ISO_PATH="${IMG_DIR}/CentOS-Stream-9-latest-boot.iso"
|
|
|
|
CONNECT_URI="qemu:///system"
|
|
|
|
download_if_missing() {
|
|
local url="$1"
|
|
local dest="$2"
|
|
if [[ ! -f "$dest" ]]; then
|
|
echo "Downloading $url to $dest"
|
|
mkdir -p "$(dirname "$dest")"
|
|
local tmp
|
|
tmp="$(mktemp)"
|
|
curl -L --progress-bar "$url" -o "$tmp"
|
|
case "$url" in
|
|
*.bz2) bunzip2 -c "$tmp" > "$dest" && rm -f "$tmp" ;;
|
|
*) mv "$tmp" "$dest" ;;
|
|
esac
|
|
else
|
|
echo "Already present: $dest"
|
|
fi
|
|
}
|
|
|
|
# Ensures a libvirt network is defined and active
|
|
ensure_network() {
|
|
local net_name="$1"
|
|
local net_xml_path="$2"
|
|
if virsh --connect "${CONNECT_URI}" net-info "${net_name}" >/dev/null 2>&1; then
|
|
echo "Network ${net_name} already exists."
|
|
else
|
|
echo "Defining network ${net_name} from ${net_xml_path}"
|
|
virsh --connect "${CONNECT_URI}" net-define "${net_xml_path}"
|
|
fi
|
|
|
|
if ! virsh --connect "${CONNECT_URI}" net-info "${net_name}" | grep "Active: *yes"; then
|
|
echo "Starting network ${net_name}..."
|
|
virsh --connect "${CONNECT_URI}" net-start "${net_name}"
|
|
virsh --connect "${CONNECT_URI}" net-autostart "${net_name}"
|
|
fi
|
|
}
|
|
|
|
# Destroys a VM completely
|
|
destroy_vm() {
|
|
local vm_name="$1"
|
|
if virsh --connect "${CONNECT_URI}" dominfo "$vm_name" >/dev/null 2>&1; then
|
|
echo "Destroying and undefining VM: ${vm_name}"
|
|
virsh --connect "${CONNECT_URI}" destroy "$vm_name" || true
|
|
virsh --connect "${CONNECT_URI}" undefine "$vm_name" --nvram
|
|
fi
|
|
}
|
|
|
|
# Destroys a libvirt network
|
|
destroy_network() {
|
|
local net_name="$1"
|
|
if virsh --connect "${CONNECT_URI}" net-info "$net_name" >/dev/null 2>&1; then
|
|
echo "Destroying and undefining network: ${net_name}"
|
|
virsh --connect "${CONNECT_URI}" net-destroy "$net_name" || true
|
|
virsh --connect "${CONNECT_URI}" net-undefine "$net_name"
|
|
fi
|
|
}
|
|
|
|
# --- Main Logic ---
|
|
create_lab_environment() {
|
|
# Create network definition files
|
|
cat > "${STATE_DIR}/default.xml" <<EOF
|
|
<network>
|
|
<name>default</name>
|
|
<forward mode='nat'/>
|
|
<bridge name='virbr0' stp='on' delay='0'/>
|
|
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
|
<dhcp>
|
|
<range start='192.168.122.100' end='192.168.122.200'/>
|
|
</dhcp>
|
|
</ip>
|
|
</network>
|
|
EOF
|
|
|
|
cat > "${STATE_DIR}/${NET_HARMONYLAN}.xml" <<EOF
|
|
<network>
|
|
<name>${NET_HARMONYLAN}</name>
|
|
<bridge name='virbr1' stp='on' delay='0'/>
|
|
</network>
|
|
EOF
|
|
|
|
# Ensure both networks exist and are active
|
|
ensure_network "default" "${STATE_DIR}/default.xml"
|
|
ensure_network "${NET_HARMONYLAN}" "${STATE_DIR}/${NET_HARMONYLAN}.xml"
|
|
|
|
# --- Create OPNsense VM (MODIFIED SECTION) ---
|
|
local disk_opn="${IMG_DIR}/${VM_OPN}.qcow2"
|
|
if [[ ! -f "$disk_opn" ]]; then
|
|
qemu-img create -f qcow2 "$disk_opn" "${DISK_OPN_GB}G"
|
|
fi
|
|
|
|
echo "Creating OPNsense VM using serial image..."
|
|
virt-install \
|
|
--connect "${CONNECT_URI}" \
|
|
--name "${VM_OPN}" \
|
|
--ram "${RAM_OPN}" \
|
|
--vcpus "${VCPUS_OPN}" \
|
|
--cpu host-passthrough \
|
|
--os-variant "${OS_VARIANT_OPN}" \
|
|
--graphics none \
|
|
--noautoconsole \
|
|
--disk path="${disk_opn}",device=disk,bus=virtio,boot.order=1 \
|
|
--disk path="${OPN_IMG_PATH}",device=disk,bus=usb,readonly=on,boot.order=2 \
|
|
--network network=default,model=virtio \
|
|
--network network="${NET_HARMONYLAN}",model=virtio \
|
|
--boot uefi,menu=on
|
|
|
|
echo "OPNsense VM created. Connect with: sudo virsh console ${VM_OPN}"
|
|
echo "The VM will boot from the serial installation image."
|
|
echo "Login with user 'installer' and password 'opnsense' to start the installation."
|
|
echo "Install onto the VirtIO disk (vtbd0)."
|
|
echo "After installation, shutdown the VM, then run 'sudo virsh edit ${VM_OPN}' and remove the USB disk block to boot from the installed system."
|
|
|
|
# --- Create PXE Client VM ---
|
|
local disk_pxe="${IMG_DIR}/${VM_PXE}.qcow2"
|
|
if [[ ! -f "$disk_pxe" ]]; then
|
|
qemu-img create -f qcow2 "$disk_pxe" "${DISK_PXE_GB}G"
|
|
fi
|
|
|
|
echo "Creating PXE client VM..."
|
|
virt-install \
|
|
--connect "${CONNECT_URI}" \
|
|
--name "${VM_PXE}" \
|
|
--ram "${RAM_PXE}" \
|
|
--vcpus "${VCPUS_PXE}" \
|
|
--cpu host-passthrough \
|
|
--os-variant "${OS_VARIANT_LINUX}" \
|
|
--graphics none \
|
|
--noautoconsole \
|
|
--disk path="${disk_pxe}",format=qcow2,bus=virtio \
|
|
--network network="${NET_HARMONYLAN}",model=virtio \
|
|
--pxe \
|
|
--boot uefi,menu=on
|
|
|
|
echo "PXE VM created. It will attempt to netboot on ${NET_HARMONYLAN}."
|
|
}
|
|
|
|
# --- Script Entrypoint ---
|
|
case "${1:-}" in
|
|
up)
|
|
mkdir -p "${IMG_DIR}" "${STATE_DIR}"
|
|
download_if_missing "$OPN_IMG_URL" "$OPN_IMG_PATH"
|
|
download_if_missing "$CENTOS_ISO_URL" "$CENTOS_ISO_PATH"
|
|
create_lab_environment
|
|
echo "Lab setup complete. Use 'sudo virsh list --all' to see VMs."
|
|
;;
|
|
clean)
|
|
destroy_vm "${VM_PXE}"
|
|
destroy_vm "${VM_OPN}"
|
|
destroy_network "${NET_HARMONYLAN}"
|
|
# Optionally destroy the default network if you want a full reset
|
|
# destroy_network "default"
|
|
echo "Cleanup complete."
|
|
;;
|
|
*)
|
|
echo "Usage: sudo $0 {up|clean}"
|
|
exit 1
|
|
;;
|
|
esac
|