hygienic-books 03b371650c refactor(role): Copy unit files instead of symlinking them
On each target machine we're storing the Git repo that has our unit
files underneath '/opt/git'. Prior to this commit we used to place
symlinks from '/etc/systemd/system' into the appropriate '/opt/git'
subdir. On most machines this worked fine, however, on some we
encountered a race condition on system start.

Sometimes '/opt/git' is not the same file system as '/'. If that's
the case chances are that systemd initializes the system and fails to
access a unit file at '/opt/git' because that file system is just
barely not yet visible early in the boot process.

For a timer unit for example this could result in enabling the unit
and upon reboot seeing that the unit no longer existed in systemd's
world view e.g. via 'systemctl list-timers' even though the symlink
at '/etc/systemd/system' still pointed to an '/opt/git' subdir when
inspected manually seconds after boot. journalctl, however, would
clearly confirm that at system initialization the symlink target was
inaccessible.

We could fiddle around with delaying boot until '/opt/git' and its
descendants are visible but the sane solution is to just not rely on
a separate file system for important stuff such as unit files. We now
copy unit files to '/etc/systemd/system' instead of symlinking them.
2025-06-04 01:26:15 +02:00
2025-04-03 00:12:58 +02:00
2025-04-07 00:25:50 +02:00
2025-04-03 00:12:58 +02:00
2025-04-03 00:12:58 +02:00
2025-04-03 00:12:58 +02:00
2025-04-02 21:46:09 +00:00
2025-04-03 00:12:58 +02:00

Role Name

role-service-generic_vm

Description

Settings and configs for most virtual machines.

Requirements

Your target machines must be Linux.

Role Variables

Per defaults/main.yml this role comes with a whole host of default variables almost all of which are relevant only to Arch Linux machines as that's what we run ourselves. Feel free to override these with host or group vars.

  • genvm_git_repos_base_dir: The base directory where we canonically store checked out Git repos. This defaults to /opt/git. We use this var to construct subdirectory paths underneath that location.
  • genvm_pacman_hook_git_base_dir: On Arch Linux we Git clone quico.space/quico-os-setup/zfs-pacman-hook into this location. The repo contains package manager hooks that automatically snapshot the root-on-ZFS filesystem that all of our Arch Linux machines are using.
  • genvm_pacman_hook_git_branch: In above repo we're interested in this branch. Can be main for example.
  • genvm_pacman_hook_auto_snapshot_datasets: Name ZFS datasets that we want to automatically snapshot whenever package manager actions happen. This is a list with one entry by default, zpool/root/archlinux.

The following four plus four vars deal with Git cloning firstly, a repo with a script that detects the need to a system reboot on Arch Linux and secondly, a repo that automatically does unattended package upgrades. They follow the same pattern.

Arch Linux reboot detection

  • genvm_os_needs_restart_git_repo: Git clone from this location
  • genvm_os_needs_restart_git_base_dir: Git clone into this base dir
  • genvm_os_needs_restart_git_branch: Check out this branch
  • genvm_os_needs_restart_git_clone_dir: Git clone into this exact dir (constructed from both genvm_os_needs_restart_git_base_dir and the branch we want).

Arch Linux unattended package upgrades

  • genvm_os_auto_upgrades_git_repo: Git clone from this location
  • genvm_os_auto_upgrades_git_base_dir: Git clone into this base dir
  • genvm_os_auto_upgrades_git_branch: Check out this branch
  • genvm_os_auto_upgrades_git_clone_dir: Git clone into this exact dir (constructed from both genvm_os_auto_upgrades_git_base_dir and the branch we want).

Dependencies

None.

Example Playbook

In your playbook.yml call it like so:

- name: 'Awesome playbook'
  hosts: all
  roles:
    - 'role-service-generic_vm'

License

MIT

Description
Settings and configs for most virtual machines
Readme MIT 40 KiB