#!/bin/bash # for Debian this must be installed for Longhorn to work # sudo apt-get install -y open-iscsi ########################### # DEFAULT VALUES # ########################### os_options=("Debian" "Ubuntu") os="Debian" # Proxmox path to the template folder template_path="/var/lib/vz/template" # Proxmox certificate path cert_path="/root/.ssh" # Number of VMs to be created vm_number=3 # The first VM id, smallest id is 100 id=121 # Name prefix of the first VM name=k3s drive_name=local-zfs agent=0 # TODO: Implement User Option for it disk_size=20G memory=2048 core=2 # IP for the first VM ip=192.168.0.21 gateway=192.168.0.1 # ssh certificate name variable cert_name=id_rsa # User settings user=$USER password=password ubuntu_url=https://cloud-images.ubuntu.com/lunar/current/lunar-server-cloudimg-amd64.img ubuntu_filename=lunar-server-cloudimg-amd64.img debian_url=https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 debian_filename=debian-12-genericcloud-amd64.qcow2 os_url=https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2 os_filename=debian-12-genericcloud-amd64.qcow2 ################## # Functions # ################## function run() { get_user_variables print_info # Prints information about what will be created based on defaults/user inputs setup # Do not worry it asks for confirmation before the setup/installation starts start_vms # You can choose to start all VMs if you want #qemu_agent # Not implemented yet, you can choose to add qemu-agent to the installation image } function get_user_variables() { echo -e -n "\e[36mWhich OS cloud image would you like to use?\n\e[0m" PS3="" select option in "${os_options[@]}"; do # Check if the user selected an option if [[ -n "$option" ]]; then # Do something with the selected option case $option in "Debian") ;; "Ubuntu") ;; *) echo -e "\e[31mInvalid option selected. Exiting...\e[0m" exit ;; esac else # No option was selected echo -e "\e[31mNo option was selected. Exiting...\e[0m" exit fi # Set the selected Operating system os=$option # Exit the select loop break done echo -e "\e[36mHow many VM do you want to create? \e[0m" read -e -p "" -i "$vm_number" vm_number echo -e "\e[36mFirst VM ID? (minimum 100)\e[0m" read -e -p "" -i $id id echo -e "\e[36mVM name prefix? \e[0m" read -e -p "" -i $name name echo -e "\e[36mIP address? \e[0m" read -e -p "" -i $ip ip # Split the IP address into its parts using the '.' character as the delimiter. ip_address_parts=(${ip//./ }) octet1=${ip_address_parts[0]} octet2=${ip_address_parts[1]} octet3=${ip_address_parts[2]} octet4=${ip_address_parts[3]} echo -e "\e[36mGateway? \e[0m" read -e -p "" -i $gateway gateway echo -e "\e[36mDisk Size? \e[0m" read -e -p "" -i $disk_size disk_size echo -e "\e[36mMemory Size? \e[0m" read -e -p "" -i $memory memory echo -e "\e[36mNumber of processor cores? \e[0m" read -e -p "" -i $core core echo -e "\e[36mUser name? \e[0m" read -e -p "" -i $user user echo -e "\e[36mUser password? \e[0m" read -e -p "" -i $password password echo -e "\e[36mCertification name? \e[0m" read -e -p "" -i $cert_name cert_name echo -e "\e[36mDrive name to store images? \e[0m" read -e -p "" -i $drive_name drive_name } # function qemu_agent() { yesno=n echo -e "\e[36mDo you want to add qemu agent to the VM images? (y/n) \e[0m" read -e -p "" -i $yesno yesno case $yesno in [Yy]*) # Install qemu agent packages for each VM echo -e "\e[32mInstalling qemu agent packages.\e[0m" for ((i = 1; i <= $vm_number; i++)); do if [[ $i -le 9 ]]; then idx="0$i" else idx=$i fi # TODO: ssh into all VMs one by one and intalll the necessary qemu agent packages done ;; [Nn]*) echo -e "\e[33mSkipping qemu agent installation.\e[0m" ;; *) ;; esac } function print_info() { echo -e "\e[36m\nThe following Virtual Machines will be created:\e[0m" for ((i = 1; i <= $vm_number; i++)); do if [[ $i -le 9 ]]; then idx="0$i" else idx=$i fi echo -e "\e[32mVM ID: $(($id + $i - 1)), Name: $name-$idx, IP address: $octet1.$octet2.$octet3.$(($octet4 + $i - 1))\e[0m" done echo -e "\e[36m\nCommon VM parameters:\e[0m" echo -e "\e[32mOS cloud image:\e[0m" "$os" echo -e "\e[32mPublic Proxmox Certificate:\e[0m" "$cert_path/$cert_name.pub\n" echo -e "\e[32mGateway:\e[0m" "$gateway" echo -e "\e[32mDisk size:\e[0m" "$disk_size""B" echo -e "\e[32mMemory size:\e[0m" "$memory""GB" echo -e "\e[32mCPU cores:\e[0m" "$core" echo -e "\e[32mDrive name:\e[0m" "$drive_name" } function setup() { yesno=n echo -e "\e[36mDo you want to proceed with the setup? (y/n) \e[0m" read -e -p "" -i $yesno yesno case $yesno in [Yy]*) get_os_image create_vms ;; [Nn]*) echo -e "\e[31mInstallation aborted by user. No changes were made.\e[0m" exit ;; *) ;; esac } function start_vms() { yesno=n echo -e "\e[36mDo you want to start up the Virtual Machines now? (y/n) \e[0m" read -e -p "" -i $yesno yesno case $yesno in [Yy]*) # Start VMs for ((i = 1; i <= $vm_number; i++)); do if [[ $i -le 9 ]]; then idx="0$i" else idx=$i fi echo -e "\e[33mStarting Virtual Machine $idx\e[0m" qm start $(($id + $i - 1)) done # Print VMs statuses for ((i = 1; i <= $vm_number; i++)); do if [[ $i -le 9 ]]; then idx="0$i" else idx=$i fi echo -e "\e[33mVirtual Machine $idx status: \e[0m" qm status $(($id + $i - 1)) done ;; [Nn]*) exit ;; *) ;; esac } function get_os_image() { case $os in "Debian") os_url=$debian_url os_filename=$debian_filename # Check if the directory exists. if [ ! -d "$template_path/qcow" ]; then mkdir $template_path/qcow fi cd $template_path/qcow ;; "Ubuntu") os_url=$ubuntu_url os_filename=$ubuntu_filename # Check if the directory exists. if [ ! -d "$template_path/iso" ]; then mkdir $template_path/iso fi cd $template_path/iso ;; *) echo -e "\e[31Invalid option.\e[0m" ;; esac # Check if the os image file already exists. # If not then download it. if [ ! -f "$os_filename" ]; then # Download the selected os cloud image echo -e "\e[33mDownloading $os cloud image ...\e[0m" wget $os_url fi } # Only runs if you uncomment the function in `create_vms`. Please be careful function destroy_existing_vms() { # Stop and destroy Virtual Machine if it already exists # TODO: Put loop and confirmation before doing anything qm stop $(($id + $i - 1)) qm destroy $(($id + $i - 1)) --destroy-unreferenced-disks --purge } function create_vms() { for ((i = 1; i <= $vm_number; i++)); do # Stop and destroy Virtual Machine if it already exists. # Be really careful with this only uncomment if you know what are you doing. !!! # # destroy_existing_vms # # ############################# # Create VM from the cloud image if [[ $i -le 9 ]]; then idx="0$i" else idx=$i fi echo -e "\e[33mCreating Virtual Machine: $idx\e[0m" echo "VM ID: $(($id + $i - 1)), Name: $name-$idx, IP address: $octet1.$octet2.$octet3.$(($octet4 + $i - 1))" qm create $(($id + $i - 1)) \ --memory $memory \ --core $core \ --numa 1 \ --name $name-$idx \ --net0 virtio,bridge=vmbr0 \ --balloon 0 \ --ipconfig0 gw=$gateway,ip=$octet1.$octet2.$octet3.$(($octet4 + $i - 1))/24 \ --cipassword $password \ --ciuser $user \ --ciupgrade 1 \ --sshkeys $cert_path/$cert_name.pub \ --agent=$agent qm importdisk $(($id + $i - 1)) $os_filename $drive_name qm set $(($id + $i - 1)) --scsihw virtio-scsi-pci --scsi0 $drive_name:vm-$(($id + $i - 1))-disk-0 qm disk resize $(($id + $i - 1)) scsi0 $disk_size qm set $(($id + $i - 1)) --ide2 $drive_name:cloudinit qm set $(($id + $i - 1)) --boot c --bootdisk scsi0 qm set $(($id + $i - 1)) --serial0 socket --vga serial0 done } ######################### # Run the script # ######################### run