release: nexus btpanel session fix and app-v2
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""Central Nexus Agent version (SSOT) and semver-style comparison."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
_AGENT_PY = Path(__file__).resolve().parents[2] / "web" / "agent" / "agent.py"
|
||||
_AGENT_VERSION_CONST_RE = re.compile(r'^AGENT_VERSION\s*=\s*"([^"]+)"', re.MULTILINE)
|
||||
|
||||
|
||||
@lru_cache(maxsize=1)
|
||||
def get_central_agent_version() -> str:
|
||||
"""Read AGENT_VERSION constant from web/agent/agent.py (heartbeat SSOT)."""
|
||||
text = _AGENT_PY.read_text(encoding="utf-8")
|
||||
match = _AGENT_VERSION_CONST_RE.search(text)
|
||||
if not match:
|
||||
raise RuntimeError(f"AGENT_VERSION not found in {_AGENT_PY}")
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def version_tuple(version: str) -> tuple[int, ...]:
|
||||
"""Parse dotted numeric prefix, e.g. 2.0.0 -> (2, 0, 0)."""
|
||||
version = (version or "").strip()
|
||||
if not version:
|
||||
return ()
|
||||
parts: list[int] = []
|
||||
for segment in re.split(r"[.-]", version):
|
||||
if segment.isdigit():
|
||||
parts.append(int(segment))
|
||||
else:
|
||||
break
|
||||
return tuple(parts)
|
||||
|
||||
|
||||
def is_version_lower(remote: str, central: str) -> bool:
|
||||
"""True when remote is strictly older than central."""
|
||||
remote_t = version_tuple(remote)
|
||||
central_t = version_tuple(central)
|
||||
if not remote_t:
|
||||
return True
|
||||
if not central_t:
|
||||
return False
|
||||
return remote_t < central_t
|
||||
|
||||
|
||||
def is_version_at_least(remote: str, central: str) -> bool:
|
||||
"""True when remote >= central (equal counts as skip)."""
|
||||
remote_t = version_tuple(remote)
|
||||
central_t = version_tuple(central)
|
||||
if not remote_t:
|
||||
return False
|
||||
if not central_t:
|
||||
return bool(remote_t)
|
||||
return remote_t >= central_t
|
||||
|
||||
|
||||
def agent_is_installed(
|
||||
*,
|
||||
agent_version_db: str | None,
|
||||
heartbeat: dict[str, str] | None = None,
|
||||
) -> bool:
|
||||
"""True when Agent has reported a version or heartbeat (not merely a DB API key)."""
|
||||
if heartbeat:
|
||||
if (heartbeat.get("agent_version") or "").strip():
|
||||
return True
|
||||
if heartbeat.get("last_heartbeat"):
|
||||
return True
|
||||
return bool((agent_version_db or "").strip())
|
||||
|
||||
|
||||
def compute_agent_guidance(
|
||||
*,
|
||||
agent_version_db: str | None,
|
||||
heartbeat: dict[str, str] | None = None,
|
||||
central: str | None = None,
|
||||
) -> dict[str, str | None]:
|
||||
"""UI hints: install / upgrade / offline / ok."""
|
||||
central_v = central or get_central_agent_version()
|
||||
live_ver = ""
|
||||
if heartbeat:
|
||||
live_ver = (heartbeat.get("agent_version") or "").strip()
|
||||
if not live_ver:
|
||||
live_ver = (agent_version_db or "").strip()
|
||||
|
||||
has_heartbeat = bool(heartbeat and heartbeat.get("last_heartbeat"))
|
||||
installed = agent_is_installed(agent_version_db=agent_version_db, heartbeat=heartbeat)
|
||||
|
||||
base: dict[str, str | None] = {
|
||||
"central_agent_version": central_v,
|
||||
"agent_action": "ok",
|
||||
"agent_action_message": None,
|
||||
}
|
||||
|
||||
if not installed:
|
||||
return {
|
||||
**base,
|
||||
"agent_action": "install",
|
||||
"agent_action_message": (
|
||||
f"尚未安装 Agent(主站版本 {central_v})。"
|
||||
"安装后可自动上报 CPU/内存/磁盘与在线状态;未安装时仅能通过 SSH 手动探活。"
|
||||
),
|
||||
}
|
||||
|
||||
if live_ver and is_version_lower(live_ver, central_v):
|
||||
return {
|
||||
**base,
|
||||
"agent_action": "upgrade",
|
||||
"agent_action_message": (
|
||||
f"当前 Agent {live_ver},低于主站 {central_v},建议升级以获取最新心跳与探针能力。"
|
||||
),
|
||||
}
|
||||
|
||||
if not has_heartbeat:
|
||||
return {
|
||||
**base,
|
||||
"agent_action": "offline",
|
||||
"agent_action_message": (
|
||||
"Agent 已登记但暂无心跳,请检查子机 nexus-agent 服务或点击「诊断」。"
|
||||
),
|
||||
}
|
||||
|
||||
return base
|
||||
Reference in New Issue
Block a user