Install Home Assistant OS with KVM on Ubuntu headless (CLI only)

I am a network engineer, so this is what I understand :slightly_smiling_face:
I tried your old version and new 5.8, but nothing new yet. I don’t see any attempts to get an address on my mikrotik DHCP server. As I know there is no another possibilites to access VM without IP? May be it have some secondary IP for managment?
Anyway I keep trying.
All I know about VM - it work and doing something)

Now I see attemps, but with the same mac-address as br0

I don’t know if you can set up a secondary IP. I know that for oVirt (that I was looking to use before the CentOS announcement), you can set up management networks. So I’d guess that it’s possible, but I wouldn’t know how to do it.

Quick question: You did ensure that it is setting up the VM with boot=UEFI right? So you have installed OVMF? The first VM I tried (using oVirt) never booted, because I hadn’t set the boot to UEFI, it was trying to use BIOS mode, and the HassOS image can’t do that.

I tried testing with a centOS qcow2 image, perhaps you could try that (https://cloud.centos.org/centos/7/images/). Just to see if it is HassOS specific, or KVM/system specific?

I did anything to use entire your command

virt-install --import --name hassos \
--memory 4096 --vcpus 4 --cpu host \
--disk hassos.qcow2,format=qcow2,bus=virtio \
--network bridge=br0,model=virtio \
--os-variant=rhel8.1 \
--graphics none \
--noautoconsole \
--boot uefi

I downloaded and try CentOS:

virt-install --import --name centos \
--memory 4096 --vcpus 4 --cpu host \
--disk CentOS-7-x86_64-GenericCloud.qcow2,format=qcow2,bus=virtio \
--network bridge=br0,model=virtio \
--os-variant=rhel8.1 \
--graphics none \
--noautoconsole \
--boot uefi

At least it have a console. But I have no idea what to do next.

And the centOS VM does show up on your network (DHCP)? I mean, is it assigned a local IP that you can ssh into, right? If the CentOS VM does show up on the network, it would seem like issue is something specifically with the HassOS.

(Well, I actually don’t think you can ssh directly into the CentOS VM, since I think you’d need to inject SSH keys into the image before running it, but is it getting an IP at least?)

How about (I’m kind of reaching for straws here) trying to start the HassOS VM and running (from the Ubuntu CLI) nmap -p 8123 192.168.7.0/24 (again, assuming you have a /24 netmask, and that DHCP assigns IPs in that range). I see something like:

PORT     STATE  SERVICE
8123/tcp closed polipo

Nmap scan report for 192.168.0.4
Host is up (0.00059s latency).

PORT     STATE  SERVICE
8123/tcp closed polipo

Nmap scan report for 192.168.0.11
Host is up (0.085s latency).

PORT     STATE  SERVICE
8123/tcp closed polipo

Nmap scan report for 192.168.0.12
Host is up (0.00096s latency).

PORT     STATE SERVICE
8123/tcp open  polipo

... etc.

Where only the IPs with a Home Assistant running has an open port 8123. In case it’s “hiding” somewhere?

Where to start?

I did all the same mistakes you guys did! Well, actually one mistake and one not knowing better. I’ll show you in a minute!

First of all! The 5.9 image obviously comes as qcow2.xz <- Please note the *.xz at the end! You have to unzip that with:

xz -d -v hassos_ova-5.9.qcow2.xz

If you do that your file will grow to a 32Gb qcow2 file.

After this, redo all your vm creation process, you’ll notice that now you really boot to home assistant.

What you show as console is in fact the UEFI console of QEMU/KVM. It has nothing to do with home assistant at all. That was my first mistake! I hope this helps.

Now on to our second problem:
No IP even though the bridge is up. I am using an Ubuntu Server 20.10 install an have Docker as well as QEMU/KVM installed. I did setup the bridge like explained before but: it seems Ubuntu likes to restrict things without my knowledge, hence:

Howto - disable netfilter

You need to disable the netfilter on your bridge or nothing will go in or out, even if everything looks absolutely fine.

In short what I did was: (in simple steps and assuming you already created your bridge as shown above with netplan).

-> Important <-
You first need to follow the tutorial/how-to above!
Create your bridge and then, when your traffic goes in + out of your host without any problem move on to the next problem.

-> Even more important! <-
This has been tested with Ubuntu Server 20.10, I can not guarantee it to work on any other Distro / Version!

-> !!!Absolutely, incredibly important!!! <-
Understand that you will be messing with udev, startup rules and such. If your server starts screaming at your wife and kids I will not be held responsible! If you do not have
!!! physical !!!
access to your server don’t do it! You could end up with a networkless machine!

-> Lets get it on <-

  1. Make sure your brigdge is in place and works so far!

  2. Create a file called /etc/sysctl.d/bridge.conf and fill it in with this:

net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0
net.bridge.bridge-nf-call-arptables=0
  1. Then create a file called /etc/udev/rules.d/99-bridge.rules
    Just one line needed inside, not more, not less:
ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", RUN+="/sbin/sysctl -p /etc/sysctl.d/bridge.conf"
  1. [Optional] Disable and remove the default virtual network for QEMU, use sudo if you get a permission denied error:
virsh net-destroy default
virsh net-undefine default
  1. Cross your fingers and reboot your server!

Of course all credits for my guide go to the author of the forementioned article. I’m just summing it up here.

I hope this helps you in any way!

1 Like

My 2 cents worth…(Caveat, I am using Ubuntu 20.0.4 Desktop and virt-manager; so things may differ from the Server version and of course using virt-install differs from virt-manager).

One observation is that it appears the netplan config gives the Ubuntu Server 'host" two IP addresses, one for eno1 (dhcp4 true), and the other for br0 (dhcp4 true). I would think it should be eno1 has dhcp4 false. Anyway an $ip addr should reveal that eno1 has no ipaddress but br0 does.

Another observation, is that even though br0 was configured, it was not activated (see the output of $ virsh net-list --all). Only the QEMU/KVM default bridge was active.
In a separate thread, I suggested a way to activate br0:

With br0 active, I would think you can specify br0 in the virt-install using --network=bridge:br0 (I am not sure about the model=virtio as my setup uses e1000 which models an Ethernet NIC card). Should then be able to run fine and not have to deal with destroying the default bridge (in my case, both br0 and default bridges are active).

As for the netfilter comment, I can’t say definitively, but I’ve gone through several other QEMU/KVM installation guides and there was no mention of needing to disable netfilter, so wondering if disabling it is only in regards to a performance issue (at least that’s all the Howto-disable netfilter guide says about it)? I did check my system doing $ lsmod and the br_filter kernel module is not installed, so for sure it is not in the way in my case. I would be curious if br_filter is installed in the Ubuntu 20.0.4 Server case?

Anyway, hope this may further help those having networking issues.

Hey wmaker!

You are probably right. I also see no need to assign eno1 an IP address, since all traffic in + out the host should be routed through the bridge. But that’s also my 2 cent.

And most definitely, you have to create the xml file for kvm and make your bridge known! I missed this (I would say fundamental step) is missing in the above guide! This is crucial.

As for netfilter all I can tell you is my virtual machines (and I tried to setup a couple) would not get any IP traffic at all until I did this. Maybe it’s the other way round and you need netfilter to do be loaded. But then again, this is where Ubuntu does it’s magic and I really don’t have the time to go that deep. I’d prefer I had to proactively do my configuration, than “magic” happen under the hood.

I hope we can help with our comments :smiley:

Hey @oldrobot & @wmaker, thanks for the inputs.

I noticed that indeed virsh net-list --all doesn’t show the br0. It shows up with brctl show though, and the VM has internet when using the virt-install command in the guide. My physical interface has no IP, but the bridge does. Regardless, all my VMs having internet by using the br0. Is it still advisable to create a host-bridge.xml file and add the br0? What will this mean (what will the actual difference in behavior be)?

Good point, I’ll clarify in the guide. Thanks! (though the qcow2 image came as a .gz file back when I made this guide, so if that changes every now and then, perhaps I’ll just note that it should be unzipped).

Is this what you see by ufw status verbose? If so, mine shows Status: inactive, which is probably why I didn’t need to do this step (and thus why I didn’t include in the guide). Could this be a change in Ubuntu 20.10 v 20.04?

Hi @Aephir

I’m looking at your brctl show and it shows that vnet0 is associated with br0 and as well, en01 is also associated with br0. To me this explains how the traffic flows successfully.

My observation has been that when qemu/kvm starts up a VM it creates an interface vnetX (X being 0, 1,2, etc, one for each VM being started). qemu/kvm virtualization has to know which bridge to assign vnetX to and my presumption is it knows this using --network bridge=br0. But since br0 is not in the netlist, it apparently takes --network bridge=br0 at face value. So… I’m not really sure know how to answer your question, but I would suggest as a best practice, that the xml file should at least be mentioned, maybe a pointer to another web page that shows how to do it.
EDIT: Having thought some more, I’m speculating that the net-list is only needed by virt-manager as its GUI is used show the user what bridges are available to use and for the user to select one. So with that, I now think it is not necessary to include the creation of the xml file.

I don’t think ufw status is an adequate indicator. Instead, run the comand $lsmod. There will be lots of output, but if you see the lines something like:

br_netfilter           24576  0
bridge                155648  1 br_netfilter

Then the netfilter is running on the bridge. If it is not, then disabling the filter would have no affect.

NOTE: Disregard update for now. The Hass I could access in this way was the instance I have running in Docker. I’m working on finding the update to give network to the VM with the updated approach. I’ve reverted the guide, since it is taking longer than I thought.

@wmaker, @seventh: I have updated the “network setup” part based on your (and other) input, thanks for the suggestions. Hopefully it’s better this way.

Now we create a vlan on the eth interface, a bridge on the vlan, and set up the VM on that.

@seventh: If you do end up trying this approach, please let me know if you try without setting DHCP reservation before first HassOS boot, I’d like to know if that step is necessary :slight_smile:

This is great! I need to map my usb z-wave stick into the VM. It’s mounted as:

/dev/serial/by-id/usb-Silicon_Labs....

if someone could point me to the correct incantation to get that inside my VM somehow… I would be grateful

@ha_steve: I was going to update the guide to include this part as soon as I’ve done it in practice. But I’ll throw in the notes I have for now (so no guarantees, I haven’t done this myself yet).

Guide taken mostly from here.

(Of course, adjust the ID’s and paths as needed for your system.)

Find the idVendor and idProduct of the USB device you want to attach.

lsusb -v

A few examples from my system, an Aeotec Z-wave:

  idVendor           0x0658 Sigma Designs, Inc.
  idProduct          0x0200 Aeotec Z-Stick Gen5 (ZW090) - UZB

And a ConBeeII stick:

  idVendor           0x1cf1 Dresden Elektronik
  idProduct          0x0030

[NOTE] Can also be attached using device address on host, though that might change if they are unplugged or host is rebooted.

EDIT I think you need one file per USB device. Below I have used the ConBeeII stick as an example.

With the above, create an xml file:

sudo nano /var/lib/libvirt/images/hassos-vm/conbeeii.xml

And insert

<hostdev mode='subsystem' type='usb' managed='yes'>
  <source>
    <vendor id='0x1cf1'/>
    <product id='0x0030'/>
  </source>
</hostdev>

[NOTE] - the “managed=‘yes’” makes it behave as if “nodedev-detach” and “nodedev-reattach” had been called at correct times, so you shouldn’t need to do anything else.

Then you can attach USB devices using virsh

virsh attach-device hassos --file /var/lib/libvirt/images/hassos-vm/conbeeii.xml --persistent

[Note] use “virsh detach-device [DOMAIN] [FILE]” to detach, where it will reattach again upon next boot. Add “–persistent” to this, to make the detach persistent.

4 Likes

@Aephir - thanks for this! I have it working now!

One additional question. Do you have a way of connecting to the console?

Good to hear, and thanks for being guinea pig before I had to test on my own! That gives me a little peace of mind before pulling the plug, and moving my old (unsupervised) Docker setup to a shiny new VM :slightly_smiling_face:

I use the “SSH and Web Terminal” add-on for what I need in HassOS, would that work for your needs?

I have followed all this tutorial step by step, and at the end I get an error:

Error: --boot uefi: Don't know how to setup UEFI for arch 'i686'

What can I do now? Im using an Asus Laptop (1201ha) and even if it has BIOS vt support, it’s a 32 bits machine… any workaround?

Update: I’m trying with: --archx86_64 but now i get:

Error validating install location: Distro 'rhel8.1' does not exist in our dictionary

I see with osinfo-query os many of them, rhel from 12.1 to 17.5, and doesn’t matter what i use, I got the same error over and over again :frowning:

By the way I’m using minimal ubuntu 18.4 for 32 bits, since my laptop is kinda old.

First off, I have no idea if it works on 32 bit, I guess I should specify that. But I’d be interested to see if it does!

Secondly, I might have made a typo in the guide (copied the wrong command after testing a few different ones). Try installing without specifying the os-type, so use the below instead of step 3 in guide:

cd /var/lib/libvirt/images/hassos-vm
virt-install --import --name hassos \
--memory 2048 --vcpus 4 --cpu host \
--disk hassos.qcow2,format=qcow2,bus=virtio \
--network bridge=br0,model=virtio \
--graphics none \
--noautoconsole \
--boot uefi

Note that I also decreased the amount of RAM. If you run 32 bit version, you have a maximum of 4GB, and the base OS (Ubuntu) says minimum requirements is 2GB (well, I think that was for the desktop variant, so likely lower minimum requirements for CLI only. But not zero.). So I’ve only allowed 2 GB to the HassOS VM in the above.

Also remember you might need to change the vcpus if needed (depending on your CPU).

And @mabusdogma, please let me know if this works so I can fix the guide :slight_smile:

Sadly it does not work, I’ve changed everything as you said on your last comment and now I get this:

this kernel requires an x86-64 CPU, but only detects an i686 CPU, unable to boot

:frowning:

Maybe a workaround is to virtualize a RbPi 3 or something 32bits… I’ll try, I hope it works

I found this guide that says

… choose either Other Linux 32-bit or 64-bit depending of your system…

This one uses the VDI image. I’m not sure KVM supports this (?), but you might try one of the other images? Or maybe ask in the Discord channel, there might be a workaround (and old image that can then be updated once installed, or something like that?)

Thanks for this guide!

When I applied the netplan my ip address changed and I thought I had botched the config. So as hint to others: either specify an IP or double check the host ip before you re-install the OS :smiley:

Home Assistant is now running but I’m not sure what the best way to access the VM is. Using virsh console hassos doesn’t seem to work. Am I missing something obvious or do I have to install the ssh addon to get proper access?

The only solution I’ve found to enable the virsh console requires that you have access to the vm already so I don’t see a way around the ssh addon. Is that the way to do it?