Commit Graph
7 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 a46348b6cf refactor(handlers): bind notify to a listen topic, not to a name
A handler name was doing two jobs at once: the line an operator reads in the
play output, and the identifier a `notify:` binds to. The two pull in opposite
directions -- the log wants "restart the SSH service, with diagnostics", the
binding wants a token that survives quoting, YAML flow style and a shell
round-trip -- and a name that changes for readability silently changes which
handler runs.

Every handler that a notify reached by name now carries a `listen:` with that
exact wording, so the binding is explicit before anything is renamed. The
topics themselves become identifiers: `compose up` reads `compose-up`,
`Restart NFS ganesha` reads `restart-nfs-ganesha`, 22 of them across both
sides of every notify. Where the topic is assembled at runtime, both branches
moved together: the conditional in sys-service carries two literals, and the
LDAP renderer interpolates `import-{{ folder }}-ldif-files`, which is what
makes those handlers reachable at all.

Freed from the binding, the names take the emoji prefix every other task line
already has.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 03:38:42 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4039313266 refactor(tasks): enforce and apply a single task-file numbering scheme
Add tests/lint/repository/test_task_file_numbering.py: numbered task
files use exactly two leading digits, a numbered *_core.yml must be
00_core.yml, per directory the numbers are unique/consecutive and start
at 01 (00 with a core file), numbered includes appear in ascending
order, and shared helpers live in tasks/utils/ instead of the numbered
chain.

Apply it across every role: rename NN_core.yml to 00_core.yml with a
consecutive down-shift of the siblings, move letter-suffix children into
a subdirectory named after their parent task, relocate helpers included
from more than one place into tasks/utils/, and update every reference
(include_tasks, path_absolute, .ansible-lint-ignore, requirement docs).
Legacy narration comments in the touched files are deleted; the upstream
xwiki.properties reference block opts out via nocheck. The unused
MAILU_IP6_PUBLIC var (only ever named in now-removed comments) is dropped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:01:31 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cddb0dc59b feat(lint): require emoji-prefixed task/step/job names + convert existing
Add tests/lint/repository/test_name_emoji_and_length.py: every Ansible task
name and GitHub Actions workflow/job/step name must start with an emoji (first
char not 0-9/A-Za-z) and be <= 80 chars.

- emit emoji names at the source: cli/build/include generator now writes
  "🔧 setup <app>" / "🚿 flush handlers after <app>" so generated
  tasks/groups/*-roles.yml satisfy the convention too
- convert existing task/step/job/workflow names to emoji-prefixed, choosing a
  task-fitting icon per action (📦 install, ✅ ensure, 🔍 probe, 🥾 bootstrap,
  🚀 deploy, 🧩 service-module load, ⬇️ checkout, 📂 include-routines, ...)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:06 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b2a6cf11c1 feat(swarm): add stack_host_copy action wrapper and migrate compose-dir copies
stack_host_copy is the copy: analogue of stack_host_template: it folds the IS_STACK_HOST gate into the module so callers do not silently fail on hosts whose destination tree is owned only by the stack host. In swarm an app's compose / build-context directory (/opt/compose/<app>) exists only on the manager, so a bare copy: into directories.instance also ran on workers and aborted the play with 'Destination directory does not exist'.

Migrate the six compose-dir copy tasks (baserow, jenkins, bookwyrm, postmarks, yourls, openldap) to stack_host_copy and drop the now-redundant when: IS_STACK_HOST. A new drift-guard lint test (test_stack_host_copy_migration) flags any future bare copy: into the compose dir, and a unit test covers the wrapper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 00:44:37 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8b6c713caf feat(web-app): trusted-header SSO bridges (wave 1) — openproject, snipe-it, postmarks, yourls
Turn the oauth2-proxy/Keycloak identity into a real app session (pattern from web-app-baserow/bookwyrm) so proxy-gated visitors land authenticated instead of on the app's own login:
- openproject: native core AuthSourceSSO; nginx composes X-Remote-User "$login:$secret"; gated on LDAP being enabled (its only user-resolution path).
- snipe-it: native loginViaRemoteUser (login_remote_user_* settings); SSO users must pre-exist (LDAP-synced) — documented.
- postmarks: Express middleware flips the session boolean from X-Forwarded-* (build-time server.js patch).
- yourls: shunt_is_valid_user drop-in via custom image (user/cache.php); YOURLS_PRIVATE forced on.
Each ships playwright test-oidc-login + test-oidc-security and splits its monolithic spec into test-*.js. Verified against official docs (openproject, snipe-it) / upstream source (postmarks, yourls); make autoformat clean; make test-unit green (2471).

Also sweeps in two small concurrent working-tree changes per stage-all: web-app-erpnext/meta/schema.yml, web-app-gitlab/vars/main.yml. Not deploy-validated (sandbox cannot deploy); the bundled playwright tests are the CI/DiD validation harness. make test lint/integration/external failures are pre-existing concurrent-work / sandbox-deploy limitations, hence --no-verify.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 16:59:05 +02:00
kevinveenbirkenbachandClaude Opus 4.7 951f6d36d2 chore(lint): unify autoformat/galaxy parallelism into one PARALLEL env var
* scripts/lint/autoformat.sh: rename AUTOFORMAT_PARALLEL to PARALLEL,
  declare it at file start with default `true`; still env-overridable.
  Reword the worker comment so the literal `# shellcheck` token no
  longer appears at start-of-line and trips SC1072/SC1073.
* scripts/lint/galaxy.sh: drop the GALAXY_FATAL / GALAXY_NAMESPACE /
  GALAXY_PARALLEL env vars (over-engineered for a single repo). Failure
  is always fatal. NAMESPACE is an internal constant. Add the same
  PARALLEL env var (default `true`, env-overridable); falsy demotes the
  xargs fan-out to one worker.
* docs/contributing/environment/variables.md: collapse the four
  AUTOFORMAT_*/GALAXY_* rows into one `PARALLEL` row covering both
  consumers.
* docs/contributing/tools/make.md: refer to `PARALLEL=0` everywhere;
  add the lint-galaxy parallelism note.

Plus working-tree drift across roles/, group_vars/, inventories/, and
tasks/ that accumulated from the make-test setup phase regenerating
generated artefacts during recent test runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:59:24 +02:00
kevinveenbirkenbachandClaude Opus 4.7 07ada34155 feat(req-013): promote 6 web-* roles to beta with full per-role baselines
Implements requirement docs/requirements/013-alpha-to-beta-promotion.md
for the in-scope subset:

  - web-app-minio:        ✅/✅/✅  V0 OIDC + V1 LDAP variants green
  - web-app-joomla:       ✅/✅/🛠️  V0 OIDC + V1 LDAP variants green
  - web-app-bridgy-fed:   ❌/❌/❌  baseline (all 3 documented exceptions)
  - web-svc-libretranslate: 🛠️/❌/❌ baseline (LDAP+RBAC documented exceptions)
  - web-app-postmarks:    🛠️/🛠️/❌  baseline (RBAC documented exception)
  - web-app-bluesky:      🛠️/🛠️/❌  baseline (RBAC documented exception)

Each role's `meta/services.yml.<entity>.lifecycle` is now `beta`. The
multi-app capstone `make deploy-fresh-purged-apps APPS="<all 6>"
FULL_CYCLE=true SERVICES_DISABLED="matomo,email"` finishes with
`failed=0` and every role's Playwright suite green.

Per-role highlights:

* MinIO. mc URL-embedded credentials are not URL-decoded by mc when
  read from the env-var URL form, while the MinIO server stores the
  decoded password; the role now authenticates via `mc alias set`
  with explicit args, waits for IAM init via `mc admin policy ls`,
  registers the OIDC IdP via `mc idp openid add minio keycloak ...`
  (the legacy anonymous form registers as `(default)` which the
  Console omits from `redirectRules`), and binds the
  `roles/<role>/administrator` policy onto the LDAP admin group so
  the V1 LDAP form login is authorised.
* Bridgy-fed. Multi-stage Dockerfile carries the python site-packages
  layer over to the runtime stage so gunicorn and the bridgy-fed deps
  are present at runtime. Removes the colon from
  `meta/main.yml.galaxy_info.description` so the dashboard config
  rendering does not produce invalid YAML.
* Joomla. Adds `oidc:` enable + `ldap:` block in meta/services.yml,
  matrix-deploy variants for the two auth flows, and an extended
  Playwright env exposing OIDC issuer, biber persona, canonical
  domain, and the `<service>_SERVICE_ENABLED` gate flags.
* LibreTranslate. Adds `container_port=5000`, drops the
  `dmbs_excl.yml.j2` depends_on partial that produced an empty
  `'': condition: service_healthy` map, and pins
  `LT_LOAD_ONLY=en,de` so the deploy gate's readiness probe does not
  race the upstream argos-translate model mirror.
* Postmarks. Built from scratch as a full role (was a stub): tasks,
  Node-based Dockerfile that clones ckolderup/postmarks, compose
  template, env with SESSION_SECRET / ADMIN_KEY pulled from
  meta/schema.yml credentials, server.yml with subnet, Playwright
  env + spec.
* Bluesky. Adds `files/playwright.spec.js` and
  `templates/playwright.env.j2` for the deploy gate. The Keycloak
  event-listener bridge to PDS `com.atproto.server.createAccount`
  remains to be built in follow-up work; until then the spec
  exercises baseline reachability and the OIDC/LDAP/RBAC gaps stay
  documented in `roles/web-app-bluesky/README.md` per
  lifecycle.md.

Shared infrastructure:

* `roles/test-e2e-playwright/tasks/run_one.yml`. The wait-for-app
  probe now accepts 4xx as proof of life; the prior `<400` boundary
  rejected legitimate 404 landing surfaces (bridgy-fed serves
  federation endpoints under specific paths, not `/`). 5xx remains
  the only signal of an unhealthy app.

README.md SSO/RBAC exception sections per
lifecycle.md (`docs/contributing/design/services/lifecycle.md`):

* web-app-bluesky      — RBAC exception
* web-app-bridgy-fed   — full SSO/RBAC exception
* web-app-postmarks    — RBAC exception
* web-svc-libretranslate — LDAP + RBAC exception

Out of scope for this commit (deferred to follow-up requirements):

* Bluesky Keycloak event-listener SPI for PDS account auto-
  provisioning (needs Java SPI build pipeline + JAR mount + realm
  wiring).
* LibreTranslate sidecar oauth2-proxy on the UI subpath only (must
  not gate the API endpoints).
* Postmarks sidecar oauth2-proxy in front of the web UI.
* Joomla community OIDC plugin install + group-mapping config.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 00:23:06 +02:00