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.
This commit is contained in:
hygienic-books 2025-06-04 01:26:15 +02:00
parent 33e3ebea6f
commit 03b371650c

View File

@ -41,19 +41,18 @@
notify: notify:
- 'Reload systemd unit configs' - 'Reload systemd unit configs'
- name: 'If Arch Linux create symlinks to repo for OS auto-upgrades' - name: 'If Arch Linux copy systemd unit files for OS auto-upgrades to ''/etc/systemd/system'''
when: 'ansible_facts[''os_family''] | lower == ''archlinux''' when: 'ansible_facts[''os_family''] | lower == ''archlinux'''
loop_control: loop_control:
loop_var: 'genvm_os_auto_upgrades_symlink' loop_var: 'genvm_os_auto_upgrades_unit'
label: 'Create symlink to ''{{ genvm_os_auto_upgrades_symlink.target | basename }}''' label: 'Copy ''{{ genvm_os_auto_upgrades_unit.source | basename }}'' to ''/etc/systemd/system'''
loop: loop:
- { target: '{{ genvm_os_auto_upgrades_git_clone_dir }}/arch-linux-update-and-restart.service', symlink: '/etc/systemd/system/arch-linux-update-and-restart.service' } - { source: '{{ genvm_os_auto_upgrades_git_clone_dir }}/arch-linux-update-and-restart.service', target: '/etc/systemd/system/arch-linux-update-and-restart.service' }
- { target: '{{ genvm_os_auto_upgrades_git_clone_dir }}/arch-linux-update-and-restart.timer', symlink: '/etc/systemd/system/arch-linux-update-and-restart.timer' } - { source: '{{ genvm_os_auto_upgrades_git_clone_dir }}/arch-linux-update-and-restart.timer', target: '/etc/systemd/system/arch-linux-update-and-restart.timer' }
ansible.builtin.file: ansible.builtin.copy:
src: '{{ genvm_os_auto_upgrades_symlink.target }}' src: '{{ genvm_os_auto_upgrades_unit.source }}'
dest: '{{ genvm_os_auto_upgrades_symlink.symlink }}' dest: '{{ genvm_os_auto_upgrades_unit.target }}'
state: 'link' remote_src: true
force: true
notify: notify:
- 'Reload systemd unit configs' - 'Reload systemd unit configs'