mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(sys-stk-backend): register the compose handlers before any role notifies them
sys-svc-rdbms notifies compose-up from dedicated.yml, but sys-svc-compose, the only role that owns that topic, was included after it. With ERROR_ON_MISSING_HANDLER on, the strategy raises before the task result is emitted, so the play dies with '[ERROR]: The requested handler compose-up was not found' and no PLAY RECAP. Rounds that happened to deploy another compose consumer first masked it; a round that deploys the app alone does not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
56b8f1716b
commit
95186163aa
2 files changed
+59
-7
No files matched your search
@@ -18,6 +18,13 @@
|
||||
- "sso_proxy_enabled={{ lookup('sso', application_id, 'is_proxy_gated') }}"
|
||||
when: MODE_DEBUG | bool
|
||||
|
||||
- name: "🧩 For '{{ application_id }}': Load sys-svc-compose"
|
||||
include_role:
|
||||
name: sys-svc-compose
|
||||
vars:
|
||||
compose_handlers_flush: false
|
||||
database_consumer_id: "{{ _sys_stk_backend_database_consumer_id }}"
|
||||
|
||||
- name: "🧩 For '{{ application_id }}': Load central RDBMS"
|
||||
include_role:
|
||||
name: sys-svc-rdbms
|
||||
@@ -44,13 +51,6 @@
|
||||
vars:
|
||||
engine_consumer_id: "{{ application_id }}"
|
||||
|
||||
- name: "🧩 For '{{ application_id }}': Load sys-svc-compose"
|
||||
include_role:
|
||||
name: sys-svc-compose
|
||||
vars:
|
||||
compose_handlers_flush: false
|
||||
database_consumer_id: "{{ _sys_stk_backend_database_consumer_id }}"
|
||||
|
||||
- block:
|
||||
- name: "🔧 set sso_proxy_application_id (needed due to lazy-loading issue)"
|
||||
set_fact:
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
"""A role may only notify a handler topic that is already registered."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from utils.cache.files import PROJECT_ROOT, iter_project_files_with_content, read_text
|
||||
from utils.cache.yaml import load_yaml_str
|
||||
from utils.roles.mapping import ROLE_FILE_TASKS_MAIN
|
||||
|
||||
BACKEND = PROJECT_ROOT / "roles/sys-stk-backend" / ROLE_FILE_TASKS_MAIN
|
||||
COMPOSE_OWNER = "sys-svc-compose"
|
||||
_NOTIFY = re.compile(r"^\s*notify:\s*(?:\[\s*)?['\"]?(compose-[\w-]+)", re.MULTILINE)
|
||||
|
||||
|
||||
def _included_roles(tasks: list) -> list[str]:
|
||||
names = []
|
||||
for task in tasks:
|
||||
include = task.get("include_role") or task.get("import_role") or {}
|
||||
if isinstance(include, dict) and include.get("name"):
|
||||
names.append(include["name"])
|
||||
return names
|
||||
|
||||
|
||||
class TestHandlerRegistrationOrder(unittest.TestCase):
|
||||
def test_the_backend_loads_the_handler_owner_before_any_other_role(self) -> None:
|
||||
order = _included_roles(load_yaml_str(read_text(str(BACKEND))))
|
||||
self.assertIn(COMPOSE_OWNER, order)
|
||||
self.assertEqual(order[0], COMPOSE_OWNER)
|
||||
|
||||
def test_the_owner_still_holds_every_compose_topic_that_is_notified(self) -> None:
|
||||
owner = ""
|
||||
for path, content in iter_project_files_with_content(
|
||||
extensions=(".yml",), exclude_tests=True
|
||||
):
|
||||
if f"roles/{COMPOSE_OWNER}/handlers/" in path:
|
||||
owner += content
|
||||
notified = set()
|
||||
for path, content in iter_project_files_with_content(
|
||||
extensions=(".yml",), exclude_tests=True
|
||||
):
|
||||
if "/roles/" in path:
|
||||
notified.update(_NOTIFY.findall(content))
|
||||
self.assertTrue(notified)
|
||||
for topic in sorted(notified):
|
||||
with self.subTest(topic=topic):
|
||||
self.assertIn(topic, owner)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user