# services/crypto/monerod/status-proxy-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: monerod-status-proxy namespace: crypto data: status_proxy.py: | from __future__ import annotations import json import os import re from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from urllib import error, request LOG_FILE = os.environ.get("MONEROD_LOG_FILE", "/tmp/monerod.log") LISTEN_PORT = int(os.environ.get("MONEROD_STATUS_PORT", "18084")) RPC_TIMEOUT_SEC = float(os.environ.get("MONEROD_STATUS_RPC_TIMEOUT_SEC", "0.5")) RPC_URL = os.environ.get("MONEROD_RPC_URL", "http://127.0.0.1:18081/get_info") SYNC_RE = re.compile(r"Synced\s+(\d+)/(\d+).*?(\d+)\s+left") CANDIDATE_RE = re.compile( r"candidate:\s+(\d+)\s+->\s+(\d+).*?node is\s+(\d+)\s+blocks", re.IGNORECASE, ) def _tail_log(path: str, limit: int = 262_144) -> str: try: size = os.path.getsize(path) with open(path, "rb") as handle: handle.seek(max(0, size - limit)) return handle.read().decode("utf-8", "ignore") except OSError: return "" def _sync_from_logs() -> tuple[int, int]: for line in reversed(_tail_log(LOG_FILE).splitlines()): match = SYNC_RE.search(line) or CANDIDATE_RE.search(line) if match: return int(match.group(1)), int(match.group(2)) return 0, 0 def _rpc_get_info() -> dict: with request.urlopen(RPC_URL, timeout=RPC_TIMEOUT_SEC) as response: payload = json.loads(response.read().decode("utf-8")) if isinstance(payload, dict): payload.setdefault("rpc_status", "ok") return payload return {"status": "BAD_UPSTREAM", "rpc_status": "bad_upstream"} def _busy_status() -> dict: height, target_height = _sync_from_logs() return { "nettype": "mainnet", "status": "SYNCING_RPC_BUSY", "height": height, "target_height": target_height, "synchronized": False, "rpc_status": "busy", } class Handler(BaseHTTPRequestHandler): def _json(self, status: int, payload: dict) -> None: body = json.dumps(payload).encode("utf-8") self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def do_GET(self) -> None: # noqa: N802 if self.path == "/healthz": self._json(200, {"status": "ok"}) return if self.path.split("?", 1)[0] != "/get_info": self._json(404, {"status": "NOT_FOUND"}) return try: self._json(200, _rpc_get_info()) except (OSError, TimeoutError, ValueError, error.URLError): self._json(200, _busy_status()) def log_message(self, fmt: str, *args) -> None: return if __name__ == "__main__": ThreadingHTTPServer(("", LISTEN_PORT), Handler).serve_forever()