fix(bluesky): register compose handlers before the pre-compose staging and move the cfg heal into a script

Run 34421944328 Bluesky#1 stopped at "The requested handler 'compose-up'
was not found in either the main handlers list nor in the listening
handlers list", right after cloning the social-app build context. The
pre-compose staging (01_social_app.yml, 02_login_broker.yml) and the PDS
routine (03_pds.yml) notify compose-up and compose-build, but the
handlers only exist once sys-stk-backend loads sys-svc-compose, which
happens later in the role.

00_core.yml now includes sys-svc-compose with tasks_from: none.yml and
handlers_from: main right after the once flag, the same handler-only
registration sys-stk-backend and sys-svc-rdbms dedicated.yml already use.
The notifications still run at the stack's own flush, after the compose
files exist; the role has no earlier flush. A handler-order test pins
the registration ahead of the pre-compose block.

The oauth2-proxy cfg heal leaves its inline shell for
files/shell/heal_sso_proxy_cfg.sh, which receives the cfg path and the
container name through the environment. The blanket
"container stop ... || true" becomes a precondition: the container is
stopped only when container inspect finds it, so a directory is still
removed when the container is gone, and a failing stop of an existing
container now fails the task instead of vanishing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-11 13:13:36 +02:00
1 parent 9d0f618e23
commit 293c67780d
3 files changed
+43 -7

No files matched your search

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Remove the oauth2-proxy cfg bind-mount source when a prior deploy left it as a directory.
#
# Environment:
# SSO_PROXY_CFG_PATH host path the oauth2-proxy cfg file is bind-mounted from
# SSO_PROXY_CONTAINER container that mounts it, stopped before the removal
set -euo pipefail
cfg_path="${SSO_PROXY_CFG_PATH:?SSO_PROXY_CFG_PATH must be set}"
container_name="${SSO_PROXY_CONTAINER:?SSO_PROXY_CONTAINER must be set}"
if [[ -d "${cfg_path}" ]]; then
if container inspect "${container_name}" >/dev/null 2>&1; then
container stop "${container_name}" >/dev/null
fi
rm -rf "${cfg_path}"
fi
+10 -7
View File
@@ -1,6 +1,12 @@
---
- include_tasks: utils/once/flag.yml
- name: "📂 Register the compose handlers the pre-compose staging notifies"
ansible.builtin.include_role:
name: sys-svc-compose
tasks_from: none.yml
handlers_from: main
- name: "🐳 Pre-compose web-enabled staging (services dir + social-app + login-broker)"
block:
- name: "✅ Ensure social-app services directory exists"
@@ -20,13 +26,10 @@
ansible.builtin.include_tasks: "03_pds.yml"
- name: "🧹 Heal oauth2-proxy cfg bind-mount (if it became a directory in a prior deploy)"
ansible.builtin.shell: >-
if [ -d "{{ BLUESKY_SSO_PROXY_CFG_PATH }}" ]; then
container stop "{{ BLUESKY_SSO_PROXY_CONTAINER }}" 2>/dev/null || true;
rm -rf "{{ BLUESKY_SSO_PROXY_CFG_PATH }}";
fi
args:
executable: /bin/bash
ansible.builtin.script: "{{ role_path }}/files/shell/heal_sso_proxy_cfg.sh"
environment:
SSO_PROXY_CFG_PATH: "{{ BLUESKY_SSO_PROXY_CFG_PATH }}"
SSO_PROXY_CONTAINER: "{{ BLUESKY_SSO_PROXY_CONTAINER }}"
changed_when: false
- name: "📂 include sys-stk-backend role"
@@ -11,6 +11,7 @@ from utils.roles.mapping import ROLE_FILE_TASKS_MAIN
BACKEND = PROJECT_ROOT / "roles/sys-stk-backend" / ROLE_FILE_TASKS_MAIN
RDBMS_DEDICATED = PROJECT_ROOT / "roles/sys-svc-rdbms/tasks/dedicated.yml"
BLUESKY_CORE = PROJECT_ROOT / "roles/web-app-bluesky/tasks/00_core.yml"
COMPOSE_OWNER = "sys-svc-compose"
_NOTIFY = re.compile(r"^\s*notify:\s*(?:\[\s*)?['\"]?(compose-[\w-]+)", re.MULTILINE)
@@ -64,6 +65,21 @@ class TestHandlerRegistrationOrder(unittest.TestCase):
self.assertEqual(loader.get("name"), COMPOSE_OWNER)
self.assertEqual(loader.get("handlers_from"), "main")
def test_bluesky_registers_the_owner_before_its_pre_compose_staging(self) -> None:
tasks = load_yaml_str(read_text(str(BLUESKY_CORE)))
loader = next(
index
for index, task in enumerate(tasks)
if _role_include(task).get("name") == COMPOSE_OWNER
and _role_include(task).get("handlers_from") == "main"
)
staging = next(
index
for index, task in enumerate(tasks)
if "Pre-compose" in str(task.get("name"))
)
self.assertLess(loader, staging)
def test_the_notifier_bootstraps_the_compose_host_before_its_first_notify(
self,
) -> None: