From 0cd58564c99a6ff56781a1ba20370974a6f765ec Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sat, 20 Aug 2022 21:15:31 -0500 Subject: [PATCH] r/vmhost: Add autostart script *libvirt*'s native autostart functionality does not work well for machines that migrate between hosts. Machines lose their auto-start flag when they are migrated, and the flag is not restored if they are migrated back. This makes the feature pretty useless for us. To work around this limitation, I've added a script that is run during boot that will start the machines listed in `/etc/vm-autostart`, if they exist. That file can also insert a delay between starting two machines, which may be useful to allow services to fully start on one machine before starting another that may depend on them. --- roles/vmhost/defaults/main.yml | 1 + roles/vmhost/files/vm-autostart.service | 45 +++++++++++++++++++++++++ roles/vmhost/files/vm-autostart.sh | 22 ++++++++++++ roles/vmhost/handlers/main.yml | 4 +++ roles/vmhost/tasks/main.yml | 39 +++++++++++++++++++++ roles/vmhost/templates/vm-autostart.j2 | 3 ++ 6 files changed, 114 insertions(+) create mode 100644 roles/vmhost/defaults/main.yml create mode 100644 roles/vmhost/files/vm-autostart.service create mode 100644 roles/vmhost/files/vm-autostart.sh create mode 100644 roles/vmhost/templates/vm-autostart.j2 diff --git a/roles/vmhost/defaults/main.yml b/roles/vmhost/defaults/main.yml new file mode 100644 index 0000000..13f1527 --- /dev/null +++ b/roles/vmhost/defaults/main.yml @@ -0,0 +1 @@ +vm_autostart: [] diff --git a/roles/vmhost/files/vm-autostart.service b/roles/vmhost/files/vm-autostart.service new file mode 100644 index 0000000..9c7cd79 --- /dev/null +++ b/roles/vmhost/files/vm-autostart.service @@ -0,0 +1,45 @@ +[Unit] +Description=Start virtual machines +After=libvirt.service +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +RemainAfterExit=yes +Environment=LIBVIRT_DEFAULT_URI=qemu:///system +ExecStart=/usr/local/libexec/vm-autostart.sh +Restart=on-failure + +DynamicUser=yes +SupplementaryGroups=libvirt +CapabilityBoundingSet= +DeviceAllow= +DevicePolicy=closed +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +PrivateDevices=yes +PrivateUsers=yes +PrivateTmp=yes +ProcSubset=pid +ProtectClock=yes +ProtectControlGroups=yes +ProtectHome=yes +ProtectHostname=yes +ProtectKernelLogs=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectProc=invisible +ProtectSystem=strict +RestrictAddressFamilies= +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged @resources +UMask=0027 + +[Install] +WantedBy=multi-user.target diff --git a/roles/vmhost/files/vm-autostart.sh b/roles/vmhost/files/vm-autostart.sh new file mode 100644 index 0000000..be8be11 --- /dev/null +++ b/roles/vmhost/files/vm-autostart.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +if [ ! -r /etc/vm-autostart ]; then + exit 0 +fi + +while read name args; do + if [ "${name}" = delay ]; then + sleep ${args} + continue + fi + if virsh domuuid "${name}" >/dev/null 2>&1; then + if virsh domid "${name}" | grep -qE '^[0-9]+$'; then + printf 'Domain %s is already running\n' "${name}" + else + virsh start "${name}" + fi + else + printf 'Domain %s does not exist\n' "${name}" + fi +done < /etc/vm-autostart diff --git a/roles/vmhost/handlers/main.yml b/roles/vmhost/handlers/main.yml index adf5c93..55f91cd 100644 --- a/roles/vmhost/handlers/main.yml +++ b/roles/vmhost/handlers/main.yml @@ -1,2 +1,6 @@ +- name: reload systemd + systemd: + daemon_reload: true + - name: save firewalld configuration command: firewall-cmd --runtime-to-permanent diff --git a/roles/vmhost/tasks/main.yml b/roles/vmhost/tasks/main.yml index 7945929..f7e94ee 100644 --- a/roles/vmhost/tasks/main.yml +++ b/roles/vmhost/tasks/main.yml @@ -99,3 +99,42 @@ state: mounted with_items: '{{ mount_shared_volumes }}' tags: mount + +- name: ensure vm-autostart script is installed + copy: + src: vm-autostart.sh + dest: /usr/local/libexec/vm-autostart.sh + mode: u=rwx,go=rx + owner: root + group: root + tags: + - install + - vm-autostart +- name: ensure vm-autostart is configured + template: + src: vm-autostart.j2 + dest: /etc/vm-autostart + mode: u=rw,go=r + owner: root + group: root + tags: + - vm-autostart +- name: ensure vm-autostart.service unit file is installed + copy: + src: vm-autostart.service + dest: /etc/systemd/system/vm-autostart.service + mode: u=rw,go=r + owner: root + group: root + notify: + - reload systemd + tags: + - vm-autostart + - systemd +- name: ensure vm-autostart.service is enabled + service: + name: vm-autostart + enabled: true + tags: + - service + diff --git a/roles/vmhost/templates/vm-autostart.j2 b/roles/vmhost/templates/vm-autostart.j2 new file mode 100644 index 0000000..8da6114 --- /dev/null +++ b/roles/vmhost/templates/vm-autostart.j2 @@ -0,0 +1,3 @@ +{% for name in vm_autostart %} +{{ name }} +{% endfor %}