#!/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, binary_path: Path, config_path: Path, registration_path: Path, ) -> None: path.write_text( f""" [Unit] ConditionPathExists={registration_path} [Service] ExecStart={binary_path} daemon --config {config_path} Restart=always CPUQuota=200% MemoryMax=8G TasksMax=512 NoNewPrivileges=true """.strip() + "\n", encoding="utf-8", ) def _write_path_unit(path: Path, registration_path: Path) -> None: path.write_text( f""" [Unit] Description=Watch AWOOOI non-110 runner registration metadata [Path] PathExists={registration_path} Unit=awoooi-non110-runner-autostart.service [Install] WantedBy=default.target """.strip() + "\n", encoding="utf-8", ) def _write_keepalive_timer(path: Path) -> None: path.write_text( """ [Unit] Description=Periodically verify AWOOOI non-110 runner user service is active [Timer] OnBootSec=30s OnUnitInactiveSec=60s AccuracySec=10s Unit=awoooi-non110-runner-keepalive.service [Install] WantedBy=timers.target """.strip() + "\n", encoding="utf-8", ) def _write_keepalive_service(path: Path) -> None: path.write_text( """ [Unit] Description=Keep AWOOOI non-110 runner active while enable sentinel exists [Service] Type=oneshot ExecStart=/usr/bin/systemctl --user daemon-reload ExecStart=-/usr/bin/systemctl --user reset-failed awoooi-non110-runner.service ExecStart=/usr/bin/systemctl --user enable awoooi-non110-runner.service ExecStart=/usr/bin/systemctl --user start awoooi-non110-runner.service RemainAfterExit=no """.strip() + "\n", encoding="utf-8", ) def _run_verifier( tmp_path: Path, registration_path: Path, *, active_service: bool = True, unit_target_matches: bool = True, unmanaged_runner_container: bool = False, keepalive_timer: bool = True, keepalive_service_failed: bool = False, ) -> 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 if [[ "$unit" == *.path ]]; then printf 'LoadState=loaded\\nActiveState=active\\nUnitFileState=enabled\\nMainPID=0\\n' exit 0 fi if [[ "$unit" == *.timer ]]; then printf 'LoadState=loaded\\nActiveState=active\\nUnitFileState=enabled\\nMainPID=0\\n' exit 0 fi if [[ "$unit" == *keepalive.service ]]; then printf 'LoadState=loaded\\nActiveState={"failed" if keepalive_service_failed else "inactive"}\\nUnitFileState=static\\nMainPID=0\\nResult={"exit-code" if keepalive_service_failed else "success"}\\nExecMainStatus={"1" if keepalive_service_failed else "0"}\\n' exit 0 fi 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 """, ) unmanaged_runner_output = ( "printf 'condescending_wilbur|gitea/act_runner:latest\\n'" if unmanaged_runner_container else "exit 0" ) _write_fake_bin( fake_bin, "docker", f"""#!/usr/bin/env bash if [ "${{1:-}}" = "ps" ]; then if printf '%s\\n' "$*" | grep -q 'Image'; then {unmanaged_runner_output} exit 0 fi 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) unit_binary_path = binary_path if unit_target_matches else tmp_path / "other_act_runner" unit_config_path = config_path if unit_target_matches else tmp_path / "other_config.yaml" _write_unit( unit_dir / "awoooi-non110-runner.service", unit_binary_path, unit_config_path, registration_path, ) _write_unit( unit_dir / "awoooi-non110-runner-rollback.service", unit_binary_path, unit_config_path, registration_path, ) _write_path_unit( unit_dir / "awoooi-non110-runner-autostart.path", registration_path, ) if keepalive_timer: _write_keepalive_service(unit_dir / "awoooi-non110-runner-keepalive.service") _write_keepalive_timer(unit_dir / "awoooi-non110-runner-keepalive.timer") 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", "RUNNER_AUTOSTART_PATH_UNIT_NAMES": "awoooi-non110-runner-autostart.path", "RUNNER_KEEPALIVE_SERVICE_UNIT_NAMES": "awoooi-non110-runner-keepalive.service", "RUNNER_KEEPALIVE_TIMER_UNIT_NAMES": "awoooi-non110-runner-keepalive.timer", "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=run_register_awoooi_non110_runner_script_without_printing_token_then_autostart_path_will_enable_service_and_rerun_this_verifier" in result.stdout ) assert "RUNNER_AUTOSTART_PATH unit=awoooi-non110-runner-autostart.path installed=1" in result.stdout assert ( "RUNNER_AUTOSTART_PATH_WATCH unit=awoooi-non110-runner-autostart.path registration_watch=1 active=1 enabled=1" in result.stdout ) assert "READY_AUTOSTART_PATH_COUNT=1" in result.stdout assert "RUNNER_KEEPALIVE_TIMER unit=awoooi-non110-runner-keepalive.timer installed=1" in result.stdout assert "BLOCKER runner_keepalive_timer_not_ready" not in result.stdout assert "BLOCKER runner_keepalive_service_not_ready" not 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 "registration_condition=1" in result.stdout assert "RUNNER_KEEPALIVE_SERVICE unit=awoooi-non110-runner-keepalive.service installed=1" in result.stdout assert "READY_KEEPALIVE_SERVICE_COUNT=1" in result.stdout assert "RUNNER_KEEPALIVE_TIMER unit=awoooi-non110-runner-keepalive.timer installed=1" in result.stdout assert "READY_KEEPALIVE_TIMER_COUNT=1" in result.stdout assert "secret-token-like-content" not in result.stdout assert "AWOOOI_NON110_RUNNER_READY=1" in result.stdout def test_non110_readiness_blocks_failed_keepalive_service(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, keepalive_service_failed=True, ) assert result.returncode == 1 assert "BLOCKER runner_keepalive_service_failed:awoooi-non110-runner-keepalive.service" in result.stdout assert "BLOCKER runner_keepalive_service_not_ready" in result.stdout assert "secret-token-like-content" not in result.stdout assert "AWOOOI_NON110_RUNNER_READY=0" in result.stdout def test_non110_readiness_blocks_registered_runner_without_keepalive_timer( 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, keepalive_timer=False) assert result.returncode == 1 assert "BLOCKER runner_keepalive_timer_not_ready" in result.stdout assert "READY_KEEPALIVE_TIMER_COUNT=0" in result.stdout assert "secret-token-like-content" not in result.stdout assert "AWOOOI_NON110_RUNNER_READY=0" in result.stdout def test_non110_readiness_blocks_service_target_mismatch(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, unit_target_matches=False) assert result.returncode == 1 assert "BLOCKER runner_service_target_mismatch:awoooi-non110-runner.service" in result.stdout assert "RUNNER_SERVICE_TARGETS unit=awoooi-non110-runner.service" in result.stdout assert "AWOOOI_NON110_RUNNER_READY=0" in result.stdout def test_non110_readiness_blocks_unmanaged_act_runner_container(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, unmanaged_runner_container=True, ) assert result.returncode == 1 assert "UNMANAGED_RUNNER_CONTAINERS=condescending_wilbur" in result.stdout assert ( "BLOCKER unmanaged_runner_containers_present:condescending_wilbur" in result.stdout ) assert "secret-token-like-content" not in result.stdout