Feat: implement dynamic agent version fetching and update mechanism
All checks were successful
Build and Push Docker Images / docker (push) Successful in 16s
All checks were successful
Build and Push Docker Images / docker (push) Successful in 16s
This commit is contained in:
Binary file not shown.
@@ -8,6 +8,7 @@ import asyncio
|
|||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import time
|
import time
|
||||||
@@ -47,7 +48,18 @@ from webauthn.helpers.structs import (
|
|||||||
# ─── Config ───────────────────────────────────────────────────────────────────
|
# ─── Config ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
DB_FILE = Path(os.getenv("DB_FILE", "data/monitor.db"))
|
DB_FILE = Path(os.getenv("DB_FILE", "data/monitor.db"))
|
||||||
EXPECTED_AGENT_VERSION = os.getenv("EXPECTED_AGENT_VERSION", "1.2.0")
|
|
||||||
|
# Version de référence : d'abord env var explicite, sinon récupérée dynamiquement depuis le dépôt
|
||||||
|
_FORCED_AGENT_VERSION = os.getenv("EXPECTED_AGENT_VERSION", "") # si non vide, court-circuite le fetch
|
||||||
|
REPO_AGENT_URL = os.getenv(
|
||||||
|
"REPO_AGENT_URL",
|
||||||
|
"https://git.jeanbonapp.com/jeanbon/ScriptVPS/raw/branch/main/vps-monitor/agent/agent.py",
|
||||||
|
)
|
||||||
|
_latest_agent_version: str = _FORCED_AGENT_VERSION or "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
def _get_expected_version() -> str:
|
||||||
|
return _latest_agent_version
|
||||||
|
|
||||||
# ─── Ring buffer de stats (en mémoire) ───────────────────────────────────────
|
# ─── Ring buffer de stats (en mémoire) ───────────────────────────────────────
|
||||||
_STATS_MAX_POINTS = 120 # 10 min à 5 s d'intervalle
|
_STATS_MAX_POINTS = 120 # 10 min à 5 s d'intervalle
|
||||||
@@ -541,8 +553,8 @@ async def fetch_vps_status(vps: dict) -> dict:
|
|||||||
"system": system,
|
"system": system,
|
||||||
"tags": vps.get("tags", []),
|
"tags": vps.get("tags", []),
|
||||||
"agent_version": agent_version,
|
"agent_version": agent_version,
|
||||||
"expected_agent_version": EXPECTED_AGENT_VERSION,
|
"expected_agent_version": _get_expected_version(),
|
||||||
"agent_up_to_date": agent_version == EXPECTED_AGENT_VERSION,
|
"agent_up_to_date": agent_version == _get_expected_version() and _get_expected_version() != "unknown",
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {
|
return {
|
||||||
@@ -557,7 +569,7 @@ async def fetch_vps_status(vps: dict) -> dict:
|
|||||||
"system": None,
|
"system": None,
|
||||||
"tags": vps.get("tags", []),
|
"tags": vps.get("tags", []),
|
||||||
"agent_version": None,
|
"agent_version": None,
|
||||||
"expected_agent_version": EXPECTED_AGENT_VERSION,
|
"expected_agent_version": _get_expected_version(),
|
||||||
"agent_up_to_date": False,
|
"agent_up_to_date": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,10 +626,37 @@ async def _stats_collector() -> None:
|
|||||||
await asyncio.sleep(5)
|
await asyncio.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
|
async def _refresh_latest_agent_version() -> None:
|
||||||
|
"""Récupère AGENT_VERSION depuis le dépôt Gitea toutes les heures.
|
||||||
|
Si EXPECTED_AGENT_VERSION est défini en env var, cette tâche n'écrase pas la valeur forcée.
|
||||||
|
"""
|
||||||
|
global _latest_agent_version
|
||||||
|
if _FORCED_AGENT_VERSION:
|
||||||
|
return # version forcée par env var — pas besoin de fetcher
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
timeout = aiohttp.ClientTimeout(total=10)
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(REPO_AGENT_URL, timeout=timeout) as r:
|
||||||
|
if r.status == 200:
|
||||||
|
text = await r.text()
|
||||||
|
m = re.search(
|
||||||
|
r'^AGENT_VERSION\s*=\s*["\']([^"\']+)["\']',
|
||||||
|
text,
|
||||||
|
re.MULTILINE,
|
||||||
|
)
|
||||||
|
if m:
|
||||||
|
_latest_agent_version = m.group(1)
|
||||||
|
except Exception:
|
||||||
|
pass # garder la dernière valeur connue en cas d'erreur réseau
|
||||||
|
await asyncio.sleep(3600) # rafraîchit toutes les heures
|
||||||
|
|
||||||
|
|
||||||
@app.on_event("startup")
|
@app.on_event("startup")
|
||||||
async def startup_event() -> None:
|
async def startup_event() -> None:
|
||||||
asyncio.create_task(_stats_collector())
|
asyncio.create_task(_stats_collector())
|
||||||
asyncio.create_task(_cleanup_old_stats())
|
asyncio.create_task(_cleanup_old_stats())
|
||||||
|
asyncio.create_task(_refresh_latest_agent_version())
|
||||||
|
|
||||||
|
|
||||||
async def _cleanup_old_stats() -> None:
|
async def _cleanup_old_stats() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user