Automatic hostname entries for libvirt domains
Have you ever wished that you could use libvirt domain names as
hostnames? So that you could do something like this:
$ virt-install -n anewhost ...
$ ssh clouduser@anewhost
Since this is something that would certainly make my life convenient, I put together a small script called virt-hosts that makes this possible. You can find virt-hosts in my virt-utils GitHub repository:
Run by itself, with no options, virt-hosts will scan through your
running domains for interfaces on the libvirt default network, look
up those MAC addresses up in the corresponding default.leases file,
and then generate a hosts file on stdout like this:
$ virt-hosts
192.168.122.221 compute-tmp0-net0.default.virt compute-tmp0.default.virt
192.168.122.101 centos-0-net0.default.virt centos-0.default.virt
192.168.122.214 controller-tmp-net0.default.virt controller-tmp.default.virt
Each address will be assigned the name
<domain_name>-<interface_name>.<network_name>.virt. The first
interface on the network will also be given the alias
<domain_name>.<network_name>.virt, so a host with multiple
interfaces on the same network would look like this:
$ virt-hosts
192.168.122.221 host0-net0.default.virt host0.default.virt
192.168.122.110 host0-net1.default.virt
Of course, this is only half the solution: having generated a hosts file we need to put it somewhere where your system can find it.
An aside: incron#
Both of the following solutions rely on incron, a tool that uses
the Linux inotify subsystem to trigger scripts in reaction to
events on file and directories. In this case, we’ll be using incron
to monitor the dnsmasq default.leases file and firing off a script
when it changes.
You could accomplish the same thing using the inotifywait program
from the inotify-tools package and a small wrapper script, or you
could hook up something to the libvirt events framework.
Using /etc/hosts#
If you want to update your /etc/hosts file, you can place the
following into a script called update-virt-hosts (somewhere in
root’s PATH) and run that via incron:
#!/bin/sh
sed -i '/^# BEGIN VIRT HOSTS/,/^# END VIRT HOSTS/ d' /etc/hosts
cat <<EOF >>/etc/hosts
# BEGIN VIRT HOSTS
$(virt-hosts)
# END VIRT HOSTS
EOF
Make sure you have incron installed, and add the following to
/etc/incron.d/virt-hosts:
/var/lib/libvirt/dnsmasq/default.leases IN_MODIFY update-virt-hosts
This will cause incron to run your update-virt-hosts script
whenever it sees an IN_MODIFY event on the default.leases file.
Using NetworkManager + dnsmasq#
I am running NetworkManager with the dnsmasq dns plugin. I created
the file /etc/NetworkManager/dnsmasq.d/virthosts containing:
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
This will cause the dnsmasq process started by NetworkManager to
use that file as an additional hosts file. I then installed the
incron package and dropped the following in
/etc/incron.d/virt-hosts:
/var/lib/libvirt/dnsmasq/default.leases IN_MODIFY /usr/local/bin/virt-hosts -ur
This has incron listen for changes to the default.leases file, and
whenever it receives the IN_MODIFY event it runs virt-hosts with
the -u (aka --update) and -r (aka --reload-dnsmasq) flags.
Thef former causes virt-hosts to send output to
/var/lib/libvirt/dnsmasq/default.addnhosts instead of stdout, and
the latter does a killall -HUP dnsmasq after installing the new
hosts file.