#!/bin/bash # Sources using Openstack images declare -A sources declare -A template_ids declare -A result_ids #!/bin/bash # Sources using Openstack images declare -A sources declare -A template_ids declare -A result_ids template_ids["Debian"]=10000 template_ids["Ubuntu"]=10100 template_ids["Almalinux"]=10200 template_ids["ArchLinux"]=10300 template_ids["Fedora"]=10400 template_ids["Centos"]=10500 template_ids["Rocky"]=10600 template_ids["Gentoo"]=10700 # Debian Versions sources["Debian-12"]="https://iso.pawhost.eu/Cloud-Image/Debian/debian-12-generic-amd64.qcow2" sources["Debian-11"]="https://iso.pawhost.eu/Cloud-Image/Debian/debian-11-generic-amd64.qcow2" sources["Debian-10"]="https://iso.pawhost.eu/Cloud-Image/Debian/debian-10-openstack-amd64.qcow2" # Ubuntu Versions # Here we use a kvm image, because they are smaller than the openstack images sources["Ubuntu-24.04"]="https://iso.pawhost.eu/Cloud-Image/Ubuntu/noble-server-cloudimg-amd64.img" sources["Ubuntu-22.04"]="https://iso.pawhost.eu/Cloud-Image/Ubuntu/jammy-server-cloudimg-amd64.img" sources["Ubuntu-20.04"]="https://iso.pawhost.eu/Cloud-Image/Ubuntu/focal-server-cloudimg-amd64.img" sources["Ubuntu-18.04"]="https://iso.pawhost.eu/Cloud-Image/Ubuntu/bionic-server-cloudimg-amd64.img" # AlmaLinux Versions sources["Almalinux-9"]="https://iso.pawhost.eu/Cloud-Image/AlmaLinux/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2" sources["Almalinux-8"]="https://iso.pawhost.eu/Cloud-Image/AlmaLinux/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2" # ArchLinux Versions sources["ArchLinux"]="https://iso.pawhost.eu/Cloud-Image/ArchLinux/Arch-Linux-x86_64-cloudimg.qcow2" # Fedora Versions sources["Fedora-41"]="https://iso.pawhost.eu/Cloud-Image/Fedora/fedora-coreos-41.20250130.3.0-nutanix.x86_64.qcow2" # CentOS Versions sources["Centos-9"]="https://iso.pawhost.eu/Cloud-Image/CentOS/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2" sources["Centos-8"]="https://iso.pawhost.euo/Cloud-Image/CentOS/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2" sources["Centos-7"]="https://iso.pawhost.eu/Cloud-Image/CentOS/CentOS-7-x86_64-GenericCloud-2211.qcow2" # Rocky Versions sources["Rocky-9"]="https://iso.pawhost.eu/Cloud-Image/Rocky/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2" sources["Rocky-8"]="https://iso.pawhost.eu/Cloud-Image/Rocky/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2" # Gentoo Versions sources["Gentoo"]="https://iso.pawhost.eu/Cloud-Image/Gentoo/di-amd64-cloudinit-20250223T170333Z.qcow2" download_template() { echo "[*] Downloading template $1..." wget -q --show-progress -O "$2" "$1" echo "[*] Download complete." } vm_exists() { qm list | grep -q "$1" } echo " # " echo " # #### ##### ##### ###### # # # # # ###### #### " echo " # # # # # # # # ## # # ## # # # # " echo " # # # # # # # ##### # # # # # # # ##### # # " echo " # # # # ##### # # # # # # ### # # # # # # # " echo " # # # # # # # # # # ## ### # # ## # # # " echo " ##### #### # # ##### ###### # # ### # # # # #### " echo " " echo "" echo " > Create Proxmox Templates <" echo "" # Check if script is run with root permissions if [ "$(id -u)" != "0" ]; then echo "[x] Please run this script with root privileges." exit 1 fi # Check if Proxmox is installed if ! [ -f /etc/pve/pve-root-ca.pem ]; then echo "[x] Proxmox is not installed, please run this script in a Proxmox Environment." exit 1 fi echo "[*] Installing dependencies..." apt -qq install -y libguestfs-tools wget dialog &> /dev/null # Let user enter a storage name read -p "[?] Please enter a the name for the storage to save the template machines to (default=local-lvm): " -r storage storage=${storage:-"local-lvm"} # Let user choose whether to delete templates after creation read -p "[?] Do you want to delete the downloaded images after creation? (y/n, default=y): " -r delete_templates delete_templates=${delete_templates:-y} read -p "[?] Do you want to delete existing templates? (y/n, default=n): " -r delete_previous delete_previous=${delete_previous:-n} read -p "[?] Use CPU type host instead of kvm64 by default? (y/n, default=y): " -r use_cpu_host use_cpu_host=${use_cpu_host:-y} clear # Let user select distros to download cmd=(dialog --separate-output --title "Distro Selection" --checklist "Select distros to create templates for:" 22 76 16) options=( $(for key in "${!sources[@]}"; do echo "$key" echo "$key" echo "on" done) ) choices=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty) clear # Check if storage exists in Proxmox if ! (pvesm list "$storage" | grep -q "$storage"); then echo "[x] Storage does not exist in Proxmox or does not have any hosts, please choose another name." exit 1 fi # Delete existing templates if [ "$delete_previous" = "y" ]; then echo "[*] Deleting existing templates..." vm_list=$(qm list | grep template | awk '{print $1}') for vm_id in "${template_ids[@]}"; do for i in $(seq $vm_id $(($vm_id + ${#sources[@]}))); do if echo "$vm_list" | grep -q "$i"; then qm destroy "$i" fi done done echo "[*] Deletion complete." fi start=$(date +%s) sorted=$(for i in "${!choices[@]}"; do echo "${choices[i]}"; done | sort) for source in $sorted; do if vm_exists "template-$source"; then echo "[*] Template for $source already exists, skipping..." continue fi distro=$(echo "$source" | cut -d'-' -f1) vm_id=${template_ids[$distro]} while vm_exists "$vm_id"; do echo "[*] VM with ID $vm_id already exists, trying next id..." vm_id=$(($vm_id + 1)) done echo "[*] Creating template for $source..." extension="${sources[$source]##*.}" image_path="/tmp/$source.$extension" download_template "${sources[$source]}" "$image_path" echo "[*] Customizing image, please wait..." virt-customize -a "$image_path" \ --install qemu-guest-agent \ --run-command 'sed -i "s/ssh_pwauth:.*0/ssh_pwauth: 1/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/ssh_pwauth:.*[Ff]alse/ssh_pwauth: true/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/disable_root:.*[Tt]rue/disable_root: false/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/disable_root:.*1/disable_root: 0/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/lock_passwd:.*[Tt]rue/lock_passwd: false/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/lock_passwd:.*1/lock_passwd: 0/" /etc/cloud/cloud.cfg' \ --run-command 'sed -i "s/PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config' \ --run-command 'sed -i "s/PermitRootLogin [Nn]o/PermitRootLogin yes/" /etc/ssh/sshd_config' \ --run-command 'sed -i "s/#PermitRootLogin [Yy]es/PermitRootLogin yes/" /etc/ssh/sshd_config' \ --run-command 'sed -i "s/#PermitRootLogin prohibit-password/PermitRootLogin yes/" /etc/ssh/sshd_config' \ --run-command 'sed -i "s/KbdInteractiveAuthentication [Nn]o/#KbdInteractiveAuthentication no/" /etc/ssh/sshd_config' \ --run-command 'sed -i "s/[#M]axAuthTries 6/MaxAuthTries 20/" /etc/ssh/sshd_config' \ --no-logfile echo "[*] Creating new VM with ID $vm_id..." is_x86_64_v2=$(echo "${sources[$source]}" | grep -c "x86_64") cpu_type="kvm64" if [ "$use_cpu_host" = "y" ]; then cpu_type="host" fi if [ "$is_x86_64_v2" -eq 1 ]; then cpu_type="x86-64-v2" fi qm create $vm_id --name "$source" --memory 512 --cores 1 --net0 virtio,bridge=vmbr0,firewall=1 --agent enabled=1,fstrim_cloned_disks=1 --cpu $cpu_type echo "[*] Importing template image..." qm importdisk $vm_id "/tmp/$source.$extension" "$storage" -format qcow2 echo "[*] Attaching disk to template..." qm set $vm_id --scsihw virtio-scsi-pci --scsi0 "$storage:vm-$vm_id-disk-0" echo "[*] Applying important settings..." qm set $vm_id --ide2 "$storage:cloudinit" --boot c --bootdisk scsi0 --serial0 socket --vga std echo "[*] Adding empty CDROM Drive..." qm set $vm_id --ide1 none,media=cdrom echo "[*] Resizing disk..." qm resize $vm_id scsi0 +2G echo "[*] Creating template from VM..." qm template $vm_id if [ "$delete_templates" = "y" ]; then echo "[*] Deleting downloaded image file:" rm -v $image_path fi result_ids[$source]="$vm_id" template_ids[$distro]=$(($vm_id+1)) echo "[*] Template creation for $source complete." done end=$(date +%s) echo "[*] Script execution finished after $((($end-$start)/60)) min $((($end-$start)%60)) sec." created_count=${#result_ids[@]} if [ "$created_count" -eq 0 ]; then echo "[!] No new templates were created." exit 0 else echo "[*] The following templates were created:" for source in "${!result_ids[@]}"; do echo " - $source: ${result_ids[$source]}" done fi