Advertisement
gersonfer

Untitled

Dec 5th, 2024
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 15.22 KB | Source Code | 0 0
  1. #!/usr/bin/env bash
  2.  
  3. # Copyright (c) 2021-2024 tteck
  4. # Author: tteck (tteckster)
  5. # License: MIT
  6. # https://github.com/tteck/Proxmox/raw/main/LICENSE
  7.  
  8. function header_info {
  9.   clear
  10.   cat <<"EOF"
  11.     __  __                        ___              _      __              __     ____  _____
  12.    / / / /___  ____ ___  ___     /   |  __________(_)____/ /_____ _____  / /_   / __ \/ ___/
  13.   / /_/ / __ \/ __ `__ \/ _ \   / /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/  / / / /\__ \
  14.  / __  / /_/ / / / / / /  __/  / ___ |(__  |__  ) (__  ) /_/ /_/ / / / / /_   / /_/ /___/ /
  15. /_/ /_/\____/_/ /_/ /_/\___/  /_/  |_/____/____/_/____/\__/\__,_/_/ /_/\__/   \____//____/
  16.  
  17. EOF
  18. }
  19. header_info
  20. echo -e "\n Loading..."
  21. GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
  22. NEXTID=$(pvesh get /cluster/nextid)
  23. VERSIONS=(stable beta dev)
  24. for version in "${VERSIONS[@]}"; do
  25.   eval "$version=$(curl -s https://raw.githubusercontent.com/home-assistant/version/master/$version.json | grep "ova" | cut -d '"' -f 4)"
  26. done
  27. YW=$(echo "\033[33m")
  28. BL=$(echo "\033[36m")
  29. HA=$(echo "\033[1;34m")
  30. RD=$(echo "\033[01;31m")
  31. BGN=$(echo "\033[4;92m")
  32. GN=$(echo "\033[1;92m")
  33. DGN=$(echo "\033[32m")
  34. CL=$(echo "\033[m")
  35. BFR="\\r\\033[K"
  36. HOLD=" "
  37. CM="${GN}${CL}"
  38. CROSS="${RD}${CL}"
  39. THIN="discard=on,ssd=1,"
  40. SPINNER_PID=""
  41. set -Eeuo pipefail
  42. trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
  43. trap cleanup EXIT
  44.  
  45. function error_handler() {
  46.   if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
  47.   printf "\e[?25h"
  48.   local exit_code="$?"
  49.   local line_number="$1"
  50.   local command="$2"
  51.   local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
  52.   echo -e "\n$error_message\n"
  53.   cleanup_vmid
  54. }
  55.  
  56. function cleanup_vmid() {
  57.   if qm status $VMID &>/dev/null; then
  58.     qm stop $VMID &>/dev/null
  59.     qm destroy $VMID &>/dev/null
  60.   fi
  61. }
  62.  
  63. function cleanup() {
  64.   popd >/dev/null
  65.   rm -rf $TEMP_DIR
  66. }
  67.  
  68. TEMP_DIR=$(mktemp -d)
  69. pushd $TEMP_DIR >/dev/null
  70. if whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOME ASSISTANT OS VM" --yesno "This will create a New Home Assistant OS VM. Proceed?" 10 58; then
  71.   :
  72. else
  73.   header_info && echo -e "⚠ User exited script \n" && exit
  74. fi
  75.  
  76. function spinner() {
  77.     local chars="/-\|"
  78.     local spin_i=0
  79.     printf "\e[?25l"
  80.     while true; do
  81.         printf "\r \e[36m%s\e[0m" "${chars:spin_i++%${#chars}:1}"
  82.         sleep 0.1
  83.     done
  84. }
  85.  
  86. function msg_info() {
  87.   local msg="$1"
  88.   echo -ne " ${HOLD} ${YW}${msg}   "
  89.   spinner &
  90.   SPINNER_PID=$!
  91. }
  92.  
  93. function msg_ok() {
  94.   if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
  95.   printf "\e[?25h"
  96.   local msg="$1"
  97.   echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
  98. }
  99.  
  100. function msg_error() {
  101.   if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
  102.   printf "\e[?25h"
  103.   local msg="$1"
  104.   echo -e "${BFR} ${CROSS} ${RD}${msg}${CL}"
  105. }
  106.  
  107. function check_root() {
  108.   if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
  109.     clear
  110.     msg_error "Please run this script as root."
  111.     echo -e "\nExiting..."
  112.     sleep 2
  113.     exit
  114.   fi
  115. }
  116.  
  117. function pve_check() {
  118.   if ! pveversion | grep -Eq "pve-manager/8.[1-3]"; then
  119.     msg_error "This version of Proxmox Virtual Environment is not supported"
  120.     echo -e "Requires Proxmox Virtual Environment Version 8.1 or later."
  121.     echo -e "Exiting..."
  122.     sleep 2
  123.     exit
  124. fi
  125. }
  126.  
  127. function arch_check() {
  128.   if [ "$(dpkg --print-architecture)" != "amd64" ]; then
  129.     msg_error "This script will not work with PiMox! \n"
  130.     echo -e "Exiting..."
  131.     sleep 2
  132.     exit
  133.   fi
  134. }
  135.  
  136. function ssh_check() {
  137.   if command -v pveversion >/dev/null 2>&1; then
  138.     if [ -n "${SSH_CLIENT:+x}" ]; then
  139.       if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
  140.         echo "you've been warned"
  141.       else
  142.         clear
  143.         exit
  144.       fi
  145.     fi
  146.   fi
  147. }
  148.  
  149. function exit-script() {
  150.   clear
  151.   echo -e "⚠  User exited script \n"
  152.   exit
  153. }
  154.  
  155. function default_settings() {
  156.   BRANCH="$stable"
  157.   VMID="$NEXTID"
  158.   FORMAT=",efitype=4m"
  159.   MACHINE=""
  160.   DISK_CACHE="cache=writethrough,"
  161.   HN="haos$stable"
  162.   CPU_TYPE=" -cpu host"
  163.   CORE_COUNT="2"
  164.   RAM_SIZE="4096"
  165.   BRG="vmbr0"
  166.   MAC="$GEN_MAC"
  167.   VLAN=""
  168.   MTU=""
  169.   START_VM="yes"
  170.   echo -e "${DGN}Using HAOS Version: ${BGN}${BRANCH}${CL}"
  171.   echo -e "${DGN}Using Virtual Machine ID: ${BGN}${VMID}${CL}"
  172.   echo -e "${DGN}Using Machine Type: ${BGN}i440fx${CL}"
  173.   echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}"
  174.   echo -e "${DGN}Using Hostname: ${BGN}${HN}${CL}"
  175.   echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}"
  176.   echo -e "${DGN}Allocated Cores: ${BGN}${CORE_COUNT}${CL}"
  177.   echo -e "${DGN}Allocated RAM: ${BGN}${RAM_SIZE}${CL}"
  178.   echo -e "${DGN}Using Bridge: ${BGN}${BRG}${CL}"
  179.   echo -e "${DGN}Using MAC Address: ${BGN}${MAC}${CL}"
  180.   echo -e "${DGN}Using VLAN: ${BGN}Default${CL}"
  181.   echo -e "${DGN}Using Interface MTU Size: ${BGN}Default${CL}"
  182.   echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}"
  183.   echo -e "${BL}Creating a HAOS VM using the above default settings${CL}"
  184. }
  185.  
  186. function advanced_settings() {
  187.   if BRANCH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "HAOS VERSION" --radiolist "Choose Version" --cancel-button Exit-Script 10 58 3 \
  188.     "$stable" "Stable  " ON \
  189.     "$beta" "Beta  " OFF \
  190.     "$dev" "Dev  " OFF \
  191.     3>&1 1>&2 2>&3); then
  192.     echo -e "${DGN}Using HAOS Version: ${BGN}$BRANCH${CL}"
  193.   else
  194.     exit-script
  195.   fi
  196.  
  197.   while true; do
  198.     if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $NEXTID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  199.       if [ -z "$VMID" ]; then
  200.         VMID="$NEXTID"
  201.       fi
  202.       if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
  203.         echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
  204.         sleep 2
  205.         continue
  206.       fi
  207.       echo -e "${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
  208.       break
  209.     else
  210.       exit-script
  211.     fi
  212.   done
  213.  
  214.   if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
  215.     "i440fx" "Machine i440fx" ON \
  216.     "q35" "Machine q35" OFF \
  217.     3>&1 1>&2 2>&3); then
  218.     if [ $MACH = q35 ]; then
  219.       echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}"
  220.       FORMAT=""
  221.       MACHINE=" -machine q35"
  222.     else
  223.       echo -e "${DGN}Using Machine Type: ${BGN}$MACH${CL}"
  224.       FORMAT=",efitype=4m"
  225.       MACHINE=""
  226.     fi
  227.   else
  228.     exit-script
  229.   fi
  230.  
  231.   if DISK_CACHE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
  232.     "0" "None" OFF \
  233.     "1" "Write Through (Default)" ON \
  234.     3>&1 1>&2 2>&3); then
  235.     if [ $DISK_CACHE1 = "1" ]; then
  236.       echo -e "${DGN}Using Disk Cache: ${BGN}Write Through${CL}"
  237.       DISK_CACHE="cache=writethrough,"
  238.     else
  239.       echo -e "${DGN}Using Disk Cache: ${BGN}None${CL}"
  240.       DISK_CACHE=""
  241.     fi
  242.   else
  243.     exit-script
  244.   fi
  245.  
  246.   if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 haos${BRANCH} --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  247.     if [ -z $VM_NAME ]; then
  248.       HN="haos${BRANCH}"
  249.       echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"
  250.     else
  251.       HN=$(echo ${VM_NAME,,} | tr -d ' ')
  252.       echo -e "${DGN}Using Hostname: ${BGN}$HN${CL}"
  253.     fi
  254.   else
  255.     exit-script
  256.   fi
  257.  
  258.   if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
  259.     "0" "KVM64" OFF \
  260.     "1" "Host (Default)" ON \
  261.     3>&1 1>&2 2>&3); then
  262.     if [ $CPU_TYPE1 = "1" ]; then
  263.       echo -e "${DGN}Using CPU Model: ${BGN}Host${CL}"
  264.       CPU_TYPE=" -cpu host"
  265.     else
  266.       echo -e "${DGN}Using CPU Model: ${BGN}KVM64${CL}"
  267.       CPU_TYPE=""
  268.     fi
  269.   else
  270.     exit-script
  271.   fi
  272.  
  273.   if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  274.     if [ -z $CORE_COUNT ]; then
  275.       CORE_COUNT="2"
  276.       echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"
  277.     else
  278.       echo -e "${DGN}Allocated Cores: ${BGN}$CORE_COUNT${CL}"
  279.     fi
  280.   else
  281.     exit-script
  282.   fi
  283.  
  284.   if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  285.     if [ -z $RAM_SIZE ]; then
  286.       RAM_SIZE="4096"
  287.       echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"
  288.     else
  289.       echo -e "${DGN}Allocated RAM: ${BGN}$RAM_SIZE${CL}"
  290.     fi
  291.   else
  292.     exit-script
  293.   fi
  294.  
  295.   if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  296.     if [ -z $BRG ]; then
  297.       BRG="vmbr0"
  298.       echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"
  299.     else
  300.       echo -e "${DGN}Using Bridge: ${BGN}$BRG${CL}"
  301.     fi
  302.   else
  303.     exit-script
  304.   fi
  305.  
  306.   if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  307.     if [ -z $MAC1 ]; then
  308.       MAC="$GEN_MAC"
  309.       echo -e "${DGN}Using MAC Address: ${BGN}$MAC${CL}"
  310.     else
  311.       MAC="$MAC1"
  312.       echo -e "${DGN}Using MAC Address: ${BGN}$MAC1${CL}"
  313.     fi
  314.   else
  315.     exit-script
  316.   fi
  317.  
  318.   if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  319.     if [ -z $VLAN1 ]; then
  320.       VLAN1="Default"
  321.       VLAN=""
  322.       echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}"
  323.     else
  324.       VLAN=",tag=$VLAN1"
  325.       echo -e "${DGN}Using Vlan: ${BGN}$VLAN1${CL}"
  326.     fi
  327.   else
  328.     exit-script
  329.   fi
  330.  
  331.   if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
  332.     if [ -z $MTU1 ]; then
  333.       MTU1="Default"
  334.       MTU=""
  335.       echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}"
  336.     else
  337.       MTU=",mtu=$MTU1"
  338.       echo -e "${DGN}Using Interface MTU Size: ${BGN}$MTU1${CL}"
  339.     fi
  340.   else
  341.     exit-script
  342.   fi
  343.  
  344.   if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
  345.     echo -e "${DGN}Start VM when completed: ${BGN}yes${CL}"
  346.     START_VM="yes"
  347.   else
  348.     echo -e "${DGN}Start VM when completed: ${BGN}no${CL}"
  349.     START_VM="no"
  350.   fi
  351.  
  352.   if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create HAOS ${BRANCH} VM?" --no-button Do-Over 10 58); then
  353.     echo -e "${RD}Creating a HAOS VM using the above advanced settings${CL}"
  354.   else
  355.     header_info
  356.     echo -e "${RD}Using Advanced Settings${CL}"
  357.     advanced_settings
  358.   fi
  359. }
  360.  
  361. function start_script() {
  362.   if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
  363.     header_info
  364.     echo -e "${BL}Using Default Settings${CL}"
  365.     default_settings
  366.   else
  367.     header_info
  368.     echo -e "${RD}Using Advanced Settings${CL}"
  369.     advanced_settings
  370.   fi
  371. }
  372.  
  373. check_root
  374. arch_check
  375. pve_check
  376. ssh_check
  377. start_script
  378.  
  379. msg_info "Validating Storage"
  380. while read -r line; do
  381.   TAG=$(echo $line | awk '{print $1}')
  382.   TYPE=$(echo $line | awk '{printf "%-10s", $2}')
  383.   FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
  384.   ITEM="  Type: $TYPE Free: $FREE "
  385.   OFFSET=2
  386.   if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
  387.     MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
  388.   fi
  389.   STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
  390. done < <(pvesm status -content images | awk 'NR>1')
  391. VALID=$(pvesm status -content images | awk 'NR>1')
  392. if [ -z "$VALID" ]; then
  393.   msg_error "Unable to detect a valid storage location."
  394.   exit
  395. elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
  396.   STORAGE=${STORAGE_MENU[0]}
  397. else
  398.   while [ -z "${STORAGE:+x}" ]; do
  399.     if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID > /dev/null; then kill $SPINNER_PID > /dev/null; fi
  400.     printf "\e[?25h"
  401.     STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
  402.       "Which storage pool you would like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
  403.       16 $(($MSG_MAX_LENGTH + 23)) 6 \
  404.       "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit
  405.   done
  406. fi
  407. msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
  408. msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
  409. msg_info "Retrieving the URL for Home Assistant ${BRANCH} Disk Image"
  410. if [ "$BRANCH" == "$dev" ]; then
  411.   URL=https://os-artifacts.home-assistant.io/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz
  412. else
  413.   URL=https://github.com/home-assistant/operating-system/releases/download/${BRANCH}/haos_ova-${BRANCH}.qcow2.xz
  414. fi
  415. sleep 2
  416. msg_ok "${CL}${BL}${URL}${CL}"
  417. wget -q --show-progress $URL
  418. echo -en "\e[1A\e[0K"
  419. FILE=$(basename $URL)
  420. msg_ok "Downloaded ${CL}${BL}haos_ova-${BRANCH}.qcow2.xz${CL}"
  421. msg_info "Extracting KVM Disk Image"
  422. unxz $FILE
  423. STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')
  424. case $STORAGE_TYPE in
  425. nfs | dir)
  426.   DISK_EXT=".raw"
  427.   DISK_REF="$VMID/"
  428.   DISK_IMPORT="-format raw"
  429.   THIN=""
  430.   ;;
  431. btrfs | local-zfs)
  432.   DISK_EXT=".raw"
  433.   DISK_REF="$VMID/"
  434.   DISK_IMPORT="-format raw"
  435.   FORMAT=",efitype=4m"
  436.   THIN=""
  437.   ;;
  438. esac
  439. for i in {0,1}; do
  440.   disk="DISK$i"
  441.   eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
  442.   eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
  443. done
  444. msg_ok "Extracted KVM Disk Image"
  445. msg_info "Creating HAOS VM"
  446. qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
  447.   -name $HN -tags proxmox-helper-scripts -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
  448. pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
  449. qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
  450. qm set $VMID \
  451.   -efidisk0 ${DISK0_REF}${FORMAT} \
  452.   -scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=32G \
  453.   -boot order=scsi0 \
  454.   -description "<div align='center'><a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'><img src='https://raw.githubusercontent.com/tteck/Proxmox/main/misc/images/logo-81x112.png'/></a>
  455.  
  456.  # Home Assistant OS
  457.  
  458.  <a href='https://ko-fi.com/D1D7EP4GF'><img src='https://img.shields.io/badge/&#x2615;-Buy me a coffee-blue' /></a>
  459.  </div>" >/dev/null
  460. msg_ok "Created HAOS VM ${CL}${BL}(${HN})"
  461. if [ "$START_VM" == "yes" ]; then
  462.   msg_info "Starting Home Assistant OS VM"
  463.   qm start $VMID
  464.   msg_ok "Started Home Assistant OS VM"
  465. fi
  466. msg_ok "Completed Successfully!\n"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement