mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 04:06:42 +00:00
Every role's base services carry `docs.enabled: "{{ 'web-app-docs' in
group_names }}"`, and the static closure counts any "in group_names" flag
as possibly true (is_explicit_truth). A round therefore pulled web-app-docs
in through any member whose active variant did not pin docs off, and a
round hands every role its index or clamps it to variant 0, where 84 roles
declare docs on. The README replay and everything it drags in (dashboard,
matomo, keycloak, prometheus with its MCP partners) landed in 365 of 469
rounds instead of one per role, which ran CI run 40625679270 out of
resources: Listmonk#0 memory, OpenProject#0 I/O in the DR drill,
Nextcloud#0/#2 budget (4310-4539 s in the replay each, 60 s over),
BookWyrm#0 drill disk, Matrix#1/#3 pids in the replay; none of those
primaries declares docs in the failing variant.
The guide host now stays on only where the primary app's own variant
declares it (declares_guide, the predicate instructions.py already used);
every other role has it switched off (guide_off), in the planner's round
overrides and in the swarm include set. The host_vars bake drops a docs
edge whenever the round does not deploy web-app-docs. Measured for
listmonk, openproject, translate and mariadb: web-app-docs is deployed in
exactly each primary's declared guide round, swarm and planner agree in
all 12 rounds, and rounds shed up to ten apps (mariadb#1 19 -> 9).
test_guide_rides_the_primary_only pins that on real role data (it fails
with the rule disabled); test_variant_pin_required leaves the guide host
out of its clone comparison and no longer counts the docs key as a
pairing edge, because the replay no longer follows a partner's index.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
72 lines
2.5 KiB
Python
72 lines
2.5 KiB
Python
"""Which matrix entry replays its role's README instructions.
|
|
|
|
The replay used to be a job of its own, picking one random role per run. It
|
|
rides on a deploy row instead, marked with ``instructions`` (the mode the
|
|
replay runs in). The job title says nothing about it: the row is an ordinary
|
|
deploy of its variant, and the guide host is one more service that variant
|
|
pulls in.
|
|
|
|
Which row carries it is declared, not computed: the role's ``meta/variants.yml``
|
|
switches the ``docs`` service on in exactly one variant, and the deploy pulls
|
|
the guide host in through that service edge. This module only reads that
|
|
declaration back out and turns it into matrix entries.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
from utils.roles.guide import declares_guide, guide_deployable
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Mapping, Sequence
|
|
from typing import Any
|
|
|
|
|
|
def redundant(entry: Mapping[str, str]) -> bool:
|
|
"""Whether the sweep drops this row as coverage an earlier row already has."""
|
|
if entry["priority"] == "true":
|
|
return False
|
|
return entry["clone"] == "true" or entry["covered"] != "0"
|
|
|
|
|
|
def _carries_guide(
|
|
app: str,
|
|
variant: str,
|
|
variants_per_app: Mapping[str, Sequence[Mapping[str, Any]]] | None,
|
|
) -> bool:
|
|
"""Whether *app*'s *variant* switches the guide host on."""
|
|
variants = (variants_per_app or {}).get(app) or []
|
|
if not variant.isdigit() or int(variant) >= len(variants):
|
|
return False
|
|
return declares_guide((variants[int(variant)] or {}).get("services") or {})
|
|
|
|
|
|
def mark(
|
|
entries: list[dict[str, str]],
|
|
variants_per_app: Mapping[str, Sequence[Mapping[str, Any]]] | None,
|
|
) -> list[dict[str, str]]:
|
|
"""Hand one entry per role the replay.
|
|
|
|
Only the first entry of the chosen variant: a priority row runs every mode
|
|
and network mode it offers, and replaying the same README block in each of
|
|
them proves nothing the first replay did not.
|
|
|
|
The row has to run in the guide's own mode. The replay is a second deploy
|
|
on the same runner, so hanging it on a swarm row would ask that runner to
|
|
bring a compose stack up beside a swarm one.
|
|
"""
|
|
marked: set[str] = set()
|
|
for entry in entries:
|
|
app = entry["apps"]
|
|
if app in marked or redundant(entry):
|
|
continue
|
|
mode = guide_deployable(app)
|
|
if not mode or entry["mode"] != mode:
|
|
continue
|
|
if not _carries_guide(app, entry["variant"], variants_per_app):
|
|
continue
|
|
entry["instructions"] = mode
|
|
marked.add(app)
|
|
return entries
|