1
0
Files
homelab-public-context/runtime/latest.json
T
2026-09-22 14:10:05 +00:00

39 lines
8.0 KiB
JSON

{
"schema_version": 1,
"channel": "homelab-runtime",
"command_id": "SUPPORT-260922-SPB-ACME-CERTBOT-FAIL-RCA-9124R1",
"status": "OK",
"rc": 0,
"host": "pve01",
"mode": "read-only",
"component": "spb-acme-certbot-fail-rca",
"started_at_utc": "2026-09-22T14:09:59Z",
"finished_at_utc": "2026-09-22T14:10:04Z",
"reference_register_checked": true,
"reference_sha256": "5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66",
"error_register_checked": true,
"error_register_sha256": "3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0",
"command_sha256": "65e45035e738859d7301cc86383acdbc514310a22e8a10f9a86928f593b10521",
"duplicate_failed_command_blocked": false,
"block_reason": null,
"execution_started": true,
"change_declared": false,
"result_contract_valid": true,
"result_contract_status": null,
"result_contract_error": null,
"command_rc": 0,
"changes_made": false,
"rollback_started": false,
"rollback_restored": null,
"mutation_outcome": "NO_MUTATION",
"sanitized": true,
"secrets_included": false,
"private_addresses_included": false,
"raw_evidence_retained_locally": true,
"raw_evidence_sha256": "0d656c5cf4c2e5febffda0117d173fb22f193ad50645d09c55e3eb5d4bbcb85c",
"sanitized_output_sha256": "0d656c5cf4c2e5febffda0117d173fb22f193ad50645d09c55e3eb5d4bbcb85c",
"output_truncated_in_json": false,
"full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt",
"output": "SPB9124_RCA={\"guest\":{\"ok\":true,\"data\":{\"hook\":{\"exists\":true,\"sha256\":\"dcaffc5a248359fa3ed93b7bf8af33ad69985776c4a8e3e7f2016c6168da5aee\",\"sha_matches_9120\":true,\"functions\":[\"out\",\"token\",\"api\",\"zone_id\",\"state_path\",\"auth\",\"cleanup\"],\"safe_to_import_without_main\":false,\"unsafe_top_level_types\":[\"Expr\"],\"selected_string_constants\":[\".json\",\"/dns_records\",\"/dns_records/\",\"/opt/npmplus/secure/gram1_cf_token\",\"/zones/\",\"/zones?\",\"GRAM1_CF_ZONE_LOOKUP ok=no http=\",\"GRAM1_CF_ZONE_LOOKUP ok=yes id_prefix=\",\"_acme-challenge.\",\"gram1.ru\",\"https://api.cloudflare.com/client/v4\",\"www.gram1.ru\",\"zone_id\"],\"function_sources\":{\"token\":[\"def token(): return TOKEN_PATH.read_text(encoding=\\\"utf-8\\\").strip()\"],\"api\":[\"def api(method, path, payload=None):\",\" data = json.dumps(payload).encode(\\\"utf-8\\\") if payload is not None else None\",\" req = urllib.request.Request(\\\"https://api.cloudflare.com/client/v4\\\" + path, data=data, headers={\\\"Authorization\\\": \\\"Bearer[REDACTED_EXPR]\\\" + token(), \\\"Content-Type\\\": \\\"application/json\\\"}, method=method)\",\" try:\",\" with urllib.request.urlopen(req, timeout=25) as r: return r.status, json.loads(r.read().decode(\\\"utf-8\\\", \\\"replace\\\"))\",\" except urllib.error.HTTPError as e:\",\" try: body = json.loads(e.read().decode(\\\"utf-8\\\", \\\"replace\\\"))\",\" except Exception: body = {\\\"success\\\": False, \\\"errors\\\": [{\\\"message\\\": \\\"http_error_non_json\\\"}]}\",\" return e.code, body\"],\"zone_id\":[\"def zone_id():\",\" status, data = api(\\\"GET\\\", \\\"/zones?\\\" + urllib.parse.urlencode({\\\"name\\\": ZONE}))\",\" if not data.get(\\\"success\\\") or not data.get(\\\"result\\\"):\",\" out(f\\\"GRAM1_CF_ZONE_LOOKUP ok=no http={status}\\\"); return None\",\" zid = data[\\\"result\\\"][0][\\\"id\\\"]; out(f\\\"GRAM1_CF_ZONE_LOOKUP ok=yes id_prefix={zid[:8]}\\\"); return zid\"],\"auth\":[\"def auth():\",\" domain = os.environ.get(\\\"CERTBOT_DOMAIN\\\", \\\"\\\"); validation = os.environ.get(\\\"CERTBOT_VALIDATION\\\", \\\"\\\")\",\" if domain not in (\\\"gram1.ru\\\", \\\"www.gram1.ru\\\") or not validation:\",\" out(f\\\"GRAM1_CF_AUTH domain={domain} status=review reason=bad_env\\\"); return 2\",\" zid = zone_id()\",\" if not zid: return 2\",\" name = \\\"_acme-challenge.\\\" + domain\",\" status, data = api(\\\"POST\\\", f\\\"/zones/{zid}/dns_records\\\", {\\\"type\\\": \\\"TXT\\\", \\\"name\\\": name, \\\"content\\\": validation, \\\"ttl\\\": 120})\",\" if not data.get(\\\"success\\\"):\",\" errs = data.get(\\\"errors\\\") or []; msg = str(errs[0].get(\\\"message\\\", \\\"\\\"))[:80].replace(\\\"\\\\n\\\", \\\" \\\") if errs else \\\"\\\"\",\" out(f\\\"GRAM1_CF_AUTH domain={domain} status=review http={status} error={msg}\\\"); return 2\",\" rec = data[\\\"result\\\"][\\\"id\\\"]; state_path(domain, validation).write_text(json.dumps({\\\"zone_id\\\": zid, \\\"record_id\\\": rec}), encoding=\\\"utf-8\\\")\",\" out(f\\\"GRAM1_CF_AUTH domain={domain} status=ok record_id_prefix={rec[:8]}\\\"); time.sleep(45); return 0\"],\"cleanup\":[\"def cleanup():\",\" domain = os.environ.get(\\\"CERTBOT_DOMAIN\\\", \\\"\\\"); validation = os.environ.get(\\\"CERTBOT_VALIDATION\\\", \\\"\\\")\",\" sp = state_path(domain, validation)\",\" if sp.exists():\",\" try:\",\" data = json.loads(sp.read_text(encoding=\\\"utf-8\\\"))\",\" status, resp = api(\\\"DELETE\\\", f\\\"/zones/{data['zone_id']}/dns_records/{data['record_id']}\\\")\",\" out(f\\\"GRAM1_CF_CLEANUP domain={domain} status={'ok' if resp.get('success') else 'review'} http={status}\\\"); sp.unlink(missing_ok=True)\",\" except Exception as e: out(f\\\"GRAM1_CF_CLEANUP domain={domain} status=review error={type(e).__name__}\\\")\",\" else: out(f\\\"GRAM1_CF_CLEANUP domain={domain} status=skip reason=no_state\\\")\",\" return 0\"]}},\"cloudflare_readonly\":{},\"certbot\":{\"data_mount_found\":true,\"data_mount_hash\":\"ec0ac67820f88633\",\"config_exists\":true,\"config_mode\":\"0o700\",\"account_json_count\":6,\"renewal_count\":13,\"renewal_basenames\":[\"hbarhub.ru.conf\",\"newfi-staging-gram1-ru.conf\",\"newfilya.ru.conf\",\"npm-17.conf\",\"npm-21.conf\",\"npm-26.conf\",\"npm-27.conf\",\"npm-29.conf\",\"npm-30.conf\",\"npm-31.conf\",\"npm-32.conf\",\"npm-35.conf\",\"npm-38.conf\"],\"certificates_rc\":0,\"certificates_diag\":[\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.\",\"The following renewal configurations were invalid:\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\",\" [PATH]\"],\"certificates_stderr_sha\":\"d744a29aaabe2413\",\"show_account_rc\":1,\"show_account_diag\":[\"An unexpected error occurred:\",\"ValueError: Requesting acme-v02.api.letsencrypt.org/directory: No route to host\"],\"gitread_live_exists\":false,\"gitread_renewal_exists\":false,\"new_vhost_files_exist\":[]},\"locks\":{\"present\":[]},\"processes\":{\"certbot_related\":[]}}}}\nTASK_COMPLETE=true\nTASK_RESULT=PASS_SPB_ACME_CERTBOT_FAIL_RCA\nDECISION=READ_EXACT_9124_THEN_CORRECT_ACME_EXECUTION_PATH\n"
}