Newer
Older
cortex-hub / agent-node / purge.py
#!/usr/bin/env python3
"""
Cortex Agent Node - Clean Purge Tool
====================================
Stops services, deregisters from the Hub, and deletes all agent files.

Usage:
    python3 purge.py [--force]
"""

import os
import sys
import time
import shutil
import platform
import subprocess
import requests
from agent_node.utils.service_manager import get_service_manager

def load_env():
    env_path = os.path.join(os.path.dirname(__file__), ".env")
    env = {}
    if os.path.exists(env_path):
        with open(env_path, "r") as f:
            for line in f:
                if "=" in line:
                    key, val = line.strip().split("=", 1)
                    env[key] = val
    return env

def main():
    print("๐Ÿงน Starting Cortex Agent Clean Purge...")
    
    env = load_env()
    node_id = env.get("AGENT_NODE_ID")
    token = env.get("AGENT_AUTH_TOKEN")
    hub_url = env.get("AGENT_HUB_URL")

    # 1. Uninstall Service
    print("[*] Removing background daemon/service...")
    manager = get_service_manager()
    try:
        manager.stop()
        if manager.uninstall():
            print("โœ… Service uninstalled.")
        else:
            print("โš ๏ธ Service was not installed or failed to uninstall.")
    except Exception as e:
        print(f"โš ๏ธ Error during service removal: {e}")

    # 2. Deregister from Hub
    if node_id and token and hub_url:
        print(f"[*] Deregistering node '{node_id}' from Hub...")
        purge_url = f"{hub_url}/api/v1/nodes/purge?node_id={node_id}&token={token}"
        try:
            resp = requests.post(purge_url, timeout=10)
            if resp.status_code == 200:
                print("โœ… Hub successfully notified. Node record deleted.")
            else:
                print(f"โš ๏ธ Hub rejected purge request: {resp.text}")
        except Exception as e:
            print(f"โš ๏ธ Could not reach Hub for deregistration: {e}")
    else:
        print("โš ๏ธ Missing .env details. Skipping Hub deregistration.")

    # 3. Final Wipe
    working_dir = os.path.abspath(os.path.dirname(__file__))
    print(f"[*] Preparing to delete directory: {working_dir}")
    
    # Platform-specific self-deletion
    if platform.system() == "Windows":
        # Create a temporary batch file to delete the folder after this process exits
        temp_dir = os.environ.get("TEMP", "C:\\Temp")
        bat_path = os.path.join(temp_dir, f"cortex_purge_{int(time.time())}.bat")
        
        # Batch script: Wait for Python to exit, remove dir, delete itself.
        bat_content = f"""@echo off
timeout /t 2 /nobreak > nul
rd /s /q "{working_dir}"
del "%~f0"
"""
        with open(bat_path, "w") as f:
            f.write(bat_content)
        
        print(f"๐Ÿš€ Launching cleanup wrapper: {bat_path}")
        subprocess.Popen(["cmd.exe", "/c", bat_path], shell=True)
    else:
        # Linux/Mac can usually 'rm' themselves while running, 
        # but to be safe we'll use a shell wrapper
        print("๐Ÿš€ Executing final recursive deletion...")
        # We run it in the background with a small delay
        cmd = f"sleep 1 && rm -rf {working_dir} &"
        os.system(cmd)

    print("\nโœ… Purge complete. Goodbye!")
    sys.exit(0)

if __name__ == "__main__":
    # Ensure requests is installed for this script (minimal dependency check)
    try:
        import requests
    except ImportError:
        print("[*] Installing requests for deregistration...")
        subprocess.run([sys.executable, "-m", "pip", "install", "requests"], capture_output=True)
        import requests
        
    main()