--- # ------------------------------------------------------------------------------ # FILE: roles/llm-inference-multimodel/tasks/systemd.yml # DESCRIPTION: Phase 2 — template + deploy both unit files. # DELIBERATELY DOES NOT START OR ENABLE either service — that is # Phase 4 (verify.yml)'s job, after Phase 3 firewall scoping is # in place. This keeps "units land on disk" and "processes # actually bind ports and load 20+GB into VRAM" as separately # reviewable checkpoints per Ryan's iterative-build preference. # # Two independent units (llama-server-aux.service, # llama-server-toolcall.service) — NOT one unit with two # ExecStarts — so either can be stopped/restarted without # affecting the other (plan §2, §6 rollback requirement). # # The pre-existing Gemma unit (whatever discover.yml found it to # be) is never templated, restarted, or disabled by this file. # ------------------------------------------------------------------------------ - name: Deploy llama-server-aux systemd unit ansible.builtin.template: src: llama-server-aux.service.j2 dest: "/etc/systemd/system/{{ llm_aux_service_name }}.service" owner: root group: root mode: "0644" become: true register: llm_aux_unit_deployed notify: - reload systemd - name: Deploy llama-server-toolcall systemd unit ansible.builtin.template: src: llama-server-toolcall.service.j2 dest: "/etc/systemd/system/{{ llm_toolcall_service_name }}.service" owner: root group: root mode: "0644" become: true register: llm_toolcall_unit_deployed notify: - reload systemd - name: Deploy llama-server-qwen systemd unit (shadow, port 8002) ansible.builtin.template: src: llama-server-qwen.service.j2 dest: "/etc/systemd/system/{{ llm_qwen_service_name }}.service" owner: root group: root mode: "0644" become: true register: llm_qwen_unit_deployed notify: - reload systemd - name: Flush handlers so daemon-reload lands before any later phase acts on unit state ansible.builtin.meta: flush_handlers # NOTE: no `ansible.builtin.systemd: state: started / enabled: true / restarted` # task here on purpose. Units exist on disk after this phase; nothing is # running or restarted. # # BUGFIX (found in production): this file used to `notify: restart # llama-server-*` on the template tasks above, followed by the # flush_handlers meta task. That combination meant Phase 2 (the `systemd` # tag) fired the restart handlers itself — on any run where either unit's # rendered content changed (including the very first apply), BOTH services # got restarted immediately, right here in Phase 2, before Phase 3's # firewall scoping or Phase 4's smoke tests ever ran. That directly # contradicted this file's own stated purpose (units land on disk, nothing # starts/restarts until Phase 4) and caused live services to bounce # unexpectedly on a routine re-run of just `--tags systemd`. # # Fix: Phase 2 only reloads the systemd daemon (harmless, no process # impact) and records whether each unit's content actually changed via # `llm_aux_unit_deployed` / `llm_toolcall_unit_deployed` (both `.changed` # booleans, persisted as play vars for later phases in this same run). # Phase 4 (verify.yml) is the only phase that starts OR restarts either # service, and it does so per-instance using those recorded `changed` # flags — so a content change to one unit's template still never causes # the other to restart, and no restart happens at all until Phase 4 has # been reached.