├── LICENSE ├── README.md └── install.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 whiskerz007 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # New Proxmox VM with Home Assistant 2 | 3 | This script will create a new Proxmox VM with the latest version of Home Assistant. To create a new VM, run the following in a SSH session or the console from Proxmox interface 4 | 5 | ``` 6 | bash -c "$(wget -qLO - https://github.com/whiskerz007/proxmox_hassos_install/raw/master/install.sh)" 7 | ``` 8 | 9 | After script completes, click on the new VM (_the script will tell you the ID_), click on the `Hardware` tab for the VM and change the `Memory` and `Processors` settings to what you desire. The `Hard Disk` can be expanded by clicking on it, then click on the `Resize disk` button above (_Note: additional steps must be taken for storage to take effect in the VM after the first boot_). The network MAC address can be changed by selecting `Network Device` and clicking `Edit` above. Once all changes have been made, click `Start` above. 10 | 11 | ## Root Prompt 12 | 13 | To get to the root prompt 14 | - Open the console after the VM has been started 15 | - When the messages slow down press the `Enter` key a couple of times until you see the following 16 | ``` 17 | 18 | Welcome to Home Assistant 19 | homeassistant login: 20 | ``` 21 | - Login using `root`, no password is requested 22 | - When you see the `hassio > ` prompt, type `login` 23 | - You should now see a `# ` prompt. 24 | 25 | ## Add a serial port 26 | 27 | By adding a serial port, you are able to use a different interface to interact with the VM. When you click on the down arrow next to `Console` you will be able to use `xterm.js` which enables you to `Right-Click` and get access to `Copy` and `Paste` functions. If the serial port was already added by the install script, no further actions are required to enable the functionality. 28 | - Click on the VM in the list of containers at the left side panel 29 | - Click `Hardware` tab located beside the list of containers 30 | - Click `Add` located beside `Summary` tab, then click `Serial Port` 31 | - `Serial Port` should be set to `0` in the input box, then click `Add` 32 | - Start the VM, if it isn't already 33 | - At the root prompt type `sed -i 's/$/ console=ttyS0/' /mnt/boot/cmdline.txt` 34 | - A `Shutdown` and `Start` is required for the changes to take effect 35 | 36 | ## Show Current IP Address 37 | 38 | To get the current IP address assigned to the VM from the Proxmox interface 39 | - Click on the VM in the list of containers at the left side panel 40 | - Click `Summary` tab located beside the list of containers 41 | - Click `More` near `IPs` in the top left section 42 | - You can find the assigned IP addresses on the line with the name similar to `enp0s18` 43 | 44 | To get the current IP address assigned to the VM from the command line 45 | - At the root prompt type `nmcli -g ip4.address d sh $(nmcli -g device c)` 46 | - The response will be the IP address with subnet mask or nothing 47 | 48 | **Note:** _If DHCP is configured and nothing is shown, check DHCP server and VM network settings_ 49 | 50 | ## Configure Network for Static IP Address 51 | 52 | To set a static IP address, use the following as an example 53 | - At the root prompt type `nmcli c mod $(nmcli -g uuid c) ipv4.method manual ipv4.addresses "192.168.20.170/24" ipv4.gateway "192.168.20.1" ipv4.dns "8.8.8.8,8.8.4.4"` 54 | - At the root prompt type `nmcli c up $(nmcli -g uuid c)` 55 | 56 | ## Configure Network for DHCP 57 | 58 | To remove all static IP addresses and enable DHCP 59 | - At the root prompt type `nmcli c mod $(nmcli -g uuid c) ipv4.method auto ipv4.addresses "" ipv4.gateway "" ipv4.dns ""` 60 | - At the root prompt type `nmcli c up $(nmcli -g uuid c)` 61 | 62 | ## Default Interface Name 63 | 64 | To get the default interface name 65 | - At the root prompt type `nmcli -g device c` 66 | - The response with be the interface name 67 | 68 | ## Change Hostname 69 | 70 | To change the HassOS VM hostname 71 | - At the root prompt type `hostnamectl set-hostname your-new-hostname` 72 | - You can verify the change by logging out with `exit`, the last line printed will be `your-new-hostname login: ` 73 | 74 | ## Resize Disk 75 | 76 | To resize the disk after the first boot 77 | - At the root prompt type `df -h /dev/sda8` and note the `Size` 78 | - Shutdown the VM 79 | - Resize the disk to the desired size 80 | - At the root prompt type `sgdisk -e /dev/sda` 81 | - At the root prompt type `reboot` 82 | - Verify resize was successful by typing `df -h /dev/sda8` at the root prompt 83 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Setup script environment 4 | set -o errexit #Exit immediately if a pipeline returns a non-zero status 5 | set -o errtrace #Trap ERR from shell functions, command substitutions, and commands from subshell 6 | set -o nounset #Treat unset variables as an error 7 | set -o pipefail #Pipe will exit with last non-zero status if applicable 8 | shopt -s expand_aliases 9 | alias die='EXIT=$? LINE=$LINENO error_exit' 10 | trap die ERR 11 | trap cleanup EXIT 12 | 13 | function error_exit() { 14 | trap - ERR 15 | local DEFAULT='Unknown failure occured.' 16 | local REASON="\e[97m${1:-$DEFAULT}\e[39m" 17 | local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" 18 | msg "$FLAG $REASON" 19 | [ ! -z ${VMID-} ] && cleanup_vmid 20 | exit $EXIT 21 | } 22 | function warn() { 23 | local REASON="\e[97m$1\e[39m" 24 | local FLAG="\e[93m[WARNING]\e[39m" 25 | msg "$FLAG $REASON" 26 | } 27 | function info() { 28 | local REASON="$1" 29 | local FLAG="\e[36m[INFO]\e[39m" 30 | msg "$FLAG $REASON" 31 | } 32 | function msg() { 33 | local TEXT="$1" 34 | echo -e "$TEXT" 35 | } 36 | function cleanup_vmid() { 37 | if $(qm status $VMID &>/dev/null); then 38 | if [ "$(qm status $VMID | awk '{print $2}')" == "running" ]; then 39 | qm stop $VMID 40 | fi 41 | qm destroy $VMID 42 | fi 43 | } 44 | function cleanup() { 45 | popd >/dev/null 46 | rm -rf $TEMP_DIR 47 | } 48 | TEMP_DIR=$(mktemp -d) 49 | pushd $TEMP_DIR >/dev/null 50 | 51 | # Select storage location 52 | while read -r line; do 53 | TAG=$(echo $line | awk '{print $1}') 54 | TYPE=$(echo $line | awk '{printf "%-10s", $2}') 55 | FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}') 56 | ITEM=" Type: $TYPE Free: $FREE " 57 | OFFSET=2 58 | if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then 59 | MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET)) 60 | fi 61 | STORAGE_MENU+=( "$TAG" "$ITEM" "OFF" ) 62 | done < <(pvesm status -content images | awk 'NR>1') 63 | if [ $((${#STORAGE_MENU[@]}/3)) -eq 0 ]; then 64 | warn "'Disk image' needs to be selected for at least one storage location." 65 | die "Unable to detect valid storage location." 66 | elif [ $((${#STORAGE_MENU[@]}/3)) -eq 1 ]; then 67 | STORAGE=${STORAGE_MENU[0]} 68 | else 69 | while [ -z "${STORAGE:+x}" ]; do 70 | STORAGE=$(whiptail --title "Storage Pools" --radiolist \ 71 | "Which storage pool you would like to use for the container?\n\n" \ 72 | 16 $(($MSG_MAX_LENGTH + 23)) 6 \ 73 | "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit 74 | done 75 | fi 76 | info "Using '$STORAGE' for storage location." 77 | 78 | # Get the next guest VM/LXC ID 79 | VMID=$(pvesh get /cluster/nextid) 80 | info "Container ID is $VMID." 81 | 82 | # Get latest Home Assistant disk image archive URL 83 | msg "Getting URL for latest Home Assistant disk image..." 84 | RELEASE_TYPE=vmdk 85 | URL=$(cat<1 {print $2}') 121 | if [ "$STORAGE_TYPE" = "dir" ]; then 122 | DISK_EXT=".qcow2" 123 | DISK_REF="$VMID/" 124 | IMPORT_OPT="-format qcow2" 125 | fi 126 | for i in {0,1}; do 127 | disk="DISK$i" 128 | eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-} 129 | eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk} 130 | done 131 | 132 | # Create VM 133 | msg "Creating VM..." 134 | VM_NAME=$(sed -e "s/\_//g" -e "s/.${RELEASE_TYPE}.*$//" <<< $FILE) 135 | qm create $VMID -agent 1 -bios ovmf -name $VM_NAME -net0 virtio,bridge=vmbr0 \ 136 | -onboot 1 -ostype l26 -scsihw virtio-scsi-pci 137 | pvesm alloc $STORAGE $VMID $DISK0 128 1>&/dev/null 138 | qm importdisk $VMID ${FILE%.*} $STORAGE ${IMPORT_OPT:-} 1>&/dev/null 139 | qm set $VMID \ 140 | -efidisk0 ${DISK0_REF},size=128K \ 141 | -sata0 ${DISK1_REF},size=6G > /dev/null 142 | qm set $VMID \ 143 | -boot order=sata0 > /dev/null 144 | 145 | # Add serial port and enable console output 146 | set +o errtrace 147 | ( 148 | msg "Adding serial port and configuring console..." 149 | trap ' 150 | warn "Unable to configure serial port. VM is still functional." 151 | if [ "$(qm config $VMID | sed -n ''/serial0/p'')" != "" ]; then 152 | qm set $VMID --delete serial0 >/dev/null 153 | fi 154 | exit 155 | ' ERR 156 | if [ "$(command -v kpartx)" = "" ]; then 157 | msg "Installing 'kpartx'..." 158 | apt-get update >/dev/null 159 | apt-get -qqy install kpartx &>/dev/null 160 | fi 161 | DISK1_PATH="$(pvesm path $DISK1_REF)" 162 | DISK1_PART1="$(kpartx -al $DISK1_PATH | awk 'NR==1 {print $1}')" 163 | DISK1_PART1_PATH="/dev/mapper/$DISK1_PART1" 164 | TEMP_MOUNT="${TEMP_DIR}/mnt" 165 | trap ' 166 | findmnt $TEMP_MOUNT >/dev/null && umount $TEMP_MOUNT 167 | command -v kpartx >/dev/null && kpartx -d $DISK1_PATH 168 | ' EXIT 169 | kpartx -a $DISK1_PATH 170 | mkdir $TEMP_MOUNT 171 | mount $DISK1_PART1_PATH $TEMP_MOUNT 172 | sed -i 's/$/ console=ttyS0/' ${TEMP_MOUNT}/cmdline.txt 173 | qm set $VMID -serial0 socket >/dev/null 174 | ) 175 | 176 | info "Completed Successfully! New VM ID is \e[1m$VMID\e[0m." 177 | --------------------------------------------------------------------------------