73 lines
2.1 KiB
Bash
Executable File
73 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Note: Not using 'set -e' here because we handle errors explicitly
|
|
# and arithmetic operations can cause false failures with set -e
|
|
|
|
VM_NAME="$1"
|
|
GOLDEN_IMAGE="$2"
|
|
MAX_WAIT="${3:-30}"
|
|
|
|
if [ -z "$VM_NAME" ] || [ -z "$GOLDEN_IMAGE" ]; then
|
|
echo "Usage: $0 <vm_name> <golden_image_path> [max_wait_seconds]"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[Provision] Creating VM: $VM_NAME"
|
|
|
|
# Create linked clone (very fast - just a pointer to base)
|
|
VM_DISK="/var/lib/libvirt/images/${VM_NAME}.qcow2"
|
|
|
|
echo "[Provision] Creating overlay disk: $VM_DISK"
|
|
sudo qemu-img create -f qcow2 -b "$GOLDEN_IMAGE" -F qcow2 "$VM_DISK" 2>/dev/null
|
|
|
|
# Define and start VM
|
|
echo "[Provision] Starting VM with virt-install..."
|
|
VIRT_INSTALL_OUTPUT=$(sudo virt-install \
|
|
--name "$VM_NAME" \
|
|
--memory 2048 \
|
|
--vcpus 2 \
|
|
--disk path="$VM_DISK",format=qcow2 \
|
|
--import \
|
|
--os-variant rocky9-unknown \
|
|
--network network=default \
|
|
--noautoconsole \
|
|
--wait 0 \
|
|
--transient \
|
|
2>&1) || {
|
|
echo "[Provision] ERROR: virt-install failed"
|
|
echo "$VIRT_INSTALL_OUTPUT" | grep -v "WARNING"
|
|
echo "[Provision] Cleaning up disk..."
|
|
sudo rm -f "$VM_DISK"
|
|
echo "ERROR"
|
|
exit 1
|
|
}
|
|
|
|
# Wait for IP address
|
|
echo "[Provision] Waiting for VM to obtain IP address (max ${MAX_WAIT}s)..."
|
|
COUNTER=0
|
|
while [ $COUNTER -lt $MAX_WAIT ]; do
|
|
# Try to get IP from DHCP lease (explicitly use system connection)
|
|
IP=$(sudo virsh -c qemu:///system domifaddr "$VM_NAME" --source lease 2>/dev/null | awk '/ipv4/ {print $4}' | cut -d/ -f1 | head -1)
|
|
|
|
if [ -n "$IP" ] && [ "$IP" != "0.0.0.0" ]; then
|
|
echo "[Provision] IP obtained: $IP"
|
|
echo "$IP"
|
|
exit 0
|
|
fi
|
|
|
|
sleep 2
|
|
((COUNTER++))
|
|
|
|
# Show progress every 5 iterations
|
|
if [ $((COUNTER % 5)) -eq 0 ]; then
|
|
echo "[Provision] Still waiting... (${COUNTER}/${MAX_WAIT}s)"
|
|
fi
|
|
done
|
|
|
|
echo "[Provision] ERROR: Could not obtain IP for $VM_NAME after $MAX_WAIT seconds"
|
|
echo "[Provision] Destroying failed VM..."
|
|
sudo virsh destroy "$VM_NAME" 2>/dev/null || true
|
|
sudo virsh undefine "$VM_NAME" 2>/dev/null || true
|
|
sudo rm -f "$VM_DISK"
|
|
echo "ERROR"
|
|
exit 1
|