#!/usr/bin/env bash set -euo pipefail : "${STAGING_AUDIT_MINION:?STAGING_AUDIT_MINION is required}" : "${STAGING_AUDIT_PROJECT_DIR:?STAGING_AUDIT_PROJECT_DIR is required}" : "${STAGING_AUDIT_MANAGE:?STAGING_AUDIT_MANAGE is required}" AUDIT_TIMEOUT_SECONDS=${AUDIT_TIMEOUT_SECONDS:-300} ARTIFACT_DIR=${ARTIFACT_DIR:-artifacts} OUTPUT_JSON=${OUTPUT_JSON:-${ARTIFACT_DIR}/multilingual-audit.json} mkdir -p "${ARTIFACT_DIR}" TMP_FILE=$(mktemp) trap 'rm -f "$TMP_FILE"' EXIT REMOTE_CMD="cd '${STAGING_AUDIT_PROJECT_DIR}' && '${STAGING_AUDIT_MANAGE}' audit_locales --format=json" set +e STAGING_AUDIT_MINION="$STAGING_AUDIT_MINION" REMOTE_CMD="$REMOTE_CMD" AUDIT_TIMEOUT_SECONDS="$AUDIT_TIMEOUT_SECONDS" python3 - <<'PY2' > "$TMP_FILE" import json import os import subprocess import sys minion = os.environ["STAGING_AUDIT_MINION"] remote_cmd = os.environ["REMOTE_CMD"] timeout_seconds = int(os.environ["AUDIT_TIMEOUT_SECONDS"]) cmd = [ "sudo", "-n", "-u", "mandel", "-g", "www-data", "/usr/bin/salt", "--out=json", minion, "cmd.run_all", remote_cmd, "python_shell=True", ] try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout_seconds, check=False, ) except subprocess.TimeoutExpired: print(json.dumps({ "run_id": None, "total_urls_checked": 0, "issues_found": 0, "summary": {}, "issues": {}, "error": f"Salt multilingual audit timed out after {timeout_seconds} seconds", }, indent=2)) sys.exit(2) if result.returncode != 0: print(json.dumps({ "run_id": None, "total_urls_checked": 0, "issues_found": 0, "summary": {}, "issues": {}, "error": f"Salt audit transport failed with exit status {result.returncode}: {(result.stderr or result.stdout).strip()}", }, indent=2)) sys.exit(2) try: payload = json.loads(result.stdout) if not isinstance(payload, dict) or minion not in payload: raise ValueError("Missing minion payload") minion_payload = payload[minion] if not isinstance(minion_payload, dict): raise ValueError("Unexpected minion payload type") retcode = int(minion_payload.get("retcode", 1)) stdout = minion_payload.get("stdout", "") stderr = minion_payload.get("stderr", "") if retcode != 0: print(json.dumps({ "run_id": None, "total_urls_checked": 0, "issues_found": 0, "summary": {}, "issues": {}, "error": f"Remote multilingual audit failed with exit status {retcode}: {(stderr or stdout).strip()}", }, indent=2)) sys.exit(2) audit = json.loads(stdout) except Exception as exc: print(json.dumps({ "run_id": None, "total_urls_checked": 0, "issues_found": 0, "summary": {}, "issues": {}, "error": f"Unable to parse salt audit response: {exc}", }, indent=2)) sys.exit(2) print(json.dumps(audit, indent=2, sort_keys=True)) PY2 status=$? set -e cp "$TMP_FILE" "$OUTPUT_JSON" cat "$OUTPUT_JSON" exit $status