GRM-17: fix grm list status — use docker inspect for docker mode, add host/user context

- Docker mode runners now check container status via docker inspect
  instead of systemctl is-active, avoiding false unknown when systemd
  service is missing or stderr output is discarded
- Binary mode still uses systemctl is-active with stderr suppressed
- Both modes now show a translated context message before the check so
  users know which host/user each BECOME password prompt belongs to
- Better ansible output filtering: strip CHANGED/FAILED/UNREACHABLE
  header lines and separator noise
- Map Docker container states (running/exited/dead) to systemd vocabulary
- All new user-facing messages fully translated (en/bg/de/ru/zh)
- 125 tests, 100% coverage, pyright clean, ruff clean
This commit is contained in:
Emil Simeonov
2026-06-19 02:35:53 +02:00
parent 51f204f90a
commit 12e6ce1601
3 changed files with 86 additions and 16 deletions
+40 -3
View File
@@ -392,14 +392,14 @@ class TestRunnerManager:
mock_executor.run.assert_not_called()
mock_registry.remove.assert_called_once_with("r1")
def test_list_runners(self) -> None:
def test_list_runners_docker(self) -> None:
mock_registry = MagicMock()
mock_registry.list.return_value = {
"r1": {"host": "10.0.0.1", "user": "ubuntu", "key": "/key", "mode": "docker"},
}
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
mock_executor.run_ad_hoc.return_value = "active"
mock_executor.run_ad_hoc.return_value = "running"
manager._executor = mock_executor
runners = manager.list_runners()
@@ -412,7 +412,31 @@ class TestRunnerManager:
"ubuntu",
"/key",
"shell",
"systemctl is-active gitea-runner@r1",
"docker inspect -f '{{.State.Status}}' gitea-runner-r1 2>/dev/null",
become=True,
ask_become_pass=True,
check=False,
)
def test_list_runners_binary(self) -> None:
mock_registry = MagicMock()
mock_registry.list.return_value = {
"r1": {"host": "10.0.0.1", "user": "ubuntu", "key": "/key", "mode": "binary"},
}
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
mock_executor.run_ad_hoc.return_value = "active"
manager._executor = mock_executor
runners = manager.list_runners()
assert len(runners) == 1
assert runners[0]["status"] == "active"
mock_executor.run_ad_hoc.assert_called_once_with(
"10.0.0.1",
"ubuntu",
"/key",
"shell",
"systemctl is-active gitea-runner@r1 2>/dev/null",
become=True,
ask_become_pass=True,
check=False,
@@ -424,6 +448,19 @@ class TestRunnerManager:
manager = RunnerManager(registry=mock_registry)
assert manager.list_runners() == []
def test_list_runners_docker_exited(self) -> None:
mock_registry = MagicMock()
mock_registry.list.return_value = {
"r1": {"host": "10.0.0.1", "user": "ubuntu", "key": None, "mode": "docker"},
}
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
mock_executor.run_ad_hoc.return_value = "exited"
manager._executor = mock_executor
runners = manager.list_runners()
assert runners[0]["status"] == "inactive"
def test_list_runners_unknown_status(self) -> None:
mock_registry = MagicMock()
mock_registry.list.return_value = {