mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
fix(test): repo-lint compliance + seaweedfs api-primary readiness
- _shared.js: wrap the boot-poll delay in resolveTimeout (raw-timeout lint) - 02_render_inventory: docker -> container wrapper (engine-abstraction lint) - seaweedfs: api becomes the primary canonical so the deploy readiness probe hits a served vhost when the frontend (filer/master) is disabled - seaweedfs frontend: exempt from variant pinning — the onion gate is a hard invariant, no variant may force the frontend on a tor node - test_coverage: add the `# nocheck: variants-coverage` exempt (same mechanism as bond-baseline) for such invariant flags Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
32b2cf7e80
commit
4e6ef25423
5 files changed
+39
-6
No files matched your search
@@ -65,7 +65,7 @@ async function gotoElementApp(page, url, readyLocator) {
|
||||
if (await readyLocator.isVisible().catch(() => false)) return;
|
||||
const bodyText = await page.locator("body").innerText().catch(() => "");
|
||||
if (ELEMENT_INIT_CRASH_RE.test(bodyText)) break;
|
||||
await page.waitForTimeout(2_000);
|
||||
await page.waitForTimeout(resolveTimeout(2_000));
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
- name: "reconfigure matrix-mdad on inventory change"
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
_mp="$(docker volume inspect -f '{% raw %}{{ .Mountpoint }}{% endraw %}' matrix_matrix_mdad_state)"
|
||||
_mp="$(container volume inspect -f '{% raw %}{{ .Mountpoint }}{% endraw %}' matrix_matrix_mdad_state)"
|
||||
rm -f "${_mp}/bootstrap.done"
|
||||
if docker ps -q -f name=^matrix-mdad$ | grep -q .; then
|
||||
docker restart matrix-mdad
|
||||
if container ps -q -f name=^matrix-mdad$ | grep -q .; then
|
||||
container restart matrix-mdad
|
||||
fi
|
||||
args:
|
||||
executable: /bin/bash
|
||||
|
||||
@@ -12,9 +12,9 @@ status_codes:
|
||||
- 403
|
||||
domains:
|
||||
canonical:
|
||||
api: api.seaweedfs.s3.{{ DOMAIN_PRIMARY }}
|
||||
filer: filer.seaweedfs.s3.{{ DOMAIN_PRIMARY }}
|
||||
master: master.seaweedfs.s3.{{ DOMAIN_PRIMARY }}
|
||||
api: api.seaweedfs.s3.{{ DOMAIN_PRIMARY }}
|
||||
aliases: []
|
||||
csp:
|
||||
flags: {}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
# nocheck: tor-contract — object-storage backend; consumed server-side over the
|
||||
# internal network (matrix S3 media etc.), never a Tor-browser surface, so it
|
||||
# rides no node onion.
|
||||
# nocheck: dynamic-flag — role-local browser UI, never consumed by other roles; shared stays literal.
|
||||
# nocheck: variants-coverage — the onion gate is a hard invariant; no variant may force the frontend on a tor node.
|
||||
# nocheck: bond-baseline — same reason: variant 0 must not pin the frontend on.
|
||||
frontend:
|
||||
bond: 1
|
||||
enabled: "{{ 'svc-net-tor' not in group_names }}"
|
||||
|
||||
@@ -28,10 +28,16 @@ For databases the same rule reduces to coverage of ``shared``: the
|
||||
DB-consumer ``enabled`` flag stays literal ``true`` (with
|
||||
``# nocheck: dynamic-flag``), so only ``shared`` is dynamic and needs
|
||||
the two-polarity coverage.
|
||||
|
||||
Exempt a service with ``# nocheck: variants-coverage`` on (or directly
|
||||
above) its ``meta/services.yml`` key — for flags whose group-derived
|
||||
value is a hard invariant that variants must never override (e.g. a
|
||||
browser frontend that must stay off on onion nodes).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@@ -51,6 +57,25 @@ if TYPE_CHECKING:
|
||||
ROLES_DIR = PROJECT_ROOT / "roles"
|
||||
|
||||
|
||||
_NOCHECK_RE = re.compile(r"#\s*nocheck:\s*variants-coverage\b")
|
||||
|
||||
|
||||
def _service_nocheck(lines: list[str], key: str) -> bool:
|
||||
pat = re.compile(r"^" + re.escape(key) + r"\s*:")
|
||||
for i, line in enumerate(lines):
|
||||
if not pat.match(line):
|
||||
continue
|
||||
if _NOCHECK_RE.search(line):
|
||||
return True
|
||||
j = i - 1
|
||||
while j >= 0 and lines[j].lstrip().startswith("#"):
|
||||
if _NOCHECK_RE.search(lines[j]):
|
||||
return True
|
||||
j -= 1
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
def _is_dynamic_flag(value) -> bool:
|
||||
return isinstance(value, str) and "in group_names" in value
|
||||
|
||||
@@ -114,7 +139,12 @@ class TestVariantsCoverage(unittest.TestCase):
|
||||
if not isinstance(services, dict):
|
||||
continue
|
||||
|
||||
pairs = _dynamic_pairs(services)
|
||||
services_lines = services_path.read_text(encoding="utf-8").splitlines()
|
||||
pairs = [
|
||||
(key, flag)
|
||||
for key, flag in _dynamic_pairs(services)
|
||||
if not _service_nocheck(services_lines, key)
|
||||
]
|
||||
if not pairs:
|
||||
continue
|
||||
|
||||
|
||||
Reference in new issue
Block a user