diff --git a/ops/runner/check-awoooi-non110-runner-readiness.sh b/ops/runner/check-awoooi-non110-runner-readiness.sh index 5bea5aa2..8c00cf5b 100755 --- a/ops/runner/check-awoooi-non110-runner-readiness.sh +++ b/ops/runner/check-awoooi-non110-runner-readiness.sh @@ -8,9 +8,9 @@ set -euo pipefail TARGET_HOST_IP="${TARGET_HOST_IP:-192.168.0.188}" FORBIDDEN_HOST_IPS="${FORBIDDEN_HOST_IPS:-192.168.0.110}" -RUNNER_CONFIG_PATHS="${RUNNER_CONFIG_PATHS:-/home/wooo/act-runner-awoooi/config.yaml /home/wooo/awoooi-act-runner/config.yaml /home/wooo/awoooi-non110-runner/config.yaml /home/wooo/act-runner/config.yaml}" -RUNNER_BINARY_PATHS="${RUNNER_BINARY_PATHS:-/home/wooo/act-runner-awoooi/act_runner /home/wooo/awoooi-act-runner/act_runner /home/wooo/awoooi-non110-runner/act_runner /home/wooo/act-runner/act_runner}" -RUNNER_REGISTRATION_PATHS="${RUNNER_REGISTRATION_PATHS:-/home/wooo/act-runner-awoooi/.runner /home/wooo/awoooi-act-runner/.runner /home/wooo/awoooi-non110-runner/.runner /home/wooo/act-runner/.runner}" +RUNNER_CONFIG_PATHS="${RUNNER_CONFIG_PATHS:-/home/wooo/act-runner-awoooi/config.yaml /home/wooo/awoooi-act-runner/config.yaml /home/wooo/awoooi-non110-runner/config.yaml /home/wooo/act-runner/config.yaml /home/ollama/act-runner-awoooi/config.yaml /home/ollama/awoooi-non110-runner/config.yaml}" +RUNNER_BINARY_PATHS="${RUNNER_BINARY_PATHS:-/home/wooo/act-runner-awoooi/act_runner /home/wooo/awoooi-act-runner/act_runner /home/wooo/awoooi-non110-runner/act_runner /home/wooo/act-runner/act_runner /home/ollama/act-runner-awoooi/act_runner /home/ollama/awoooi-non110-runner/act_runner}" +RUNNER_REGISTRATION_PATHS="${RUNNER_REGISTRATION_PATHS:-/home/wooo/act-runner-awoooi/.runner /home/wooo/awoooi-act-runner/.runner /home/wooo/awoooi-non110-runner/.runner /home/wooo/act-runner/.runner /home/ollama/act-runner-awoooi/.runner /home/ollama/awoooi-non110-runner/.runner}" RUNNER_SERVICE_NAMES="${RUNNER_SERVICE_NAMES:-awoooi-non110-runner.service gitea-act-runner-awoooi.service gitea-act-runner-host.service}" ALLOWED_LABEL_NAMES="${ALLOWED_LABEL_NAMES:-awoooi-non110-host awoooi-non110-ubuntu awoooi-host awoooi-ubuntu}" FORBIDDEN_LABEL_RE="${FORBIDDEN_LABEL_RE:-^(ubuntu-latest|ubuntu-[0-9].*|self-hosted|stockplatform.*|stock-platform.*|headless.*|playwright.*)$}" @@ -77,12 +77,15 @@ systemd_cat() { systemd_show() { local unit="$1" - if systemctl show "$unit" >/dev/null 2>&1; then - systemctl show "$unit" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null + local out + if out="$(systemctl show "$unit" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null)" \ + && ! grep -q '^LoadState=not-found$' <<<"$out"; then + printf '%s\n' "$out" return 0 fi - if systemctl --user show "$unit" >/dev/null 2>&1; then - systemctl --user show "$unit" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null + if out="$(systemctl --user show "$unit" -p LoadState -p ActiveState -p UnitFileState -p MainPID --no-pager 2>/dev/null)" \ + && ! grep -q '^LoadState=not-found$' <<<"$out"; then + printf '%s\n' "$out" return 0 fi return 1 @@ -387,6 +390,13 @@ main() { return 0 fi printf 'AWOOOI_NON110_RUNNER_READY=0\n' + if [ "$READY_CONFIG_COUNT" -gt 0 ] \ + && [ "$READY_BINARY_COUNT" -gt 0 ] \ + && [ "$READY_SERVICE_COUNT" -gt 0 ] \ + && [ "$READY_REGISTRATION_COUNT" -eq 0 ]; then + printf 'safe_next_step=complete_runner_registration_without_printing_token_then_enable_service_and_rerun_this_verifier\n' + return 1 + fi printf 'safe_next_step=install_or_fix_non110_runner_config_service_rollback_then_rerun_this_verifier\n' return 1 } diff --git a/ops/runner/test_check_awoooi_non110_runner_readiness.py b/ops/runner/test_check_awoooi_non110_runner_readiness.py new file mode 100644 index 00000000..6518be9f --- /dev/null +++ b/ops/runner/test_check_awoooi_non110_runner_readiness.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import os +import subprocess +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] +VERIFIER = ROOT / "ops/runner/check-awoooi-non110-runner-readiness.sh" + + +def _write_fake_bin(path: Path, name: str, body: str) -> None: + target = path / name + target.write_text(body, encoding="utf-8") + target.chmod(0o755) + + +def _write_runner_config(path: Path) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text( + """ +runner: + capacity: 1 + labels: + - "awoooi-host:host" + - "awoooi-ubuntu:docker://192.168.0.110:5000/awoooi/ci-runner:act-22.04" +""".strip() + + "\n", + encoding="utf-8", + ) + + +def _write_unit(path: Path) -> None: + path.write_text( + """ +[Service] +ExecStart=/tmp/act_runner daemon --config /tmp/config.yaml +Restart=always +CPUQuota=200% +MemoryMax=8G +TasksMax=512 +NoNewPrivileges=true +""".strip() + + "\n", + encoding="utf-8", + ) + + +def _run_verifier( + tmp_path: Path, + registration_path: Path, + *, + active_service: bool = True, +) -> subprocess.CompletedProcess[str]: + fake_bin = tmp_path / "bin" + unit_dir = tmp_path / "units" + fake_bin.mkdir() + unit_dir.mkdir() + _write_fake_bin( + fake_bin, + "systemctl", + f"""#!/usr/bin/env bash +set -euo pipefail +if [ "${{1:-}}" = "--user" ]; then shift; fi +cmd="${{1:-}}"; unit="${{2:-}}" +case "$cmd" in + show) + if [ "${{2:-}}" = "-p" ]; then + unit="${{1:-}}" + fi + if [ -f "{unit_dir}/$unit" ]; then + printf 'LoadState=loaded\\nActiveState={"active" if active_service else "inactive"}\\nUnitFileState=disabled\\nMainPID={"1234" if active_service else "0"}\\n' + exit 0 + fi + if [ "${{2:-}}" = "-p" ] && [ "${{3:-}}" = "LoadState" ]; then + printf 'not-found\\n' + exit 0 + fi + printf 'LoadState=not-found\\nActiveState=inactive\\nUnitFileState=\\nMainPID=0\\n' + exit 0 + ;; + cat) + if [ -f "{unit_dir}/$unit" ]; then cat "{unit_dir}/$unit"; exit 0; fi + exit 1 + ;; +esac +exit 1 +""", + ) + _write_fake_bin( + fake_bin, + "docker", + """#!/usr/bin/env bash +if [ "${1:-}" = "ps" ]; then exit 0; fi +exit 0 +""", + ) + _write_fake_bin( + fake_bin, + "pgrep", + """#!/usr/bin/env bash +exit 1 +""", + ) + _write_fake_bin( + fake_bin, + "ip", + """#!/usr/bin/env bash +if [ "${1:-}" = "-o" ] && [ "${2:-}" = "-4" ] && [ "${3:-}" = "addr" ]; then + printf '1: lo inet 127.0.0.1/8 scope host lo\\n' + printf '2: eth0 inet 192.168.0.188/24 brd 192.168.0.255 scope global eth0\\n' + exit 0 +fi +exit 1 +""", + ) + + config_path = tmp_path / "config.yaml" + binary_path = tmp_path / "act_runner" + _write_runner_config(config_path) + binary_path.write_text("#!/usr/bin/env bash\nexit 0\n", encoding="utf-8") + binary_path.chmod(0o755) + _write_unit(unit_dir / "awoooi-non110-runner.service") + _write_unit(unit_dir / "awoooi-non110-runner-rollback.service") + + env = { + **os.environ, + "PATH": f"{fake_bin}:{os.environ['PATH']}", + "TARGET_HOST_IP": "", + "FORBIDDEN_HOST_IPS": "", + "RUNNER_CONFIG_PATHS": str(config_path), + "RUNNER_BINARY_PATHS": str(binary_path), + "RUNNER_SERVICE_NAMES": "awoooi-non110-runner.service", + "ROLLBACK_UNIT_NAMES": "awoooi-non110-runner-rollback.service", + "RUNNER_REGISTRATION_PATHS": str(registration_path), + "MAX_HEAVY_PROCESS_COUNT": "0", + } + return subprocess.run( + ["bash", str(VERIFIER)], + check=False, + env=env, + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + + +def test_non110_readiness_blocks_without_registration_state(tmp_path: Path) -> None: + result = _run_verifier(tmp_path, tmp_path / ".runner") + assert result.returncode == 1 + assert "BLOCKER runner_registration_missing" in result.stdout + assert "AWOOOI_NON110_RUNNER_READY=0" in result.stdout + assert "raw_runner_registration_read=false" in result.stdout + assert ( + "safe_next_step=complete_runner_registration_without_printing_token_then_enable_service_and_rerun_this_verifier" + in result.stdout + ) + + +def test_non110_readiness_accepts_registration_state_presence_without_reading_it( + tmp_path: Path, +) -> None: + registration_path = tmp_path / ".runner" + registration_path.write_text("secret-token-like-content-not-printed\n", encoding="utf-8") + result = _run_verifier(tmp_path, registration_path) + assert result.returncode == 0, result.stdout + result.stderr + assert "RUNNER_REGISTRATION" in result.stdout + assert "present=1" in result.stdout + assert "content_read=false" in result.stdout + assert "secret-token-like-content" not in result.stdout + assert "AWOOOI_NON110_RUNNER_READY=1" in result.stdout