mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
fix: sync public_html/agent/jarvis-agent.py with agent source
public_html/agent/ is what agents download for self-update. It was 5 days out of date — missing the version-in-heartbeat fix and all other v3.1 changes. Now mirrors agent/jarvis-agent.py exactly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,11 +28,45 @@ AGENT_VERSION = "3.1"
|
|||||||
# ── Config helpers ────────────────────────────────────────────────────────────
|
# ── Config helpers ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
def load_config() -> dict:
|
def load_config() -> dict:
|
||||||
|
legacy_path = "/opt/jarvis-agent/config.json"
|
||||||
|
|
||||||
if not os.path.exists(CONFIG_PATH):
|
if not os.path.exists(CONFIG_PATH):
|
||||||
print(f"[ERROR] Config not found at {CONFIG_PATH}. Run the installer first.", flush=True)
|
if os.path.exists(legacy_path):
|
||||||
sys.exit(1)
|
print(f"[JARVIS] Config found at legacy path {legacy_path} - migrating...", flush=True)
|
||||||
with open(CONFIG_PATH) as f:
|
Path(CONFIG_PATH).parent.mkdir(parents=True, exist_ok=True)
|
||||||
return json.load(f)
|
with open(legacy_path) as f:
|
||||||
|
cfg = json.load(f)
|
||||||
|
else:
|
||||||
|
print(f"[ERROR] Config not found at {CONFIG_PATH}. Run the installer first.", flush=True)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
with open(CONFIG_PATH) as f:
|
||||||
|
cfg = json.load(f)
|
||||||
|
|
||||||
|
# Migrate old key names so the agent self-heals instead of crash-looping
|
||||||
|
import re as _re
|
||||||
|
changed = False
|
||||||
|
if "server_url" in cfg and "jarvis_url" not in cfg:
|
||||||
|
cfg["jarvis_url"] = cfg.pop("server_url")
|
||||||
|
print("[JARVIS] Config migrated: server_url -> jarvis_url", flush=True)
|
||||||
|
changed = True
|
||||||
|
if "api_key" in cfg and "registration_key" not in cfg:
|
||||||
|
cfg["registration_key"] = cfg.pop("api_key")
|
||||||
|
print("[JARVIS] Config migrated: api_key -> registration_key", flush=True)
|
||||||
|
changed = True
|
||||||
|
if "hostname" not in cfg:
|
||||||
|
cfg["hostname"] = socket.gethostname()
|
||||||
|
changed = True
|
||||||
|
if "ssl_verify" not in cfg:
|
||||||
|
cfg["ssl_verify"] = not bool(_re.match(r"https?://\d+\.\d+\.\d+\.\d+", cfg.get("jarvis_url", "")))
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if changed:
|
||||||
|
with open(CONFIG_PATH, "w") as f:
|
||||||
|
json.dump(cfg, f, indent=2)
|
||||||
|
print("[JARVIS] Config saved after migration.", flush=True)
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
|
||||||
def load_state() -> dict:
|
def load_state() -> dict:
|
||||||
if os.path.exists(STATE_PATH):
|
if os.path.exists(STATE_PATH):
|
||||||
@@ -265,11 +299,23 @@ def get_load() -> list:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return [0, 0, 0]
|
return [0, 0, 0]
|
||||||
|
|
||||||
|
def get_nordvpn_status() -> dict | None:
|
||||||
|
"""Check nordlynx WireGuard interface. Returns None if nordlynx not present on this host."""
|
||||||
|
try:
|
||||||
|
r = subprocess.run(["ip", "link", "show", "nordlynx"],
|
||||||
|
capture_output=True, text=True, timeout=3)
|
||||||
|
if r.returncode != 0:
|
||||||
|
return None
|
||||||
|
active = "UP,LOWER_UP" in r.stdout or "state UP" in r.stdout
|
||||||
|
return {"active": active, "interface": "nordlynx"}
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
def collect_metrics(cfg: dict) -> dict:
|
def collect_metrics(cfg: dict) -> dict:
|
||||||
# First reading for CPU delta
|
# First reading for CPU delta
|
||||||
get_cpu_percent()
|
get_cpu_percent()
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return {
|
metrics = {
|
||||||
"hostname": cfg.get("hostname", socket.gethostname()),
|
"hostname": cfg.get("hostname", socket.gethostname()),
|
||||||
"cpu_percent": get_cpu_percent(),
|
"cpu_percent": get_cpu_percent(),
|
||||||
"memory": get_memory(),
|
"memory": get_memory(),
|
||||||
@@ -280,6 +326,10 @@ def collect_metrics(cfg: dict) -> dict:
|
|||||||
"platform": platform.system(),
|
"platform": platform.system(),
|
||||||
"timestamp": datetime.utcnow().isoformat() + "Z",
|
"timestamp": datetime.utcnow().isoformat() + "Z",
|
||||||
}
|
}
|
||||||
|
nordvpn = get_nordvpn_status()
|
||||||
|
if nordvpn is not None:
|
||||||
|
metrics["nordvpn"] = nordvpn
|
||||||
|
return metrics
|
||||||
|
|
||||||
# ── Proxmox metrics ───────────────────────────────────────────────────────────
|
# ── Proxmox metrics ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -384,7 +434,7 @@ def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
# Heartbeat + get commands
|
# Heartbeat + get commands
|
||||||
hb = api_post(f"{jarvis_url}/api/agent/heartbeat", {}, headers, ssl_verify=ssl_verify)
|
hb = api_post(f"{jarvis_url}/api/agent/heartbeat", {"version": AGENT_VERSION}, headers, ssl_verify=ssl_verify)
|
||||||
if "error" in hb:
|
if "error" in hb:
|
||||||
print(f"[WARN] Heartbeat failed: {hb['error']}", flush=True)
|
print(f"[WARN] Heartbeat failed: {hb['error']}", flush=True)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1a9e8e24e5aee8f27a5900b6340373023ff2171e844e71e451eecdbf3b2b0f03 jarvis-agent.py
|
6ba92a1ad4f91a218cbc4ce6834c55e8f56a0e22fca04278d77260958e429d5b
|
||||||
|
|||||||
Reference in New Issue
Block a user