diff --git a/runtime/history/GITEA-READER-LAN-BIND-290.json b/runtime/history/GITEA-READER-LAN-BIND-290.json new file mode 100644 index 0000000..7df900a --- /dev/null +++ b/runtime/history/GITEA-READER-LAN-BIND-290.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "channel": "homelab-runtime", + "command_id": "GITEA-READER-LAN-BIND-290", + "status": "FAIL", + "rc": 7, + "host": "pve01", + "mode": "change", + "component": "cluster-audit", + "started_at_utc": "2026-07-22T21:26:06Z", + "finished_at_utc": "2026-07-22T21:26:06Z", + "reference_register_checked": true, + "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", + "error_register_checked": true, + "error_register_sha256": "08b3a769b8e38eaa1acec915352fb328180d70caa7ff6cd9d1ec0da426262752", + "command_sha256": "e5009582d1686f1b95e6deb9aa32a84bda61a54b2d8f91ac6c99615de642c579", + "duplicate_failed_command_blocked": false, + "block_reason": null, + "execution_started": true, + "changes_made": true, + "sanitized": true, + "secrets_included": false, + "private_addresses_included": false, + "raw_evidence_retained_locally": true, + "raw_evidence_sha256": "66f054e4ae3cc3399d1b9ad7a843066a3b1fc6e36ce812372418c4b8a6f2fa82", + "sanitized_output_sha256": "ab940a12ce1fd656cdc00b6b10f684a877690ae7f5d2ec76a42690cc38c91c81", + "output_truncated_in_json": false, + "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", + "output": "DETAIL=SOURCE_SHA256=86019c63091dbe7ce16beab24012ed779e496a7010798502cde37921b6551f62\ncurl: (7) Failed to connect to [PRIVATE_IP] port 18788 after 0 ms: Could not connect to server\nDETAIL=ROLLBACK=APPLIED\n" +} diff --git a/runtime/history/GITEA-READER-LAN-BIND-290.txt b/runtime/history/GITEA-READER-LAN-BIND-290.txt new file mode 100644 index 0000000..d8a7d94 --- /dev/null +++ b/runtime/history/GITEA-READER-LAN-BIND-290.txt @@ -0,0 +1,27 @@ +CHAT_OUTPUT_BEGIN +COMMAND_ID=GITEA-READER-LAN-BIND-290 +STATUS=FAIL +RC=7 +HOST=pve01 +MODE=change +COMPONENT=cluster-audit +REFERENCE_REGISTER_CHECK=OK +REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e +ERROR_REGISTER_CHECK=OK +ERROR_REGISTER_SHA256=08b3a769b8e38eaa1acec915352fb328180d70caa7ff6cd9d1ec0da426262752 +COMMAND_SHA256=e5009582d1686f1b95e6deb9aa32a84bda61a54b2d8f91ac6c99615de642c579 +DUPLICATE_FAILED_COMMAND_BLOCKED=false +EXECUTION_STARTED=true +CHANGES_MADE=true +SANITIZED=yes +SECRETS_INCLUDED=no +PRIVATE_ADDRESSES_INCLUDED=no +RAW_EVIDENCE_SHA256=66f054e4ae3cc3399d1b9ad7a843066a3b1fc6e36ce812372418c4b8a6f2fa82 +SANITIZED_OUTPUT_SHA256=ab940a12ce1fd656cdc00b6b10f684a877690ae7f5d2ec76a42690cc38c91c81 +OUTPUT_BEGIN +DETAIL=SOURCE_SHA256=86019c63091dbe7ce16beab24012ed779e496a7010798502cde37921b6551f62 +curl: (7) Failed to connect to [PRIVATE_IP] port 18788 after 0 ms: Could not connect to server +DETAIL=ROLLBACK=APPLIED + +OUTPUT_END +CHAT_OUTPUT_END diff --git a/runtime/latest.json b/runtime/latest.json index ea6f3c8..7df900a 100644 --- a/runtime/latest.json +++ b/runtime/latest.json @@ -1,30 +1,30 @@ { "schema_version": 1, "channel": "homelab-runtime", - "command_id": "GITEA-READER-ROUTES-AUDIT-289", - "status": "OK", - "rc": 0, + "command_id": "GITEA-READER-LAN-BIND-290", + "status": "FAIL", + "rc": 7, "host": "pve01", - "mode": "read-only", + "mode": "change", "component": "cluster-audit", - "started_at_utc": "2026-07-22T21:23:40Z", - "finished_at_utc": "2026-07-22T21:23:40Z", + "started_at_utc": "2026-07-22T21:26:06Z", + "finished_at_utc": "2026-07-22T21:26:06Z", "reference_register_checked": true, "reference_sha256": "5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e", "error_register_checked": true, "error_register_sha256": "08b3a769b8e38eaa1acec915352fb328180d70caa7ff6cd9d1ec0da426262752", - "command_sha256": "ca1499ccd79985134e654f663bd829da73f07f8aa2af0a227387a97e6c32c66d", + "command_sha256": "e5009582d1686f1b95e6deb9aa32a84bda61a54b2d8f91ac6c99615de642c579", "duplicate_failed_command_blocked": false, "block_reason": null, "execution_started": true, - "changes_made": false, + "changes_made": true, "sanitized": true, "secrets_included": false, "private_addresses_included": false, "raw_evidence_retained_locally": true, - "raw_evidence_sha256": "8077c2ba090c3c446ffa120fd830682af6b005d086e4263b67ad67eb043d3a9b", - "sanitized_output_sha256": "8077c2ba090c3c446ffa120fd830682af6b005d086e4263b67ad67eb043d3a9b", + "raw_evidence_sha256": "66f054e4ae3cc3399d1b9ad7a843066a3b1fc6e36ce812372418c4b8a6f2fa82", + "sanitized_output_sha256": "ab940a12ce1fd656cdc00b6b10f684a877690ae7f5d2ec76a42690cc38c91c81", "output_truncated_in_json": false, "full_sanitized_output_url": "https://git.gram1.ru/.well-known/homelab-runtime/latest.txt", - "output": "PREVIOUS_COMMAND_ID=GITEA-READER-BIND-AUDIT-288\nDETAIL= 1\t#!/usr/bin/python3\nDETAIL= 2\timport hashlib\nDETAIL= 3\timport http.server\nDETAIL= 4\timport json\nDETAIL= 5\timport os\nDETAIL= 6\timport pathlib\nDETAIL= 7\timport re\nDETAIL= 8\timport sys\nDETAIL= 9\t\nDETAIL= 10\tROOT=pathlib.Path(\"/var/lib/homelab-reader-v3\")\nDETAIL= 11\tMANIFEST=ROOT/\"manifest.json\"\nDETAIL= 12\tRESULTS=ROOT/\"results\"\nDETAIL= 13\tCAPABILITY=os.environ[\"HOMELAB_READER_CAPABILITY\"]\nDETAIL= 14\tPORT=int(os.environ.get(\"HOMELAB_READER_PORT\",\"18788\"))\nDETAIL= 15\tRESULT_RE=re.compile(r\"^[A-Za-z0-9][A-Za-z0-9._-]{0,127}-[0-9a-f]{64}\\.txt$\")\nDETAIL= 16\t\nDETAIL= 17\tclass Handler(http.server.BaseHTTPRequestHandler):\nDETAIL= 18\t server_version=\"HomelabReader/3\"\nDETAIL= 19\t\nDETAIL= 20\t def log_message(self,fmt,*args):\nDETAIL= 21\t sys.stderr.write(\"%s - %s\\n\"%(self.address_string(),fmt%args))\nDETAIL= 22\t\nDETAIL= 23\t def reply(self,status,content_type,payload,etag=\"\",include_body=True):\nDETAIL= 24\t self.send_response(status)\nDETAIL= 25\t self.send_header(\"Content-Type\",content_type)\nDETAIL= 26\t self.send_header(\"Content-Length\",str(len(payload)))\nDETAIL= 27\t self.send_header(\"Cache-Control\",\"no-store, no-cache, must-revalidate, max-age=0\")\nDETAIL= 28\t self.send_header(\"Surrogate-Control\",\"no-store\")\nDETAIL= 29\t self.send_header(\"Pragma\",\"no-cache\")\nDETAIL= 30\t self.send_header(\"Expires\",\"0\")\nDETAIL= 31\t self.send_header(\"X-Robots-Tag\",\"noindex, nofollow, noarchive\")\nDETAIL= 32\t if etag:\nDETAIL= 33\t self.send_header(\"ETag\",chr(34)+etag+chr(34))\nDETAIL= 34\t self.send_header(\"X-Homelab-Generation\",etag)\nDETAIL= 35\t self.end_headers()\nDETAIL= 36\t if include_body:\nDETAIL= 37\t self.wfile.write(payload)\nDETAIL= 38\t\nDETAIL= 39\t def do_HEAD(self):\nDETAIL= 40\t self.handle_reader(False)\nDETAIL= 41\t\nDETAIL= 42\t def do_GET(self):\nDETAIL= 43\t self.handle_reader(True)\nDETAIL= 44\t\nDETAIL= 45\t def handle_reader(self,include_body):\nDETAIL= 46\t request_path=self.path.split(\"?\",1)[0]\nDETAIL= 47\t prefix=\"/\"+CAPABILITY+\"/\"\nDETAIL= 48\t if not request_path.startswith(prefix):\nDETAIL= 49\t self.reply(404,\"text/plain; charset=utf-8\",b\"not found\\n\",include_body=include_body)\nDETAIL= 50\t return\nDETAIL= 51\t\nDETAIL= 52\t relative=request_path[len(prefix):]\nDETAIL= 53\t\nDETAIL= 54\t if relative==\"health\":\nDETAIL= 55\t self.reply(200,\"application/json; charset=utf-8\",b\"{\\\"status\\\":\\\"ok\\\",\\\"version\\\":3}\\n\",\"health-v3\",include_body)\nDETAIL= 56\t return\nDETAIL= 57\t\nDETAIL= 58\t if relative==\"feed\":\nDETAIL= 59\t try:\nDETAIL= 60\t payload=MANIFEST.read_bytes()\nDETAIL= 61\t document=json.loads(payload.decode(\"utf-8\"))\nDETAIL= 62\t generation=str(document.get(\"generation\",\"0\"))\nDETAIL= 63\t self.reply(200,\"application/json; charset=utf-8\",payload,generation,include_body)\nDETAIL= 64\t except Exception:\nDETAIL= 65\t self.reply(500,\"text/plain; charset=utf-8\",b\"reader error\\n\",include_body=include_body)\nDETAIL= 66\t return\nDETAIL= 67\t\nDETAIL= 68\t if relative.startswith(\"results/\"):\nDETAIL= 69\t name=relative[len(\"results/\"):]\nDETAIL= 70\t target=RESULTS/name\nDETAIL= 71\t if not RESULT_RE.fullmatch(name) or not target.is_file():\nDETAIL= 72\t self.reply(404,\"text/plain; charset=utf-8\",b\"not found\\n\",include_body=include_body)\nDETAIL= 73\t return\nDETAIL= 74\t try:\nDETAIL= 75\t payload=target.read_bytes()\nDETAIL= 76\t digest=name.rsplit(\"-\",1)[1][:-4]\nDETAIL= 77\t if hashlib.sha256(payload).hexdigest()!=digest:\nDETAIL= 78\t self.reply(500,\"text/plain; charset=utf-8\",b\"integrity error\\n\",include_body=include_body)\nDETAIL= 79\t return\nDETAIL= 80\t self.reply(200,\"text/plain; charset=utf-8\",payload,digest,include_body)\nDETAIL= 81\t except Exception:\nDETAIL= 82\t self.reply(500,\"text/plain; charset=utf-8\",b\"reader error\\n\",include_body=include_body)\nDETAIL= 83\t return\nDETAIL= 84\t\nDETAIL= 85\t self.reply(404,\"text/plain; charset=utf-8\",b\"not found\\n\",include_body=include_body)\nDETAIL= 86\t\nDETAIL= 87\tclass Server(http.server.ThreadingHTTPServer):\nDETAIL= 88\t allow_reuse_address=True\nDETAIL= 89\t\nDETAIL= 90\tServer((\"127.0.0.1\",PORT),Handler).serve_forever()\nCHANGES_MADE=NO\n" + "output": "DETAIL=SOURCE_SHA256=86019c63091dbe7ce16beab24012ed779e496a7010798502cde37921b6551f62\ncurl: (7) Failed to connect to [PRIVATE_IP] port 18788 after 0 ms: Could not connect to server\nDETAIL=ROLLBACK=APPLIED\n" } diff --git a/runtime/latest.txt b/runtime/latest.txt index ef33bde..d8a7d94 100644 --- a/runtime/latest.txt +++ b/runtime/latest.txt @@ -1,116 +1,27 @@ CHAT_OUTPUT_BEGIN -COMMAND_ID=GITEA-READER-ROUTES-AUDIT-289 -STATUS=OK -RC=0 +COMMAND_ID=GITEA-READER-LAN-BIND-290 +STATUS=FAIL +RC=7 HOST=pve01 -MODE=read-only +MODE=change COMPONENT=cluster-audit REFERENCE_REGISTER_CHECK=OK REFERENCE_SHA256=5763f2f8edc75fcf6f3951f8c95896d1cc112ceccb6cf5b64a383f540a4deb8e ERROR_REGISTER_CHECK=OK ERROR_REGISTER_SHA256=08b3a769b8e38eaa1acec915352fb328180d70caa7ff6cd9d1ec0da426262752 -COMMAND_SHA256=ca1499ccd79985134e654f663bd829da73f07f8aa2af0a227387a97e6c32c66d +COMMAND_SHA256=e5009582d1686f1b95e6deb9aa32a84bda61a54b2d8f91ac6c99615de642c579 DUPLICATE_FAILED_COMMAND_BLOCKED=false EXECUTION_STARTED=true -CHANGES_MADE=false +CHANGES_MADE=true SANITIZED=yes SECRETS_INCLUDED=no PRIVATE_ADDRESSES_INCLUDED=no -RAW_EVIDENCE_SHA256=8077c2ba090c3c446ffa120fd830682af6b005d086e4263b67ad67eb043d3a9b -SANITIZED_OUTPUT_SHA256=8077c2ba090c3c446ffa120fd830682af6b005d086e4263b67ad67eb043d3a9b +RAW_EVIDENCE_SHA256=66f054e4ae3cc3399d1b9ad7a843066a3b1fc6e36ce812372418c4b8a6f2fa82 +SANITIZED_OUTPUT_SHA256=ab940a12ce1fd656cdc00b6b10f684a877690ae7f5d2ec76a42690cc38c91c81 OUTPUT_BEGIN -PREVIOUS_COMMAND_ID=GITEA-READER-BIND-AUDIT-288 -DETAIL= 1 #!/usr/bin/python3 -DETAIL= 2 import hashlib -DETAIL= 3 import http.server -DETAIL= 4 import json -DETAIL= 5 import os -DETAIL= 6 import pathlib -DETAIL= 7 import re -DETAIL= 8 import sys -DETAIL= 9 -DETAIL= 10 ROOT=pathlib.Path("/var/lib/homelab-reader-v3") -DETAIL= 11 MANIFEST=ROOT/"manifest.json" -DETAIL= 12 RESULTS=ROOT/"results" -DETAIL= 13 CAPABILITY=os.environ["HOMELAB_READER_CAPABILITY"] -DETAIL= 14 PORT=int(os.environ.get("HOMELAB_READER_PORT","18788")) -DETAIL= 15 RESULT_RE=re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,127}-[0-9a-f]{64}\.txt$") -DETAIL= 16 -DETAIL= 17 class Handler(http.server.BaseHTTPRequestHandler): -DETAIL= 18 server_version="HomelabReader/3" -DETAIL= 19 -DETAIL= 20 def log_message(self,fmt,*args): -DETAIL= 21 sys.stderr.write("%s - %s\n"%(self.address_string(),fmt%args)) -DETAIL= 22 -DETAIL= 23 def reply(self,status,content_type,payload,etag="",include_body=True): -DETAIL= 24 self.send_response(status) -DETAIL= 25 self.send_header("Content-Type",content_type) -DETAIL= 26 self.send_header("Content-Length",str(len(payload))) -DETAIL= 27 self.send_header("Cache-Control","no-store, no-cache, must-revalidate, max-age=0") -DETAIL= 28 self.send_header("Surrogate-Control","no-store") -DETAIL= 29 self.send_header("Pragma","no-cache") -DETAIL= 30 self.send_header("Expires","0") -DETAIL= 31 self.send_header("X-Robots-Tag","noindex, nofollow, noarchive") -DETAIL= 32 if etag: -DETAIL= 33 self.send_header("ETag",chr(34)+etag+chr(34)) -DETAIL= 34 self.send_header("X-Homelab-Generation",etag) -DETAIL= 35 self.end_headers() -DETAIL= 36 if include_body: -DETAIL= 37 self.wfile.write(payload) -DETAIL= 38 -DETAIL= 39 def do_HEAD(self): -DETAIL= 40 self.handle_reader(False) -DETAIL= 41 -DETAIL= 42 def do_GET(self): -DETAIL= 43 self.handle_reader(True) -DETAIL= 44 -DETAIL= 45 def handle_reader(self,include_body): -DETAIL= 46 request_path=self.path.split("?",1)[0] -DETAIL= 47 prefix="/"+CAPABILITY+"/" -DETAIL= 48 if not request_path.startswith(prefix): -DETAIL= 49 self.reply(404,"text/plain; charset=utf-8",b"not found\n",include_body=include_body) -DETAIL= 50 return -DETAIL= 51 -DETAIL= 52 relative=request_path[len(prefix):] -DETAIL= 53 -DETAIL= 54 if relative=="health": -DETAIL= 55 self.reply(200,"application/json; charset=utf-8",b"{\"status\":\"ok\",\"version\":3}\n","health-v3",include_body) -DETAIL= 56 return -DETAIL= 57 -DETAIL= 58 if relative=="feed": -DETAIL= 59 try: -DETAIL= 60 payload=MANIFEST.read_bytes() -DETAIL= 61 document=json.loads(payload.decode("utf-8")) -DETAIL= 62 generation=str(document.get("generation","0")) -DETAIL= 63 self.reply(200,"application/json; charset=utf-8",payload,generation,include_body) -DETAIL= 64 except Exception: -DETAIL= 65 self.reply(500,"text/plain; charset=utf-8",b"reader error\n",include_body=include_body) -DETAIL= 66 return -DETAIL= 67 -DETAIL= 68 if relative.startswith("results/"): -DETAIL= 69 name=relative[len("results/"):] -DETAIL= 70 target=RESULTS/name -DETAIL= 71 if not RESULT_RE.fullmatch(name) or not target.is_file(): -DETAIL= 72 self.reply(404,"text/plain; charset=utf-8",b"not found\n",include_body=include_body) -DETAIL= 73 return -DETAIL= 74 try: -DETAIL= 75 payload=target.read_bytes() -DETAIL= 76 digest=name.rsplit("-",1)[1][:-4] -DETAIL= 77 if hashlib.sha256(payload).hexdigest()!=digest: -DETAIL= 78 self.reply(500,"text/plain; charset=utf-8",b"integrity error\n",include_body=include_body) -DETAIL= 79 return -DETAIL= 80 self.reply(200,"text/plain; charset=utf-8",payload,digest,include_body) -DETAIL= 81 except Exception: -DETAIL= 82 self.reply(500,"text/plain; charset=utf-8",b"reader error\n",include_body=include_body) -DETAIL= 83 return -DETAIL= 84 -DETAIL= 85 self.reply(404,"text/plain; charset=utf-8",b"not found\n",include_body=include_body) -DETAIL= 86 -DETAIL= 87 class Server(http.server.ThreadingHTTPServer): -DETAIL= 88 allow_reuse_address=True -DETAIL= 89 -DETAIL= 90 Server(("127.0.0.1",PORT),Handler).serve_forever() -CHANGES_MADE=NO +DETAIL=SOURCE_SHA256=86019c63091dbe7ce16beab24012ed779e496a7010798502cde37921b6551f62 +curl: (7) Failed to connect to [PRIVATE_IP] port 18788 after 0 ms: Could not connect to server +DETAIL=ROLLBACK=APPLIED OUTPUT_END CHAT_OUTPUT_END