GRM-17: fix docker inspect Jinja2 conflict and add per-iteration exception handling
- docker inspect -f "{{.State.Status}}" used Go template braces that
conflicted with Ansible Jinja2 templating in the shell module.
Ansible tried to parse {{.State.Status}} as a Jinja2 variable (which
starts with a dot, making it invalid), causing a local template error.
The outer except Exception caught this immediately, so the fallback
loop never reached the legacy container name or systemctl checks.
- Replaced with: docker inspect <name> | python3 -c JSON parsing,
which avoids any brace syntax and uses python3 (already required by
Ansible on managed nodes).
- Added per-iteration try/except inside the fallback loop so a failure
on one container name continues to the next fallback instead of
aborting the entire check.
- Added tests for fallback behavior and binary mode exception path.
128 tests, 100% coverage, ruff + pyright clean
This commit is contained in:
@@ -295,27 +295,36 @@ class RunnerManager:
|
||||
lines = [ln for ln in stdout.splitlines() if ln.strip() and not any(p in ln for p in ansible_noise)]
|
||||
return lines[-1].strip() if lines else "unknown"
|
||||
|
||||
try:
|
||||
if mode == "docker":
|
||||
# Try expected container name first, then host-based fallback for legacy installs
|
||||
for container_name in (f"gitea-runner-{name}", f"gitea-runner-{host}"):
|
||||
service_status = "unknown"
|
||||
if mode == "docker":
|
||||
# Try expected container name first, then host-based fallback for legacy installs.
|
||||
# Use python3 JSON parsing to avoid Jinja2 brace conflicts in Ansible shell args.
|
||||
for container_name in (f"gitea-runner-{name}", f"gitea-runner-{host}"):
|
||||
try:
|
||||
stdout = self._executor.run_ad_hoc(
|
||||
host,
|
||||
user,
|
||||
key,
|
||||
"shell",
|
||||
f"docker inspect -f '{{{{.State.Status}}}}' {container_name} 2>/dev/null",
|
||||
(
|
||||
f"docker inspect {container_name} 2>/dev/null | "
|
||||
f"python3 -c \"import sys,json; print(json.load(sys.stdin)[0]['State']['Status'])\" "
|
||||
f"2>/dev/null || echo unknown"
|
||||
),
|
||||
become=True,
|
||||
ask_become_pass=True,
|
||||
check=False,
|
||||
)
|
||||
service_status = _parse_status(stdout)
|
||||
if service_status != "unknown":
|
||||
docker_map = {"running": "active", "exited": "inactive", "dead": "failed"}
|
||||
service_status = docker_map.get(service_status, "unknown")
|
||||
break
|
||||
else:
|
||||
# Final fallback: check systemd service (for installs using the fixed template)
|
||||
except Exception:
|
||||
continue
|
||||
status = _parse_status(stdout)
|
||||
if status != "unknown":
|
||||
docker_map = {"running": "active", "exited": "inactive", "dead": "failed"}
|
||||
service_status = docker_map.get(status, "unknown")
|
||||
break
|
||||
else:
|
||||
# Final fallback: check systemd service (for installs using the fixed template)
|
||||
try:
|
||||
stdout = self._executor.run_ad_hoc(
|
||||
host,
|
||||
user,
|
||||
@@ -327,7 +336,10 @@ class RunnerManager:
|
||||
check=False,
|
||||
)
|
||||
service_status = _parse_status(stdout)
|
||||
else:
|
||||
except Exception:
|
||||
service_status = "unknown"
|
||||
else:
|
||||
try:
|
||||
stdout = self._executor.run_ad_hoc(
|
||||
host,
|
||||
user,
|
||||
@@ -339,8 +351,8 @@ class RunnerManager:
|
||||
check=False,
|
||||
)
|
||||
service_status = _parse_status(stdout)
|
||||
except Exception:
|
||||
service_status = "unknown"
|
||||
except Exception:
|
||||
service_status = "unknown"
|
||||
# Translate known status values
|
||||
translated_status = _(
|
||||
service_status if service_status in {"active", "inactive", "failed", "unknown"} else "unknown"
|
||||
|
||||
Reference in New Issue
Block a user