From 46a1a4fe65593e856235ef194561676f4255bd0b Mon Sep 17 00:00:00 2001 From: Jan Smyrek Date: Wed, 13 Aug 2025 12:57:31 +0000 Subject: [PATCH] =?UTF-8?q?template.sh=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template.sh | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 template.sh diff --git a/template.sh b/template.sh new file mode 100644 index 0000000..56af4f7 --- /dev/null +++ b/template.sh @@ -0,0 +1,243 @@ +#!/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://root.jorden.info/Cloud-Image/Debian/debian-12-generic-amd64.qcow2" +sources["Debian-11"]="https://root.jorden.info/Cloud-Image/Debian/debian-11-generic-amd64.qcow2" +sources["Debian-10"]="https://root.jorden.info/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://root.jorden.info/Cloud-Image/Ubuntu/noble-server-cloudimg-amd64.img" +sources["Ubuntu-22.04"]="https://root.jorden.info/Cloud-Image/Ubuntu/jammy-server-cloudimg-amd64.img" +sources["Ubuntu-20.04"]="https://root.jorden.info/Cloud-Image/Ubuntu/focal-server-cloudimg-amd64.img" +sources["Ubuntu-18.04"]="https://root.jorden.info/Cloud-Image/Ubuntu/bionic-server-cloudimg-amd64.img" + +# AlmaLinux Versions +sources["Almalinux-9"]="https://root.jorden.info/Cloud-Image/AlmaLinux/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2" +sources["Almalinux-8"]="https://root.jorden.info/Cloud-Image/AlmaLinux/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2" + +# ArchLinux Versions +sources["ArchLinux"]="https://root.jorden.info/Cloud-Image/ArchLinux/Arch-Linux-x86_64-cloudimg.qcow2" + +# Fedora Versions +sources["Fedora-41"]="https://root.jorden.info/Cloud-Image/Fedora/fedora-coreos-41.20250130.3.0-nutanix.x86_64.qcow2" + +# CentOS Versions +sources["Centos-9"]="https://root.jorden.info/Cloud-Image/CentOS/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2" +sources["Centos-8"]="https://root.jorden.info/Cloud-Image/CentOS/CentOS-8-GenericCloud-8.4.2105-20210603.0.x86_64.qcow2" +sources["Centos-7"]="https://root.jorden.info/Cloud-Image/CentOS/CentOS-7-x86_64-GenericCloud-2211.qcow2" + +# Rocky Versions +sources["Rocky-9"]="https://root.jorden.info/Cloud-Image/Rocky/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2" +sources["Rocky-8"]="https://root.jorden.info/Cloud-Image/Rocky/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2" + +# Gentoo Versions +sources["Gentoo"]="https://root.jorden.info/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 + + \ No newline at end of file