Files
kevinveenbirkenbachandClaude Opus 5.5 a67dd9b372 feat(constructor): stop a deploy in a pre-flight when the host cannot carry it
The constructor now runs tasks/utils/constructor/preflight.yml before the package install and fails with a named remedy when: the running kernel has no module index on disk or the clock is not synchronised (chrony leap status, else timedatectl, outside containers); / or the docker root is fuller than SIZE_PERCENT_MAXIMUM_DISK_USAGE (90); a docker network contradicts the entity that declares it (name, compose project label, subnet outside its block, overlap with another declared subnet); a declared container lacks or a declared volume carries a foreign entity label; a docker default address pool overlaps the mesh, Tor or a declared subnet; a host process outside docker holds a public port of the deploy; or, in assert mode, a clearnet domain of the deploy does not resolve.

A volume without any label passes, since compose adopts it and installs before this change created the Synapse volume with docker run. web-app-discourse declares its launcher-started containers through networks.local.launcher, and web-app-matrix labels a new Synapse volume with its compose project.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 13:38:15 +01:00

60 lines
2.1 KiB
YAML

---
# include-gated: when: not (DOCKER_IN_CONTAINER | bool)
- name: "🔍 Check whether the running kernel loads modules at all"
ansible.builtin.stat:
path: /proc/modules
register: preflight_proc_modules
- name: "🔍 List the kernels with an installed module index"
ansible.builtin.find:
paths:
- /usr/lib/modules
- /lib/modules
patterns: modules.dep
recurse: true
depth: 2
follow: true
register: preflight_module_indexes
- name: "🛑 Fail when the running kernel has no modules on disk"
ansible.builtin.assert:
that: >-
not preflight_proc_modules.stat.exists
or preflight_module_trees | length == 0
or ansible_facts['kernel'] in preflight_module_trees
quiet: true
fail_msg: >-
Pre-flight: reboot required: the running kernel {{ ansible_facts['kernel'] }} has no module index in
/usr/lib/modules or /lib/modules; only {{ preflight_module_trees | join(', ') }} have one.
No kernel module can load, so restarting Docker would fail to create its iptables chains
and leave every container down. Reboot into the installed kernel, then deploy again.
vars:
preflight_module_trees: >-
{{ preflight_module_indexes.files | map(attribute='path') | map('dirname')
| map('basename') | unique | sort }}
- name: "🔍 Check whether chrony keeps the host clock"
ansible.builtin.stat:
path: /usr/bin/chronyc
register: preflight_chronyc
- name: "⏳ Wait up to 2 min until chrony reports leap status Normal"
ansible.builtin.command:
argv: [chronyc, tracking]
register: preflight_chrony
changed_when: false
retries: 24
delay: 5
until: preflight_chrony.stdout is search('Leap status +[:] +Normal')
when: preflight_chronyc.stat.exists
- name: "⏳ Wait up to 2 min until timedatectl reports NTPSynchronized=yes"
ansible.builtin.command:
argv: [timedatectl, show, --property=NTPSynchronized, --value]
register: preflight_clock
changed_when: false
retries: 24
delay: 5
until: preflight_clock.stdout | trim == 'yes'
when: not preflight_chronyc.stat.exists