evolved-npcs-infra/control-plane/vm-setup/create-control-plane-vms.sh
2025-09-29 22:58:13 -07:00

193 lines
No EOL
4.4 KiB
Bash
Executable file

#!/bin/bash
set -e
# Configuration
VM_DIR="${VM_DIR:-$(pwd)/control-plane-vm}"
CONTROLPLANE_NAME="talos-controlplane"
MEMORY="2048" # 2GB per VM
CPUS="2"
DISK_SIZE="10G" # 10GB disk
TALOS_ISO_URL="https://github.com/siderolabs/talos/releases/download/v1.11.0/metal-arm64.iso"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Create VM directory
create_vm_dir() {
local vm_name=$1
local vm_path="$VM_DIR/$vm_name"
mkdir -p "$vm_path"
echo "$vm_path"
}
# Download Talos ISO if not exists
download_talos_iso() {
local iso_path="$VM_DIR/talos.iso"
if [[ ! -f "$iso_path" ]]; then
log_info "Downloading Talos ISO..."
curl -L -o "$iso_path" "$TALOS_ISO_URL"
else
log_info "Talos ISO already exists"
fi
echo "$iso_path"
}
# Create disk image
create_disk_image() {
local vm_path=$1
local vm_name=$2
local disk_path="$vm_path/disk.qcow2"
if [[ ! -f "$disk_path" ]]; then
# log_info "Creating disk image for $vm_name..."
qemu-img create -f qcow2 "$disk_path" "$DISK_SIZE"
else
log_warn "Disk image already exists for $vm_name"
fi
echo "$disk_path"
}
# Generate unique MAC address
generate_mac() {
local vm_name=$1
local hash=$(echo "$vm_name" | md5sum | cut -c1-6)
printf "52:54:00:%s:%s:%s" "${hash:0:2}" "${hash:2:2}" "${hash:4:2}"
}
# Create VM startup script
create_vm_script() {
local vm_path=$1
local vm_name=$2
local mac_address=$3
local iso_path=$4
local disk_path=$5
local script_path="$vm_path/start.sh"
# Use a function to escape the variables
cat > "$script_path" << EOF
#!/bin/bash
qemu-system-aarch64 \\
-name "$vm_name" \\
-machine virt,highmem=off \\
-accel hvf \\
-cpu host \\
-smp "$CPUS" \\
-m "${MEMORY}M" \\
-drive file="$disk_path",if=virtio,format=qcow2 \\
-cdrom "$iso_path" \\
-netdev user,id=net0 \\
-device virtio-net-pci,netdev=net0,mac=$mac_address \\
-nographic \\
-serial mon:stdio
EOF
chmod +x "$script_path"
echo "$script_path"
}
# Create systemd service file (optional)
create_service_file() {
local vm_path=$1
local vm_name=$2
local script_path=$3
local service_path="$vm_path/$vm_name.service"
cat > "$service_path" << EOF
[Unit]
Description=Talos VM - $vm_name
After=network.target
[Service]
Type=simple
ExecStart=$script_path
WorkingDirectory=$vm_path
Restart=always
User=$USER
[Install]
WantedBy=multi-user.target
EOF
echo "$service_path"
}
# Main execution
main() {
log_info "Creating Talos VMs with QEMU..."
if ! command -v qemu-system-aarch64 &> /dev/null; then
log_error "QEMU is not installed. Install with: brew install qemu"
exit 1
fi
local iso_path=$(download_talos_iso)
log_info "Creating controlplane VM..."
local controlplane_path=$(create_vm_dir "$CONTROLPLANE_NAME")
local controlplane_disk=$(create_disk_image "$controlplane_path" "$CONTROLPLANE_NAME")
local controlplane_mac=$(generate_mac "$CONTROLPLANE_NAME")
local controlplane_script=$(create_vm_script "$controlplane_path" "$CONTROLPLANE_NAME" "$controlplane_mac" "$iso_path" "$controlplane_disk")
create_service_file "$controlplane_path" "$CONTROLPLANE_NAME" "$controlplane_script"
local manage_script="$VM_DIR/manage-vm.sh"
cat > "$manage_script" << 'EOF'
#!/bin/bash
VM_DIR="$(cd "$(dirname "$0")" && pwd)"
start_vm() {
echo "Starting Talos VM..."
"$VM_DIR/talos-controlplane/start.sh" &
}
stop_vm() {
echo "Stopping Talos VM..."
pkill -f "qemu-system-aarch64.*talos-controlplane"
}
case "$1" in
start)
start_vm
;;
stop)
stop_vm
;;
status)
pgrep -f "qemu-system-aarch64.*talos-controlplane" > /dev/null && echo "VM is running" || echo "VM is stopped"
;;
*)
echo "Usage: $0 {start|stop|status}"
exit 1
;;
esac
EOF
chmod +x "$manage_script"
log_info "VM creation complete!"
log_info "VM files located at: $VM_DIR"
log_info ""
log_info "To start VM: $manage_script start"
log_info "To stop VM: $manage_script stop"
log_info ""
log_info "Controlplane MAC: $controlplane_mac"
}
main "$@"