From 80d75731a825365e3941d9b37014be76a113f705 Mon Sep 17 00:00:00 2001 From: CanbiZ <47820557+MickLesk@users.noreply.github.com> Date: Mon, 1 Sep 2025 15:02:10 +0200 Subject: [PATCH] Refactor + Feature Bump: HomeAssistant OS (#7336) --- vm/haos-vm.sh | 153 ++++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/vm/haos-vm.sh b/vm/haos-vm.sh index 854551921..30c71efbc 100644 --- a/vm/haos-vm.sh +++ b/vm/haos-vm.sh @@ -208,11 +208,11 @@ function exit-script() { function default_settings() { BRANCH="$stable" VMID=$(get_valid_nextid) - FORMAT=",efitype=4m" - MACHINE="" - DISK_CACHE="cache=writethrough," - HN="haos$stable" - CPU_TYPE=" -cpu host" + MACHINE="q35" + FORMAT="" + DISK_SIZE="32G" + HN="haos-${BRANCH}" + CPU_TYPE="" CORE_COUNT="2" RAM_SIZE="4096" BRG="vmbr0" @@ -222,9 +222,8 @@ function default_settings() { START_VM="yes" METHOD="default" echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}" - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}" echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}" - echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}" echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}" echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}" echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}" @@ -268,16 +267,16 @@ function advanced_settings() { fi done - if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \ - "i440fx" "Machine i440fx" ON \ - "q35" "Machine q35" OFF \ + if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Machine Type" 10 58 2 \ + "q35" "Modern (PCIe, UEFI, default)" ON \ + "i440fx" "Legacy (older compatibility)" OFF \ 3>&1 1>&2 2>&3); then - if [ $MACH = q35 ]; then - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}" + if [ "$MACH" = "q35" ]; then + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}q35${CL}" FORMAT="" MACHINE=" -machine q35" else - echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}" + echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}" FORMAT=",efitype=4m" MACHINE="" fi @@ -327,17 +326,20 @@ function advanced_settings() { exit-script fi - if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \ - "0" "KVM64" OFF \ - "1" "Host (Default)" ON \ + if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose CPU Model" --cancel-button Exit-Script 10 58 2 \ + "KVM64" "Default – safe for migration/compatibility" ON \ + "Host" "Use host CPU features (faster, no migration)" OFF \ 3>&1 1>&2 2>&3); then - if [ $CPU_TYPE1 = "1" ]; then + case "$CPU_TYPE1" in + Host) echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}" CPU_TYPE=" -cpu host" - else + ;; + *) echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}" CPU_TYPE="" - fi + ;; + esac else exit-script fi @@ -484,51 +486,70 @@ msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}." var_version="${BRANCH}" msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image" if [ "$BRANCH" == "$dev" ]; then - URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz + URL="https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz" else - URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz + URL="https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz" fi -sleep 2 + +CACHE_DIR="/var/lib/vz/template/cache" +CACHE_FILE="$CACHE_DIR/$(basename "$URL")" +FILE_IMG="/var/lib/vz/template/tmp/${CACHE_FILE##*/%.xz}" # .qcow2 + +mkdir -p "$CACHE_DIR" "$(dirname "$FILE_IMG")" 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}haos_ova-${BRANCH}.qcow2.xz${CL}" -msg_info "Extracting KVM Disk Image" -unxz $FILE -STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}') -case $STORAGE_TYPE in -nfs | dir) - DISK_EXT=".raw" - DISK_REF="$VMID/" - DISK_IMPORT="-format raw" - THIN="" - ;; -btrfs | local-zfs) - 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 -msg_ok "Extracted KVM Disk Image" +if [[ ! -s "$CACHE_FILE" ]]; then + curl -f#SL -o "$CACHE_FILE" "$URL" + msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}" +else + msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}" +fi -msg_info "Creating Homeassistant 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=32G \ - -boot order=scsi0 >/dev/null +if ! command -v pv &>/dev/null; then + apt-get update -qq &>/dev/null && apt-get install -y pv &>/dev/null +fi + +set -o pipefail +msg_info "Creating Home Assistant OS VM shell" +qm create "$VMID" -machine q35 -bios ovmf -agent 1 -tablet 0 -localtime 1 ${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 >/dev/null +msg_ok "Created VM shell" + +msg_info "Decompressing $(basename "$CACHE_FILE") to $FILE_IMG" +xz -dc "$CACHE_FILE" | pv -N "Extracting" >"$FILE_IMG" +msg_ok "Decompressed to $FILE_IMG" + +msg_info "Importing disk into storage ($STORAGE)" +if qm disk import --help >/dev/null 2>&1; then + IMPORT_CMD=(qm disk import) +else + IMPORT_CMD=(qm importdisk) +fi +IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "$FILE_IMG" "$STORAGE" --format raw 2>&1 || true)" +DISK_REF="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")" +[[ -z "$DISK_REF" ]] && DISK_REF="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)" +[[ -z "$DISK_REF" ]] && { + msg_error "Unable to determine imported disk reference." + echo "$IMPORT_OUT" + exit 1 +} +msg_ok "Imported disk (${CL}${BL}${DISK_REF}${CL})" + +rm -f "$FILE_IMG" + +msg_info "Attaching EFI and root disk" +qm set "$VMID" \ + --efidisk0 "${STORAGE}:0,efitype=4m" \ + --scsi0 "${DISK_REF},ssd=1,discard=on" \ + --boot order=scsi0 \ + --serial0 socket >/dev/null +qm set "$VMID" --agent enabled=1 >/dev/null +msg_ok "Attached EFI and root disk" + +msg_info "Resizing disk to $DISK_SIZE" +qm resize "$VMID" scsi0 "${DISK_SIZE}" >/dev/null +msg_ok "Resized disk" DESCRIPTION=$( cat < EOF ) - qm set "$VMID" -description "$DESCRIPTION" >/dev/null -if [ -n "$DISK_SIZE" ]; then - msg_info "Resizing disk to $DISK_SIZE GB" - qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null +msg_ok "Created Homeassistant OS VM ${CL}${BL}(${HN})" + +if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Image Cache" \ + --yesno "Keep downloaded Home Assistant OS image for future VMs?\n\nFile: $CACHE_FILE" 10 70; then + msg_ok "Keeping cached image" else - msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB" - qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null + rm -f "$CACHE_FILE" + msg_ok "Deleted cached image" fi -msg_ok "Created Homeassistant OS VM ${CL}${BL}(${HN})" if [ "$START_VM" == "yes" ]; then msg_info "Starting Home Assistant OS VM" qm start $VMID