- debian/control, changelog, conffiles — package metadata - debian/postinst — creates irc-bot system user, installs Python venv, symlinks runtime dirs, enables systemd services - debian/prerm/postrm — clean stop/uninstall with purge support - debian/systemd/ — hardened systemd units for bot and portal - build_deb.sh — assembles and builds the .deb via dpkg-deb - Path resolver in irc_client.py, memory.py, config_manager.py, portal/app.py: uses /etc/irc-bot + /var/lib/irc-bot when installed as .deb, relative paths otherwise (Docker/venv unchanged) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
74 lines
2.2 KiB
Python
74 lines
2.2 KiB
Python
import json
|
|
import logging
|
|
import os
|
|
import signal
|
|
import socket
|
|
import sys
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
if os.path.isdir("/etc/irc-bot"):
|
|
CONFIG_PATH = "/etc/irc-bot/config.json"
|
|
PID_PATH = "/var/lib/irc-bot/ircbot.pid"
|
|
SOCK_PATH = "/var/lib/irc-bot/ircbot.sock"
|
|
else:
|
|
CONFIG_PATH = "config/config.json"
|
|
PID_PATH = "data/ircbot.pid"
|
|
SOCK_PATH = "data/ircbot.sock"
|
|
|
|
|
|
def load_config() -> dict:
|
|
if not os.path.exists(CONFIG_PATH):
|
|
return {}
|
|
with open(CONFIG_PATH, "r") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def save_config(cfg: dict) -> None:
|
|
os.makedirs("config", exist_ok=True)
|
|
with open(CONFIG_PATH, "w") as f:
|
|
json.dump(cfg, f, indent=2)
|
|
logger.info("[CONFIG] Saved config.json")
|
|
|
|
|
|
def signal_bot_reload() -> bool:
|
|
"""Signal bot to reload config. Returns True on success."""
|
|
# Try Unix socket first (Docker mode)
|
|
if sys.platform != "win32" and os.path.exists(SOCK_PATH):
|
|
try:
|
|
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
s.connect(SOCK_PATH)
|
|
s.sendall(b"RELOAD")
|
|
s.close()
|
|
logger.info("[CONFIG] Sent RELOAD via Unix socket")
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"[CONFIG] Socket reload failed: {e}")
|
|
|
|
# Fall back to SIGHUP
|
|
if sys.platform != "win32" and os.path.exists(PID_PATH):
|
|
try:
|
|
with open(PID_PATH) as f:
|
|
pid = int(f.read().strip())
|
|
os.kill(pid, signal.SIGHUP)
|
|
logger.info(f"[CONFIG] Sent SIGHUP to PID {pid}")
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"[CONFIG] SIGHUP failed: {e}")
|
|
|
|
logger.warning("[CONFIG] Could not signal bot (no socket or PID available)")
|
|
return False
|
|
|
|
|
|
def signal_bot_reconnect() -> bool:
|
|
if sys.platform != "win32" and os.path.exists(SOCK_PATH):
|
|
try:
|
|
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
s.connect(SOCK_PATH)
|
|
s.sendall(b"RECONNECT")
|
|
s.close()
|
|
return True
|
|
except Exception as e:
|
|
logger.warning(f"[CONFIG] Reconnect signal failed: {e}")
|
|
return False
|