DeaD_EyE

systemd-socket-test (AI + Human)

Oct 10th, 2026
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.34 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import asyncio
  3. import os
  4. import sys
  5. import socket
  6. import subprocess
  7. from pathlib import Path
  8. from textwrap import dedent
  9.  
  10. # =====================================================================
  11. # SYSTEMD TEMPLATE GENERATION FUNCTIONS (Modern Python Strings)
  12. # =====================================================================
  13.  
  14. SERVICE_UNIT = """
  15. [Unit]
  16. Description=Resilient Async Python Service (FD-Store)
  17. Requires={socket_name}
  18. After=network.target
  19.  
  20. [Service]
  21. Type=simple
  22. ExecStart={exec_path}
  23. Environment=PYTHONUNBUFFERED=1
  24.  
  25. # FD-Store and Recovery configurations
  26. FileDescriptorStoreMax=100
  27. Restart=on-failure
  28. RestartSec=0.1s
  29.  
  30. [Install]
  31. WantedBy=default.target
  32. """
  33.  
  34. SOCKET_UNIT = """[Unit]
  35. Description=Resilient Async Python Service Socket
  36.  
  37. [Socket]
  38. # Listens on localhost port {port} by default (ideal for user units)
  39. ListenStream={port}
  40.  
  41. [Install]
  42. WantedBy=sockets.target
  43. """
  44.  
  45.  
  46. def create_service_unit(socket_name: str, exec_path: str) -> str:
  47.     """Generates the systemd service configuration using modern multi-line formatting."""
  48.     return SERVICE_UNIT.format(socket_name=socket_name, exec_path=exec_path)
  49.  
  50.  
  51. def create_socket_unit(port: int = 8080) -> str:
  52.     """Generates the systemd socket configuration."""
  53.     return SOCKET_UNIT.format(port=port)
  54.  
  55.  
  56. # =====================================================================
  57. # SYSTEMD COMMAND HELPER
  58. # =====================================================================
  59.  
  60.  
  61. def run_systemctl_user(args: list) -> bool:
  62.     """Helper function to safely run systemctl commands in user space."""
  63.     try:
  64.         cmd = ["systemctl", "--user"] + args
  65.         print(f"Running: {' '.join(cmd)}")
  66.         subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  67.         return True
  68.     except subprocess.CalledProcessError as e:
  69.         print(
  70.             f"[ERROR] systemctl command failed: {e.stderr.decode().strip()}",
  71.             file=sys.stderr,
  72.         )
  73.         return False
  74.  
  75.  
  76. def resilient_accept(conn):
  77.     send_fd_to_systemd(conn.fileno())
  78.  
  79.  
  80. # =====================================================================
  81. # INSTALLATION & DEINSTALLATION LOGIC
  82. # =====================================================================
  83.  
  84.  
  85. def install_systemd_user_units():
  86.     """Automatically installs, enables, and starts the systemd user units."""
  87.  
  88.     # human note:
  89.     # Automatic installs are not good, if everything emerges from a single file.
  90.     # The user doesn't know from where the file came and where it was installed.
  91.     #
  92.  
  93.     print("Initializing systemd user unit installation...")
  94.  
  95.     # 1. Resolve structural paths
  96.     script_path = Path(__file__).resolve()
  97.     home_dir = Path.home()
  98.  
  99.     # Standard systemd user configuration directory
  100.     systemd_user_dir = home_dir / ".config" / "systemd" / "user"
  101.  
  102.     service_file = systemd_user_dir / "async-resilient.service"
  103.     socket_file = systemd_user_dir / "async-resilient.socket"
  104.  
  105.     # 2. Ensure the configuration directories exist
  106.     systemd_user_dir.mkdir(parents=True, exist_ok=True)
  107.  
  108.     # 3. Generate unit contents via template functions
  109.     service_content = create_service_unit(
  110.         socket_name="async-resilient.socket", exec_path=str(script_path)
  111.     )
  112.     socket_content = create_socket_unit(port=8080)
  113.  
  114.     # 4. Write unit configurations to disk
  115.     try:
  116.         service_file.write_text(service_content, encoding="utf-8")
  117.         socket_file.write_text(socket_content, encoding="utf-8")
  118.  
  119.         # Ensure the script itself remains executable
  120.         # holy shit, the ai know octal notation!!!
  121.         script_path.chmod(script_path.stat().st_mode | 0o755)
  122.         print(f"[SUCCESS] Configurations written successfully.")
  123.  
  124.         # 5. Execute systemd lifecycle commands automatically
  125.         print("\nExecuting systemd lifecycle commands...")
  126.         if run_systemctl_user(["daemon-reload"]):
  127.             if run_systemctl_user(["enable", "async-resilient.socket"]):
  128.                 if run_systemctl_user(["start", "async-resilient.socket"]):
  129.                     print("\n[SUCCESS] Server socket is up and running via systemd!")
  130.                     print("You can now connect to port 8080.")
  131.  
  132.     except Exception as e:
  133.         print(f"[ERROR] Failed during systemd initialization: {e}", file=sys.stderr)
  134.         sys.exit(1)
  135.  
  136.  
  137. def stop_and_disable_units():
  138.     """Stops and disables the running systemd socket and service units."""
  139.     print("Stopping and disabling systemd user units...")
  140.  
  141.     # Stop the units first so connections drop cleanly
  142.     run_systemctl_user(["stop", "async-resilient.service"])
  143.     run_systemctl_user(["stop", "async-resilient.socket"])
  144.  
  145.     # Disable them so they don't boot next time systemd starts
  146.     run_systemctl_user(["disable", "async-resilient.socket"])
  147.     run_systemctl_user(["disable", "async-resilient.service"])
  148.  
  149.     # Reload daemon to clear out the state
  150.     run_systemctl_user(["daemon-reload"])
  151.     print("[SUCCESS] Units have been successfully stopped and disabled.")
  152.  
  153.  
  154. # =====================================================================
  155. # CORE NETWORK DAEMON LOGIC
  156. # =====================================================================
  157.  
  158.  
  159. def send_fd_to_systemd(fd: int):
  160.     """Sends an active client File Descriptor to the systemd FD-Store."""
  161.     notify_socket_path = os.environ.get("NOTIFY_SOCKET")
  162.     if not notify_socket_path:
  163.         return
  164.  
  165.     if notify_socket_path.startswith("@"):
  166.         notify_socket_path = "\x00" + notify_socket_path[1:]
  167.  
  168.     try:
  169.         with socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) as sock:
  170.             sock.connect(notify_socket_path)
  171.             sock.sendmsg(
  172.                 [b"FDSTORE=1\n"],
  173.                 [
  174.                     (
  175.                         socket.SOL_SOCKET,
  176.                         socket.SCM_RIGHTS,
  177.                         int.to_bytes(fd, 4, sys.byteorder),
  178.                     )
  179.                 ],
  180.             )
  181.     except Exception as e:
  182.         print(f"FD-Store Sync Error: {e}", file=sys.stderr)
  183.  
  184.  
  185. async def handle_client(
  186.     reader: asyncio.StreamReader, writer: asyncio.StreamWriter, is_recovered=False
  187. ):
  188.     """Asynchronously processes ongoing network clients."""
  189.     try:
  190.         addr = writer.get_extra_info("peername")
  191.         print(f"Processing client from {addr} (Recovered: {is_recovered})")
  192.  
  193.         if is_recovered:
  194.             writer.write(
  195.                 b"Your server crashed, but asyncio recovered your connection flawlessly!\n"
  196.             )
  197.             await writer.drain()
  198.         else:
  199.             resilient_accept(writer.get_extra_info("socket"))
  200.  
  201.         writer.write(b"Processing request... please wait 10 seconds.\n")
  202.         await writer.drain()
  203.         await asyncio.sleep(10)
  204.         writer.write(b"Processing finished successfully.\n")
  205.         await writer.drain()
  206.     except Exception as e:
  207.         print(f"Error handling client: {e}", file=sys.stderr)
  208.     finally:
  209.         writer.close()
  210.         await writer.wait_closed()
  211.  
  212.  
  213. async def run_server():
  214.     """Main daemon loop hooked into the systemd socket lifecycle."""
  215.     listen_fds = os.environ.get("LISTEN_FDS")
  216.     if not listen_fds:
  217.         print(
  218.             "Error: No systemd sockets passed down. Run 'init' or launch via systemd.socket.",
  219.             file=sys.stderr,
  220.         )
  221.         sys.exit(1)
  222.  
  223.     num_fds = int(listen_fds)
  224.     print(f"Received {num_fds} total File Descriptors from systemd.")
  225.  
  226.     # Main Listening Socket is always FD 3
  227.     SYSTEMD_FIRST_FD = 3
  228.     server_sock = socket.fromfd(SYSTEMD_FIRST_FD, socket.AF_INET, socket.SOCK_STREAM)
  229.  
  230.     server = await asyncio.start_server(
  231.         lambda r, w: asyncio.create_task(handle_client(r, w, is_recovered=False)),
  232.         sock=server_sock,
  233.     )
  234.  
  235.     print("Async Server successfully bound and accepting connections...")
  236.  
  237.     # Rehydrate any existing client connections (FD 4+) rescued from a previous crash
  238.     if num_fds > 1:
  239.         print(f"Resurrecting {num_fds - 1} surviving client connections...")
  240.         for fd_num in range(4, 3 + num_fds):
  241.             try:
  242.                 recovered_sock = socket.fromfd(
  243.                     fd_num, socket.AF_INET, socket.SOCK_STREAM
  244.                 )
  245.                 reader, writer = await asyncio.open_connection(sock=recovered_sock)
  246.                 asyncio.create_task(handle_client(reader, writer, is_recovered=True))
  247.             except Exception as e:
  248.                 print(
  249.                     f"Failed to recover existing connection on FD {fd_num}: {e}",
  250.                     file=sys.stderr,
  251.                 )
  252.  
  253.     async with server:
  254.         await server.serve_forever()
  255.  
  256.  
  257. # =====================================================================
  258. # APPLICATION ENTRYPOINT
  259. # =====================================================================
  260.  
  261. if __name__ == "__main__":
  262.     if len(sys.argv) > 1:
  263.         action = sys.argv[1].lower()
  264.         if action == "init":
  265.             install_systemd_user_units()
  266.         elif action == "stop":
  267.             stop_and_disable_units()
  268.         else:
  269.             print(
  270.                 f"Unknown argument: '{sys.argv[1]}'. Use 'init' or 'stop'.",
  271.                 file=sys.stderr,
  272.             )
  273.     else:
  274.         try:
  275.             asyncio.run(run_server())
  276.         except KeyboardInterrupt:
  277.             print("\nServer shutting down gracefully.")
  278.  
Advertisement