How to: Setup HassOS on a KVM Virtual Machine


EDIT: I gave in and made the switch to Proxmox. Should have started there, its much easier to manage overall.

I've been using HA for about 2 years now on Ubuntu 20.04 which has been announced as unsupported. I ignored it for a while, but had a few update errors that made me want to make the switch. I came across a post by u/fourierswager that gave a high level guide to converting over to a VM Found here.

My problem was that the deploy VM step was more difficult for a novice like me so I figured I would provide a write-up to help someone else looking to migrate their system. I know a lot of people go with Promox, but I wanted to keep my existing Ubuntu system in tact and didn't want to load the desktop version. For each step I've included the source to help understand and support the functions. There maybe easier ways to do this so please correct anything I may have done wrong.

I already have Ubuntu server 20.04 setup and running and use Putty to ssh into it, but any software should work.

  1. Install a hypervisor: I chose KVM. A write up for the install can be found Here or use the two commands below to install via SSH.

     sudo apt -y install qemu-kvm libvirt-daemon bridge-utils virtinst libvirt-daemon-system
     sudo apt -y install virt-top libguestfs-tools libosinfo-bin  qemu-system virt-manager
  2. Install Cockpit. This allows you to manage the VM via webportal. Documentation Here and Here. This installs Cockpit that can be accessed via hostIP:9090 and installs the virtual machine manager.

     sudo apt-get install cockpit
     sudo apt-get install cockpit-machines
     sudo apt-get install virt-viewer
  3. To allow the VM to access your network and the internet you need to setup a network bridge. Documentation Here.

    cd /etc/netplan/
    sudo nano 50-cloud-init.yaml

The edited file should look like this. Highlighted in red was in my default file. I changed dhcp4: to false then added the bridges section below. update the ip addresses to the ip address of your host machine, not what you want the VM to be. Interfaces should match the ethernets section above. For me it was eno1, but yours may be different. Save the file and run the following commands to apply the settings.

    sudo netplan generate
    sudo netplan -debug apply

Next create a file named "host-bridge.xml" to the /etc/libvert/qemu/networks folder. You can do this next one in a single line, but being a novice i like navigating to the folder then creating the file.

    cd /etc/libvert/qemu/networks
    nano host-bridge.xml

copy the following and save in the host-bridge.xml file.

      <forward mode="bridge"/>
      <bridge name="br0"/>

home stretch - create the new network, this will be seen in Cockpit for the next step

    virsh net-define host-bridge.xml
    virsh net-start host-bridge
    virsh net-autostart host-bridge

confirm the new network is created with the following command

    virsh net-list --all    

4. Now we're ready to create the VM image in Cockpit. If you have Ubuntu Desktop I recommend creating the VM in virtManager, but since I don't this was my solution.

Go to hostIP:9090 and should see the Cockpit login page. This will be the same log-in info for your host machine. Navigate to the Virtual Machines section and select import VM. See documentation for step #2 to see what this looks like. That example creates a new VM, where here we are simply importing one. Download the Home Assistant OS Image CQOW2 to you host machine and create the virtual machine Should look like this

Once its created you can go to the VM in Cockpit and find the console. This new VM will fail to boot because Cockpit does not boot the file as UEFI... Documentation Here. This is a fairly easy solution. Ovmf is used to boot the file, then we edit the VM file on the host machine to boot it correctly.

    Apt-get install ovmf
    cd /usr/share/ovmf/

confirm OVMF.fd is there. Now we need to edit the VM file to boot as UEFI.

    Virsh edit Virtual_Machine_Name

In the file edit the lines below to add the <loader... line so it looks like the code below.

         <type arch='x86_64' machine='pc-q35-3.1'>hvm</type>
         <loader readonly='yes' type='rom'>/usr/share/ovmf/OVMF.fd</loader> 
         <boot dev='hd'/>

Back to Cockpit, change the VM to work with bridged connection from step 3. Select edit and adjust the network settings from default to the new host-bridge. When the machine boots this automatically switches to br0. Image

5. Boot the VM and select Consoles in Cockpit. This will give you a visual of the VM and you should see the log-in for Home Assistant terminal similar to if you where to SHH into the machine. Log-in with "root" there is no password.

    network info

Will provide the assigned IP address to the VM. From there you should be able to access Home Assistant via your browser at Virtual Machine's IP address:8123.

I set a static IP address to the new VM via my router, but found that it reverted back for some reason so I also set the same static IP address via nmcli. I won't go into the details since it may not be necessary for everyone, but the documentation can be found here.

6. Final step - USB pass through. Documentation Here. This source does a pretty good job at explaining it so I won't re-paste everything here and there are a few system specific adjustments so probably best to just read the article. The short version is you edit the VM file similar to step 4 to add USB devices then create a USB.xml file with your device specifics then attach to the VM. Reboot everything and should be ready to import your snapshot. If you have the desktop version you should be able to also do this in virtManager.

This turned out longer than I was expecting, but I hope this helps anyone looking to do the same. I'm not sure how much I can help with any questions since most of this was found via googling each step which is why I provided the support documentation that I found to guide me through the process. It looks a little daunting at first, but its not that bad. The hardest part for me was just finding good documentation of what I needed to do.

Adding to this since I have to look it up every time. If you need access to the host command once in the HassOS CLI, just type "login"