mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
The applications: host_vars block is the config namespace keyed by role id, so it also carries system services (sys-ctl-hlth-csp, sys-svc-container). Those declare system_service_id and match no application role, and the resolver died on them instead of reporting their absence. role_name now raises RoleNotFoundError and exits 3, distinct from argparse's usage error (2) and from a genuine failure (1). run_subprocess grew ok_returncodes so a caller can accept an expected non-zero status while every other failure still surfaces, and resolve_role_path returns None for that code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
30 lines
879 B
Python
30 lines
879 B
Python
from __future__ import annotations
|
|
|
|
import subprocess
|
|
|
|
|
|
def run_subprocess(
|
|
cmd: list[str],
|
|
capture_output: bool = False,
|
|
env: dict[str, str] | None = None,
|
|
ok_returncodes: tuple[int, ...] = (0,),
|
|
) -> subprocess.CompletedProcess:
|
|
"""
|
|
Run a subprocess command and either stream output or capture it.
|
|
Raise SystemExit on a return code outside `ok_returncodes`.
|
|
"""
|
|
if capture_output:
|
|
result = subprocess.run(
|
|
cmd, text=True, capture_output=True, env=env, check=False
|
|
)
|
|
else:
|
|
result = subprocess.run(cmd, text=True, env=env, check=False)
|
|
|
|
if result.returncode not in ok_returncodes:
|
|
msg = f"Command failed: {' '.join(str(c) for c in cmd)}\n"
|
|
if capture_output:
|
|
msg += f"STDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}\n"
|
|
raise SystemExit(msg)
|
|
|
|
return result
|