Handlers¶
Six shared handler files live in stage1/handlers/. Plays pull them in with import_tasks under their own handlers: key, so one of these is only reachable from a play that imports it. kubeadm_node also carries a role-local handler, which needs no import.
Every shared handler except reboot.yml uses listen: rather than being notified by name, which is why the notify strings below are lowercase and do not match the task names.
flowchart LR
changed["Task changes state<br/>e.g. install-fail2ban.yml"]
notify["notify: restart fail2ban"]
listen["Handler with<br/>listen: restart fail2ban"]
run["Runs once, at end of play<br/>or at flush_handlers"]
changed --> notify --> listen --> run
The six shared handler files¶
| File | Handler | listen |
Imported by |
|---|---|---|---|
apt-cache.yml |
Clean apt cache | clean apt cache |
play 2 |
apt-cache.yml |
Update package cache | update package cache |
play 2 |
fail2ban.yml |
Restart fail2ban | restart fail2ban |
play 2 |
reboot.yml |
Reboot host | (by name) | play 2 |
sysctl.yml |
Reload sysctl | reload sysctl |
plays 3, 4 |
systemd.yml |
Reload systemd daemon | reload systemd daemon |
plays 3, 4 |
minikube.yml |
Enable/Start minikube, Enable/Start minitunnel | enable minikube, start minikube, enable minitunnel, start minitunnel |
play 3 |
The one role-local handler¶
stage1/roles/kubeadm_node/handlers/main.yml defines Restart kubelet, notified by name from the node-IP pin task. Role handler files load automatically for the role, so no play imports it, and because kubeadm_node is a meta dependency of both kubeadm_server and kubeadm_agent it is in scope on every cluster host.
There is no multipathd handler
stage1/roles/host_setup/tasks/update-multipath.yml stops, disables and masks multipathd.service and multipathd.socket so Longhorn's environment check clears. A masked unit cannot be restarted, so the task notifies nothing and no handler exists to receive it.
Do not add one back.
The reboot barrier¶
reboot.yml is the only handler with a hard ordering requirement. Play 2 ends with:
Handlers normally run at the end of a play, which would still be before play 3. The explicit flush exists so the ordering is stated rather than inferred, and so it survives anyone adding further post_tasks later.
The reboot is triggered by enable-memory-cgroup.yml when it has to edit the kernel command line, common on Raspberry Pi, where memory cgroups are off by default. Without the reboot, kubeadm init fails on the cgroup preflight check.
Debugging¶
Handlers are skipped when nothing notifies them, which reads identically to "no change was needed". To force them:
--force-handlers also runs handlers for hosts that failed later in the play, which is occasionally what you want after a partial failure.