By default libvirt/kvm virtual machines created with Foreman will not be set to autostart. This is a slight irritation in that if the host ever crashes the virtual's won't start back up automatically. So here's the solution!

I first tried to solve this within Foreman's rails code, but this turned troublesome quite quickly. Foreman uses Fog to manage VMs. Fog's implementation of Libvirt though will not let you save a VM that has already been created, giving an error that doing so could result in duplicate machines being created. How irritating! Compounding this is a bug that a virtual machine created with :autostart => true in its initial hash of settings won't get created with autostart enabled. I'm guessing this is a libvirt issue in that for a new virtual machine there isn't an XML that can be symlinked to the autostart directory on the host. The whole libvirt symlink for autostart solution itself is quite dubious, you'd think it'd be included in the XML file directly... Double boo!

To solve this issue we'll use the foreman_hooks plugin to talk directly to libvirt and set the vm to autostart. So first setup foreman_hooks based on Foreman's directions. Make sure you add the hook_functions.sh script into and the following script into /usr/share/foreman/config/hooks/host/managed/create/

#!/bin/bash
# Autostart Libvirt VM's created with Foreman
# /usr/share/foreman/config/hooks/host/managed/create/10_autostart_libvirt.sh
# Source: http://www.uberobert.com/autostart-libvirt-vms-in-foreman/

. $(dirname $0)/hook_functions.sh

username='admin'
password='changeme'

# event name (create, before_destroy etc.)
# orchestration hooks must obey this to support rollbacks (create/update/destroy)
event=${HOOK_EVENT}

# to_s representation of the object, e.g. host's fqdn
object=${HOOK_OBJECT}
hostname=$(hook_data host.name)

echo "$(date): setting ${object} to autostart" >> /tmp/hook.log

# find our compute_resource
compute_resource=$(hook_data host.compute_resource_id)

# get compute_resource's url from foreman
compute_resource_url=$(curl -k -u ${username}:${password} https://$(hostname)/api/compute_resources/${compute_resource} | grep -Po '"url":.*?[^\\]",' | awk -F\" '{print $4}') >> /tmp/hook.log

# autostart our host
virsh -c $compute_resource_url autostart $hostname

exit 0

Note that you need to add a username and password that has API access to compute resources. Foreman doesn't pass the compute resource URL info into the script via the host's object so we need to pull it manually.

And that should be it, have fun! If you have any issues please comment below. I've made a gist of this on github, if you have any recommendations leave a comment and make recommendations on the gist. Thanks!