Commit the accumulated infrastructure work that was living only in the working tree: monitoring stack, emergency access/bot, gyro allocator, grimmory, adguard, backup audit and the OpenCode agent definitions. Also ignore Python bytecode, local archives and Nix/direnv artifacts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
#!/usr/bin/python3
|
|
import os
|
|
import socket
|
|
import sys
|
|
import urllib.parse
|
|
import urllib.request
|
|
|
|
|
|
def main() -> int:
|
|
token = os.environ.get("TELEGRAM_BOT_TOKEN", "").strip()
|
|
user_id = os.environ.get("TELEGRAM_USER_ID", "").strip()
|
|
if not token or not user_id:
|
|
print("Gyro failure notification skipped: Telegram credentials are absent")
|
|
return 1
|
|
|
|
proxy = os.environ.get("TELEGRAM_PROXY", "").strip()
|
|
handlers = [urllib.request.ProxyHandler({"http": proxy, "https": proxy})] if proxy else []
|
|
opener = urllib.request.build_opener(*handlers)
|
|
failed_unit = sys.argv[1] if len(sys.argv) > 1 else "gyro.service"
|
|
message = f"Gyro job failed on {socket.gethostname()}: {failed_unit}. Check journalctl -u gyro.service."
|
|
body = urllib.parse.urlencode({"chat_id": user_id, "text": message}).encode()
|
|
request = urllib.request.Request(
|
|
f"https://api.telegram.org/bot{token}/sendMessage",
|
|
data=body,
|
|
method="POST",
|
|
)
|
|
|
|
try:
|
|
with opener.open(request, timeout=20) as response:
|
|
return 0 if response.status == 200 else 1
|
|
except Exception as exc:
|
|
print(f"Gyro failure notification failed: {type(exc).__name__}")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|