From c3ab9ae8305ec8ac41ab40539c9a34133bf08c50 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:08:44 +0200 Subject: [PATCH] Update unifi-os-vm.sh --- vm/unifi-os-vm.sh | 144 ++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/vm/unifi-os-vm.sh b/vm/unifi-os-vm.sh index 41239a6b..39dc54d7 100644 --- a/vm/unifi-os-vm.sh +++ b/vm/unifi-os-vm.sh @@ -9,11 +9,11 @@ source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-sc function header_info() { clear cat <<"EOF" - ____ __ _ ____ ___ - / __ \____ _____/ /_____ _____ | | / / |/ / - / / / / __ \/ ___/ //_/ _ \/ ___/ | | / / /|_/ / - / /_/ / /_/ / /__/ ,< / __/ / | |/ / / / / -/_____/\____/\___/_/|_|\___/_/ |___/_/ /_/ + __ __ _ _____ ____ _____ _____ + / / / /___ (_) __(_) / __ \/ ___/ / ___/___ ______ _____ _____ + / / / / __ \/ / /_/ / / / / /\__ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ +/ /_/ / / / / / __/ / / /_/ /___/ / ___/ / __/ / | |/ / __/ / +\____/_/ /_/_/_/ /_/ \____//____/ /____/\___/_/ |___/\___/_/ EOF } @@ -25,8 +25,8 @@ METHOD="" NSAPP="UniFi OS Server" var_os="linux" var_version="x64" -UOS_VERSION="4.2.23" -UOS_URL="https://fw-download.ubnt.com/data/unifi-os-server/8b93-linux-x64-4.2.23-158fa00b-6b2c-4cd8-94ea-e92bc4a81369.23-x64" +UOS_VERSION="4.3.5" +UOS_URL="https://fw-download.ubnt.com/data/unifi-os-server/da70-linux-x64-4.3.5-5306ffbb-fc6d-4414-912b-29cbfb0ce85a.5-x64" UOS_INSTALLER="unifi-os-server-${UOS_VERSION}.bin" YW=$(echo "\033[33m") @@ -62,19 +62,20 @@ VLANTAG="${TAB}🏷️${TAB}${CL}" CREATING="${TAB}🚀${TAB}${CL}" ADVANCED="${TAB}🧩${TAB}${CL}" THIN="discard=on,ssd=1," -set -e + +set -Eeuo pipefail trap 'error_handler $LINENO "$BASH_COMMAND"' ERR trap cleanup EXIT trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM + function error_handler() { local exit_code="$?" local line_number="$1" local command="$2" post_update_to_api "failed" "${command}" - local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}" - echo -e "\n$error_message\n" - cleanup_vmid + echo -e "\n${RD}[ERROR]${CL} line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing ${YW}$command${CL}\n" + if qm status $VMID &>/dev/null; then qm stop $VMID &>/dev/null || true; fi } function get_valid_nextid() { @@ -205,11 +206,11 @@ function exit-script() { function default_settings() { VMID=$(get_valid_nextid) FORMAT=",efitype=4m" - MACHINE="" + MACHINE="-machine q35" DISK_CACHE="" DISK_SIZE="30G" HN="unifi-server-os" - CPU_TYPE="" + CPU_TYPE="-cpu host" CORE_COUNT="2" RAM_SIZE="4096" BRG="vmbr0" @@ -435,102 +436,67 @@ start_script post_to_api_vm msg_info "Validating Storage" +STORAGE_MENU=() while read -r line; do TAG=$(echo $line | awk '{print $1}') TYPE=$(echo $line | awk '{printf "%-10s", $2}') FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') - ITEM=" Type: $TYPE Free: $FREE " - OFFSET=2 - if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then - MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) - fi - STORAGE_MENU+=("$TAG" "$ITEM" "OFF") + STORAGE_MENU+=("$TAG" "Type: $TYPE Free: $FREE" OFF) done < <(pvesm status -content images | awk 'NR>1') -VALID=$(pvesm status -content images | awk 'NR>1') -if [ -z "$VALID" ]; then - msg_error "Unable to detect a valid storage location." - exit -elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then + +if [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then STORAGE=${STORAGE_MENU[0]} else - while [ -z "${STORAGE:+x}" ]; do - STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ - "Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \ - 16 $(($MSG_MAX_LENGTH + 23)) 6 \ - "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) - done + STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" \ + --radiolist "Choose storage pool for UniFi OS VM" 16 70 6 "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) fi -msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location." -msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." -msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image" -URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2" -sleep 2 -msg_ok "${CL}${BL}${URL}${CL}" -curl -f#SL -o "$(basename "$URL")" "$URL" -echo -en "\e[1A\e[0K" -FILE=$(basename $URL) -msg_ok "Downloaded ${CL}${BL}${FILE}${CL}" +msg_ok "Using $STORAGE" -STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in -nfs | dir | cifs) - DISK_EXT=".qcow2" - DISK_REF="$VMID/" - DISK_IMPORT="-format qcow2" - THIN="" - ;; -btrfs) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - FORMAT=",efitype=4m" - THIN="" - ;; -esac -for i in {0,1}; do - disk="DISK$i" - eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} - eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} -done +# --- Download Debian Cloud Image --- +msg_info "Downloading Debian 13 Cloud Image" +URL="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-amd64.qcow2" +curl -fsSL -o debian-13-nocloud-amd64.qcow2 "$URL" +FILE="debian-13-nocloud-amd64.qcow2" +msg_ok "Downloaded Debian Cloud Image" +# --- Inject UniFi Installer --- if ! command -v virt-customize &>/dev/null; then - msg_info "Installing Pre-Requisite libguestfs-tools onto Host" + msg_info "Installing libguestfs-tools on host" apt-get -qq update >/dev/null - apt-get -qq install libguestfs-tools lsb-release -y >/dev/null - msg_ok "Installed libguestfs-tools successfully" + apt-get -qq install libguestfs-tools -y >/dev/null + msg_ok "Installed libguestfs-tools" fi -msg_info "Adding UniFi OS Server Installer & root Autologin zu Debian 12 Qcow2 Disk Image" -UOS_VERSION="4.2.23" -UOS_URL="https://fw-download.ubnt.com/data/unifi-os-server/8b93-linux-x64-4.2.23-158fa00b-6b2c-4cd8-94ea-e92bc4a81369.23-x64" -UOS_INSTALLER="unifi-os-server-${UOS_VERSION}.bin" -virt-customize -q -a "${FILE}" \ +msg_info "Injecting UniFi OS Installer into Cloud Image" +virt-customize -q -a "$FILE" \ --install qemu-guest-agent,ca-certificates,curl,lsb-release,podman \ --run-command "curl -fsSL '${UOS_URL}' -o /root/${UOS_INSTALLER} && chmod +x /root/${UOS_INSTALLER}" \ --run-command 'mkdir -p /etc/systemd/system/getty@tty1.service.d' \ --run-command "bash -c 'echo -e \"[Service]\nExecStart=\nExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM\" > /etc/systemd/system/getty@tty1.service.d/override.conf'" \ - --run-command 'systemctl daemon-reload' \ - --run-command 'systemctl restart getty@tty1' >/dev/null -msg_ok "Installer & root Autologin integrated in image" + >/dev/null +msg_ok "UniFi OS Installer integrated" -msg_info "Expanding root partition to use full disk space" -qemu-img create -f qcow2 expanded.qcow2 ${DISK_SIZE} >/dev/null 2>&1 -virt-resize --expand /dev/sda1 ${FILE} expanded.qcow2 >/dev/null 2>&1 -mv expanded.qcow2 ${FILE} >/dev/null 2>&1 -msg_ok "Expanded image to full size" +msg_info "Creating UniFi OS VM" +qm create "$VMID" -agent 1 $MACHINE -tablet 0 -localtime 1 -bios ovmf \ + $CPU_TYPE -cores "$CORE_COUNT" -memory "$RAM_SIZE" \ + -name "$HN" -tags community-script \ + -net0 virtio,bridge="$BRG",macaddr="$MAC""$VLAN""$MTU" \ + -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -msg_info "Creating a Unifi OS VM" -qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \ - -name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci -pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null -qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null -qm set $VMID \ - -efidisk0 ${DISK0_REF}${FORMAT} \ - -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \ - -boot order=scsi0 \ - -serial0 socket >/dev/null -qm resize $VMID scsi0 8G >/dev/null -qm set $VMID --agent enabled=1 >/dev/null +pvesm alloc "$STORAGE" "$VMID" "vm-$VMID-disk-0" 4M >/dev/null +IMPORT_OUT="$(qm importdisk "$VMID" "$FILE" "$STORAGE" --format qcow2 2>&1 || true)" +DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p")" + +if [[ -z "$DISK_REF" ]]; then + DISK_REF="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$1 ~ ("vm-"id"-disk-") {print $1}' | sort | tail -n1)" +fi + +qm set "$VMID" \ + -efidisk0 "${STORAGE}:0${FORMAT},size=4M" \ + -scsi0 "${DISK_REF},size=${DISK_SIZE}" \ + -boot order=scsi0 -serial0 socket >/dev/null +qm resize "$VMID" scsi0 "$DISK_SIZE" >/dev/null +qm set "$VMID" --agent enabled=1 >/dev/null DESCRIPTION=$( cat <