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
+7
View File
@@ -205,6 +205,13 @@ TRANSLATIONS: dict[str, dict[str, str]] = {
"ru": "Проверка состояния Gitea Runner {name} на {host}",
"zh": "正在检查 {host} 上 Gitea Runner {name} 的状态",
},
"Checking status of Gitea Runner {name} on {host} as {user} (sudo required)": {
"en": "Checking status of Gitea Runner {name} on {host} as {user} (sudo required)",
"bg": "Проверка на състоянието на Gitea Runner {name} на {host} като {user} (необходим е sudo)",
"de": "Prüfe Status von Gitea Runner {name} auf {host} als {user} (sudo erforderlich)",
"ru": "Проверка состояния Gitea Runner {name} на {host} как {user} (требуется sudo)",
"zh": "正在检查 {host} 上 Gitea Runner {name} 的状态(用户 {user},需要 sudo",
},
"Removing Gitea Runner {name} from {host}": {
"en": "Removing Gitea Runner {name} from {host}",
"bg": "Премахване на Gitea Runner {name} от {host}",
+39 -13
View File
@@ -9,6 +9,7 @@ from .executor import AnsibleExecutor
from .i18n import _
from .registry import RunnerRegistry
from .report import track_steps
from .ui import say
class RunnerManager:
@@ -280,23 +281,48 @@ class RunnerManager:
user = info["user"]
key = info.get("key")
mode = info.get("mode", "docker")
try:
stdout = self._executor.run_ad_hoc(
host,
user,
key,
"shell",
f"systemctl is-active gitea-runner@{name}",
become=True,
ask_become_pass=True,
check=False,
say(
_(
"Checking status of Gitea Runner {name} on {host} as {user} (sudo required)",
name=name,
host=host,
user=user,
)
# Filter out ansible noise (SSH warnings etc)
lines = [ln for ln in stdout.splitlines() if ln.strip() and not ln.startswith(("[WARNING]", "ssh:"))]
)
try:
if mode == "docker":
stdout = self._executor.run_ad_hoc(
host,
user,
key,
"shell",
f"docker inspect -f '{{{{.State.Status}}}}' gitea-runner-{name} 2>/dev/null",
become=True,
ask_become_pass=True,
check=False,
)
else:
stdout = self._executor.run_ad_hoc(
host,
user,
key,
"shell",
f"systemctl is-active gitea-runner@{name} 2>/dev/null",
become=True,
ask_become_pass=True,
check=False,
)
# Filter out ansible noise (headers, warnings, SSH messages)
ansible_noise = (" | CHANGED | ", " | FAILED | ", " | UNREACHABLE | ", "[WARNING]", "ssh:", ">>")
lines = [ln for ln in stdout.splitlines() if ln.strip() and not any(p in ln for p in ansible_noise)]
service_status = lines[-1].strip() if lines else "unknown"
# Docker statuses need mapping to systemd vocabulary
if mode == "docker":
docker_map = {"running": "active", "exited": "inactive", "dead": "failed"}
service_status = docker_map.get(service_status, "unknown")
except Exception:
service_status = "unknown"
# Translate known systemd status values
# Translate known status values
translated_status = _(
service_status if service_status in {"active", "inactive", "failed", "unknown"} else "unknown"
)