#!/usr/bin/env python3
"""
Cortex Agent Node - Daemon Installer
====================================
Configures the Cortex Agent to run automatically as a background daemon
on macOS (launchd) or Linux (systemd).
Usage:
python3 install_service.py
"""
import os
import sys
import platform
import subprocess
def get_python_path():
return sys.executable
def get_agent_main_path():
return os.path.abspath(os.path.join(os.path.dirname(__file__), "agent_node", "main.py"))
def get_working_dir():
return os.path.abspath(os.path.dirname(__file__))
def install_mac_launchd():
print("Installing macOS launchd service...")
plist_content = f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jerxie.cortex.agent</string>
<key>ProgramArguments</key>
<array>
<string>{get_python_path()}</string>
<string>{get_agent_main_path()}</string>
</array>
<key>WorkingDirectory</key>
<string>{get_working_dir()}</string>
<key>KeepAlive</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>{os.path.expanduser("~")}/.cortex/agent.err.log</string>
<key>StandardOutPath</key>
<string>{os.path.expanduser("~")}/.cortex/agent.out.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
</dict>
</plist>
"""
agents_dir = os.path.expanduser("~/Library/LaunchAgents")
os.makedirs(agents_dir, exist_ok=True)
os.makedirs(os.path.expanduser("~/.cortex"), exist_ok=True)
plist_path = os.path.join(agents_dir, "com.jerxie.cortex.agent.plist")
with open(plist_path, "w") as f:
f.write(plist_content)
print(f"Created plist at {plist_path}")
try:
# Unload if exists
subprocess.run(["launchctl", "unload", plist_path], capture_output=True)
# Load new
subprocess.run(["launchctl", "load", plist_path], check=True)
print("✅ macOS Daemon successfully started!")
print(f"Logs: ~/.cortex/agent.out.log and ~/.cortex/agent.err.log")
print("Commands:")
print(f" Stop: launchctl unload {plist_path}")
print(f" Start: launchctl load {plist_path}")
except subprocess.CalledProcessError as e:
print(f"❌ Failed to load launchd service: {e}")
def install_linux_systemd():
print("Installing Linux systemd user service...")
service_content = f"""[Unit]
Description=Cortex Agent Node
After=network.target
[Service]
Type=simple
ExecStart={get_python_path()} {get_agent_main_path()}
WorkingDirectory={get_working_dir()}
Restart=always
RestartSec=5
StandardOutput=append:{os.path.expanduser("~")}/.cortex/agent.out.log
StandardError=append:{os.path.expanduser("~")}/.cortex/agent.err.log
[Install]
WantedBy=default.target
"""
systemd_dir = os.path.expanduser("~/.config/systemd/user")
os.makedirs(systemd_dir, exist_ok=True)
os.makedirs(os.path.expanduser("~/.cortex"), exist_ok=True)
service_path = os.path.join(systemd_dir, "cortex-agent.service")
with open(service_path, "w") as f:
f.write(service_content)
print(f"Created systemd service at {service_path}")
try:
subprocess.run(["systemctl", "--user", "daemon-reload"], check=True)
subprocess.run(["systemctl", "--user", "enable", "cortex-agent"], check=True)
subprocess.run(["systemctl", "--user", "restart", "cortex-agent"], check=True)
# Ensure user services run even when not logged in
subprocess.run(["loginctl", "enable-linger", os.environ.get("USER", "root")], capture_output=True)
print("✅ Linux Daemon successfully started!")
print(f"Logs: ~/.cortex/agent.out.log and ~/.cortex/agent.err.log")
print("Commands:")
print(" Status: systemctl --user status cortex-agent")
print(" Stop: systemctl --user stop cortex-agent")
print(" Start: systemctl --user start cortex-agent")
print(" Logs: journalctl --user -u cortex-agent -f")
except subprocess.CalledProcessError as e:
print(f"❌ Failed to configure systemd service: {e}")
def main():
if not os.path.exists(get_agent_main_path()):
print(f"❌ Error: Could not find main agent script at {get_agent_main_path()}")
sys.exit(1)
system = platform.system().lower()
if system == "darwin":
install_mac_launchd()
elif system == "linux":
install_linux_systemd()
else:
print(f"❌ Unsupported OS for automated daemon install: {system}")
print("Please configure your system service manager manually.")
if __name__ == "__main__":
main()