mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-11 21:26:44 +00:00
The deploy decides what ADAPTER_PORT or OPENWEBUI_ADMIN_NAME is and
writes it into the environment. A default in the reader is a second place
that value lives, and it is the one nobody greps for. os.environ["X"]
fails loudly on a missing key, which is the behaviour a misconfiguration
deserves.
Empty values stay free, because they add no second source and only say
absent: "", None, False, 0, the empty containers, and the "[]"/"{}" a
json.loads reader hands an absent variable. A default that is itself an
environ.get is free too, since it reads the one source again under
another key; a literal ending such a chain is still reported. Detection
runs on the parsed tree, so a call split across lines reads the same.
Five sites were real duplication and lost their default: the adapter
port, openwebui's admin name (a role that runs as a bot user), odoo's
OIDC uid field, seaweedfs' public-primary flag, and the swarm hosts
entry IP. Nineteen carry a nocheck naming why the value is not the
deploy's: contributor tooling whose default is the only source, test
scaffolding that writes the file it names, and two readers of
CA_TRUST_CERT_EXTRA_HOST, which nothing in the repo sets.
utils/diagnostics/container.py resolves without a marker: RESCUE_DEPTH is
a recursion base case, and the integer 0 says what the string "0" said.
The file sits exactly at the 500-line cap, so a comment line was not
available.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diagnostics: recursive container rescue snapshot
container.py is the single failure-diagnostics entry point. The CI
workflows (compose + swarm) call it once on the runner when a job fails;
it captures the current level and then recurses itself through every
Docker-in-Docker boundary, so one call collects evidence from the
outermost runner down to the innermost application container. It always
exits 1.
flowchart TB
subgraph entry["🩺 One workflow call on failure()"]
wf["⚙️ CI step (compose + swarm identical)<br/>INFINITO_RESCUE_DIAGNOSTICS_DIR=/tmp/rescue-diagnostics/<app><br/>python3 utils/diagnostics/container.py <app> <context>"]:::infra
end
subgraph level["📸 Per-level capture (repeated on every depth)"]
direction TB
host["🖥️ Host facts<br/>meta, uname, df/free/uptime,<br/>journal, dmesg OOM evidence"]:::store
dumps["📂 local-dumps/<br/>in-play role evidence from<br/>DIR_RESCUE_DIAGNOSTICS (pg_hba, xwiki)"]:::store
rtc["🐳 Runtime state<br/>info, stats, ps -a,<br/>per-container logs + inspect"]:::store
svc["🐝 Swarm services<br/>ls, per-service ps + logs"]:::store
end
subgraph recursion["🔁 Recursion (RESCUE_MAX_DEPTH, default 3)"]
direction TB
probe["🔍 For every RUNNING container:<br/>has python3 + docker/container runtime?"]:::step
copy["📤 Copy itself in<br/>(stdin → /tmp/rescue-self.py)"]:::step
nested["🩺 Run nested capture<br/>RESCUE_DEPTH+1, own staging dir"]:::step
pull["📥 tar the nested snapshot back to<br/>containers/<name>/nested/ + clean up"]:::step
probe -->|yes| copy --> nested --> pull
probe -.->|no: plain app container,<br/>logs already captured| skipped["⏭️ skip"]:::skip
end
wf --> level --> recursion
nested -.->|same program,<br/>one level deeper| level
result["🗂️ Artifact tree (uploaded by CI)<br/><app>-<stamp>-<pid>/<br/>├── meta/system/journal/…<br/>├── local-dumps/…<br/>├── containers/<name>.log + .inspect.json<br/>├── containers/<did-node>/nested/<app>-…/ (recursion)<br/>└── services/<svc>.log + .ps.txt"]:::store
recursion --> result
classDef infra fill:#f3f7fb,stroke:#d6e2ee,color:#455a64;
classDef store fill:#f1f8f6,stroke:#d5e7e2,color:#455a64;
classDef step fill:#fbf6f0,stroke:#eee1cf,color:#455a64;
classDef skip fill:#f7f8f9,stroke:#e3e6e9,color:#455a64;
style entry fill:#ffffff,stroke:#e6e6e6;
style level fill:#ffffff,stroke:#e6e6e6;
style recursion fill:#ffffff,stroke:#e6e6e6;
Ansible rescue: blocks are forbidden
(tests/lint/ansible/structure/test_no_rescue_blocks.py); the rare
justified block (# nocheck: rescue-<reason>) leaves its role-specific
evidence in DIR_RESCUE_DIAGNOSTICS, which every capture level ships as
local-dumps/.