mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(swarm-test): read the tor-quiesce container name from the env SPOT
The quiesce guard spelled the dev container as the literal infinito_nexus_debian, so it only ever matched a checkout whose .env was generated for debian without a project prefix. It missed the self-hosted runner form infinito_<project>_nexus_<distro>, any custom.env pin, and any .env generated for another distro — and it missed them silently, because a non-matching grep just skips the block and leaves the competing onion publisher running. INFINITO_CONTAINER is the SPOT for that name: compose.yml uses it as container_name, and scripts/meta/env/load.sh (already sourced at line 19) exports it. Proven against the container running on the author's host: the literal does not match it, the variable does. The outer `docker ps | grep -qx` pre-check is gone with it — `docker exec` on an absent container already exits non-zero with stderr suppressed, and the `if` absorbs that even under `set -euo pipefail`. The variable joins the line-21 assertion so a broken env fails by name instead of dying inside a pipeline subshell, which would reproduce exactly the silent-skip class this commit removes. compose.yml already requires the same variable with `:?`, so this is not a new demand on the environment. tests/lint/repository/test_no_hardcoded_container_name.py pins it: run against the pre-fix file it flags all three lines, and it stays green on the distro-agnostic spellings in stack_refresh.sh and worktree/up.sh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3d93c81f70
commit
05f425ea51
2 files changed
+72
-6
No files matched your search
@@ -18,17 +18,15 @@ set +a
|
||||
# shellcheck source=scripts/meta/env/load.sh
|
||||
source "${SCRIPT_DIR}/../../../../../scripts/meta/env/load.sh"
|
||||
|
||||
: "${RUNNER_TEMP:?}" "${APP_ID:?}" "${INFINITO_DOMAIN:?}"
|
||||
: "${RUNNER_TEMP:?}" "${APP_ID:?}" "${INFINITO_DOMAIN:?}" "${INFINITO_CONTAINER:?}"
|
||||
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
if [ "$(id -u)" -eq 0 ]; then apt-get update -qq || true; else sudo -E apt-get update -qq || true; fi # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
fi
|
||||
|
||||
if docker ps --format '{{.Names}}' | grep -qx 'infinito_nexus_debian'; then
|
||||
if docker exec infinito_nexus_debian docker ps --format '{{.Names}}' 2>/dev/null | grep -qx 'tor'; then
|
||||
echo "==> quiescing CI compose tor (competing onion publisher)"
|
||||
docker exec infinito_nexus_debian docker stop tor
|
||||
fi
|
||||
if docker exec "${INFINITO_CONTAINER}" docker ps --format '{{.Names}}' 2>/dev/null | grep -qx 'tor'; then
|
||||
echo "==> quiescing CI compose tor (competing onion publisher)"
|
||||
docker exec "${INFINITO_CONTAINER}" docker stop tor
|
||||
fi
|
||||
|
||||
bash "${SCRIPT_DIR}/../utils/unmount/nfs_mounts.sh" "${NFS_SERVER}" >/dev/null 2>&1 || true # nocheck: shell-or-true -- grandfathered: worked in practice; TODO: sharpen to catch only the exact tolerated error
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
"""Lint guard: never hard-code the compose container name of one distro.
|
||||
|
||||
``INFINITO_CONTAINER`` is derived from ``INFINITO_DISTRO`` by
|
||||
``utils/env/handlers/infinito/container.py`` and exported into every script
|
||||
by ``scripts/meta/env/load.sh``. A literal ``infinito_nexus_<distro>`` pins
|
||||
the line to one checkout shape: it misses every other distro, the
|
||||
runner-prefixed ``infinito_<project>_nexus_<distro>`` form, and any
|
||||
``custom.env`` override. The guarded branch then never fires, with nothing
|
||||
failing to make that visible. Read ``"${INFINITO_CONTAINER}"`` instead.
|
||||
|
||||
Distro-agnostic spellings carry no literal distro and stay allowed: the
|
||||
``^infinito_nexus_`` prefix match in
|
||||
``scripts/system/network/docker/stack_refresh.sh`` and the slug-composed
|
||||
name in ``scripts/system/worktree/up.sh``. A comment line and the hint text
|
||||
of a ``${VAR:?...}`` expansion name an example in prose rather than a value,
|
||||
so both are skipped.
|
||||
|
||||
Per-line opt-out: ``# nocheck: hardcoded-container`` on the offending line
|
||||
or the one above it.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from utils.annotations.suppress import is_suppressed_at
|
||||
from utils.cache.files import PROJECT_ROOT, iter_project_files, read_text
|
||||
from utils.distros import FILE_META_DISTROS, distro_names
|
||||
|
||||
_RULE = "hardcoded-container"
|
||||
_CONTAINER = re.compile(r"infinito_\w*nexus_(?:" + "|".join(distro_names()) + r")\b")
|
||||
|
||||
|
||||
class TestNoHardcodedContainerName(unittest.TestCase):
|
||||
def test_container_name_is_read_from_the_env_spot(self) -> None:
|
||||
offenders: list[str] = []
|
||||
for path_str in iter_project_files(
|
||||
extensions=(".sh", ".yml"),
|
||||
exclude_tests=True,
|
||||
exclude_dirs=("docs",),
|
||||
):
|
||||
rel = Path(path_str).relative_to(PROJECT_ROOT).as_posix()
|
||||
lines = read_text(path_str).splitlines()
|
||||
for lineno, line in enumerate(lines, 1):
|
||||
match = _CONTAINER.search(line)
|
||||
if match is None:
|
||||
continue
|
||||
if line.lstrip().startswith("#") or ":?" in line[: match.start()]:
|
||||
continue
|
||||
if is_suppressed_at(lines, lineno, _RULE):
|
||||
continue
|
||||
offenders.append(f"{rel}:{lineno}: {line.strip()}")
|
||||
|
||||
if offenders:
|
||||
self.fail(
|
||||
f"{len(offenders)} container name(s) hard-coded to a single "
|
||||
f"distro declared in {FILE_META_DISTROS}. The name is derived "
|
||||
'per distro; read "${INFINITO_CONTAINER}" (exported by '
|
||||
"scripts/meta/env/load.sh) so the line works on every distro, "
|
||||
f"or mark a genuinely single-distro line `# nocheck: {_RULE}`."
|
||||
"\n" + "\n".join(f" - {o}" for o in offenders)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user