#!/bin/bash BUILT_IN_CLOUDINIT=false AGENT="${AGENT:-1}" BALLOON="${BALLOON:-0}" MEMORY="${MEMORY:-1024}" CORES="${CORES:-1}" BIOS_TYPE="${BIOS_TYPE:-ovmf}" CPU_TYPE="${CPU_TYPE:-cputype=host}" EFI_OPTS="${EFI_OPTS:-1,efitype=4m,pre-enrolled-keys=0}" MACHINE_TYPE="${MACHINE_TYPE:-q35}" OS_TYPE="${OS_TYPE:-l26}" SCSI_TYPE="${SCSI_TYPE:-virtio-scsi-pci}" CPU_SOCKETS="${CPU_SOCKETS:-1}" BRIDGE="${BRIDGE:-vmbr0}" FILE_SYSTEM="${FILE_SYSTEM:-zfs}" VERSION="${VERSION:-15}" [ -f .env ] && source .env declare -A distros=() declare -A distro_array=( [freebsd14-ufs]="https://download.freebsd.org/releases/VM-IMAGES/14.4-RELEASE/amd64/Latest/FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz" [freebsd14-zfs]="https://download.freebsd.org/releases/VM-IMAGES/14.4-RELEASE/amd64/Latest/FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-zfs.qcow2.xz" [freebsd15-ufs]="https://download.freebsd.org/releases/VM-IMAGES/15.1-RELEASE/amd64/Latest/FreeBSD-15.1-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz" [freebsd15-zfs]="https://download.freebsd.org/releases/VM-IMAGES/15.1-RELEASE/amd64/Latest/FreeBSD-15.1-RELEASE-amd64-BASIC-CLOUDINIT-zfs.qcow2.xz" ) Help(){ echo "Usage: $0 [FLAG] " echo "" echo "Required Flags:" echo "-v Select the VMID to use for template" echo "-s Select the PVE storage i.e. local-lvm" echo "" echo "Optional:" echo "-n Selects version number i.e. 14 or 15" echo "-N Selects both version numbers i.e. 14 and 15" echo "-u Selects \"UFS\" as the File System" echo "-U Selects both \"UFS\" versions" echo "-z Selects \"ZFS\" as the File System" echo "-Z Selects both \"ZFS\" versions" echo "-a Selects all available versions" } assertNotEmpty() { : "${!1:? "$1 is required, see help (-h) for more info."}" } download_image() { local FILENAME=$(basename "$URL") wget "$URL" unxz "$FILENAME" mv "${FILENAME%.*}" $IMAGE } create_template() { # create VM, resize the disk, import disk and create Cloud Init drive. Then set default settings for vm echo "Creating $VMID with name \"$DISTRO-template\""; qm create $VMID --agent $AGENT --balloon $BALLOON --memory $MEMORY --cores $CORES --bios $BIOS_TYPE --cpu $CPU_TYPE --efidisk0 $STORAGE:$EFI_OPTS --ide2 $STORAGE:cloudinit --machine $MACHINE_TYPE --ostype $OS_TYPE --scsihw $SCSI_TYPE --sockets $CPU_SOCKETS --name $DISTRO-template --net0 virtio,bridge=$BRIDGE > /dev/null echo "Resizing disk"; qemu-img resize $IMAGE 10G > /dev/null echo "Importing disk"; qm importdisk $VMID $IMAGE $STORAGE > /dev/null echo "Setting Virtual Drive to scsi0"; qm set $VMID --scsihw virtio-scsi-pci --scsi0 $STORAGE:vm-$VMID-disk-1,discard=on > /dev/null echo "Set bootdisk to scsi0"; qm set $VMID --boot c --bootdisk scsi0 > /dev/null # Define Cloud-Init parameters based on env file or the user interaction assertNotEmpty QM_CLOUDINIT && echo "Set Cloud Init params"; qm set $VMID $QM_CLOUDINIT > /dev/null echo Converting $VMID to Template; qm template $VMID > /dev/null echo Deleting $IMAGE file; rm $IMAGE echo "Your new ${DISTRO^} template is ready!" } while getopts hauUzZn:N:v:s: opt do case $opt in h) Help exit 0 ;; a) for key in "${!distro_array[@]}"; do distros["$key"]="${distro_array[$key]}" done ;; v) VMID=$OPTARG ;; u) FILE_SYSTEM="ufs" ;; U) distros["freebsd14-ufs"]="${distro_array[freebsd14-ufs]}" distros["freebsd15-ufs"]="${distro_array[freebsd15-ufs]}" ;; z) FILE_SYSTEM="zfs" ;; Z) distros["freebsd14-zfs"]="${distro_array[freebsd14-zfs]}" distros["freebsd15-zfs"]="${distro_array[freebsd15-zfs]}" ;; s) STORAGE=$OPTARG ;; n) if [[ $OPTARG -eq 14 || $OPTARG -eq 15 ]]; then VERSION=$OPTARG distros["freebsd$OPTARG-$FILE_SYSTEM"]="${distro_array[freebsd$OPTARG-$FILE_SYSTEM]}" else echo "Invalid selection. Choices are 14 or 15..." Help exit 1 fi ;; N) if [[ $OPTARG -eq 14 || $OPTARG -eq 15 ]]; then distros["freebsd$OPTARG-ufs"]="${distro_array[freebsd$OPTARG-ufs]}" distros["freebsd$OPTARG-zfs"]="${distro_array[freebsd$OPTARG-zfs]}" else echo "Invalid selection. Choices are 14 or 15..." Help exit 1 fi ;; \?) echo "Invalid Flag" exit 1 ;; esac done ########################## Start of Script ################################# NAME="freebsd${VERSION}" URL="${distro_array[freebsd$VERSION-$FILE_SYSTEM]}" assertNotEmpty VMID assertNotEmpty STORAGE if [ ${#distros[@]} -eq 0 ]; then distros["freebsd$VERSION-$FILE_SYSTEM"]="${distro_array[freebsd$VERSION-$FILE_SYSTEM]}" fi for DISTRO in ${!distros[@]}; do IMAGE=$NAME.qcow2 URL=${distros[$DISTRO]} download_image create_template ((VMID=VMID+1)) done