Agent-Fassung je Gerät: SHA-256 der agent.py beim Check-in speichern (Migration 0060)
Nachtrag zu ADR-0044: Ob ein Gerät die über die Rolle agent freigegebene Fassung übernommen hat, war aus der Ferne nicht sichtbar. Ältere Agenten schicken nichts (Wert bleibt stehen), ungültige Werte werden verworfen statt den Check-in abzulehnen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
48ebac7576
commit
4ff3c99bee
2 files changed
+26
-3
No files matched your search
@@ -187,6 +187,11 @@ class AgentHealthPayload(BaseModel):
|
||||
class AgentCheckinRequest(BaseModel):
|
||||
device_id: str
|
||||
health: AgentHealthPayload | None = None
|
||||
# SHA-256 der agent.py (14.10.2026, ADR-0044) - ältere Agenten schicken
|
||||
# das Feld nicht, dann bleibt der gespeicherte Wert unverändert. Bewusst
|
||||
# ohne Musterprüfung im Modell: ein ungültiger Wert darf den Check-in
|
||||
# nicht ablehnen, er wird in agent_checkin() nur verworfen.
|
||||
agent_sha256: str | None = None
|
||||
|
||||
|
||||
class AgentReportEntry(BaseModel):
|
||||
@@ -2434,10 +2439,10 @@ def fetch_device_gruppen(device_id: str):
|
||||
# als Konstante statt zweimal ausgeschrieben.
|
||||
GERAETE_HEALTH_SPALTEN_SQL = """d.debug_mode_until, d.health_disk_used_percent, d.health_ram_used_percent,
|
||||
d.health_uptime_seconds, d.health_load_1m, d.health_load_5m, d.health_load_15m,
|
||||
d.health_collected_at"""
|
||||
d.health_collected_at, d.agent_sha256"""
|
||||
|
||||
|
||||
def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, load15, collected_at) -> dict:
|
||||
def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, load15, collected_at, agent_sha256) -> dict:
|
||||
# Live gefunden (11.09.2026): debug_mode_until wird beim Ablaufen nie
|
||||
# in der DB geloescht (agent_checkin() vergleicht nur zur Laufzeit
|
||||
# gegen "jetzt", um das Poll-Intervall zu bestimmen - das bleibt
|
||||
@@ -2449,6 +2454,7 @@ def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, lo
|
||||
ist_noch_aktiv = debug_mode_until is not None and debug_mode_until > datetime.now(timezone.utc)
|
||||
return {
|
||||
"debug_mode_until": debug_mode_until.isoformat() if ist_noch_aktiv else None,
|
||||
"agent_sha256": agent_sha256,
|
||||
"health": {
|
||||
"disk_used_percent": disk,
|
||||
"ram_used_percent": ram,
|
||||
@@ -5686,7 +5692,8 @@ def agent_checkin(
|
||||
health_load_1m = CASE WHEN %(hat_health)s THEN %(load1)s ELSE health_load_1m END,
|
||||
health_load_5m = CASE WHEN %(hat_health)s THEN %(load5)s ELSE health_load_5m END,
|
||||
health_load_15m = CASE WHEN %(hat_health)s THEN %(load15)s ELSE health_load_15m END,
|
||||
health_collected_at = CASE WHEN %(hat_health)s THEN %(jetzt)s ELSE health_collected_at END
|
||||
health_collected_at = CASE WHEN %(hat_health)s THEN %(jetzt)s ELSE health_collected_at END,
|
||||
agent_sha256 = COALESCE(%(agent_sha256)s, agent_sha256)
|
||||
WHERE id = %(device_id)s
|
||||
RETURNING debug_mode_until, hostname
|
||||
""",
|
||||
@@ -5699,6 +5706,11 @@ def agent_checkin(
|
||||
"load1": health.load_1m if health else None,
|
||||
"load5": health.load_5m if health else None,
|
||||
"load15": health.load_15m if health else None,
|
||||
"agent_sha256": (
|
||||
payload.agent_sha256
|
||||
if payload.agent_sha256 and re.fullmatch(r"[0-9a-f]{64}", payload.agent_sha256)
|
||||
else None
|
||||
),
|
||||
"device_id": payload.device_id,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
-- Agent-Fassung je Gerät (14.10.2026, Nachtrag zu platform-docs ADR-0044).
|
||||
-- Der Agent schickt beim Check-in die SHA-256-Summe seiner agent.py mit.
|
||||
-- Damit ist aus der Ferne sichtbar, ob ein Gerät die über die Rolle "agent"
|
||||
-- freigegebene Fassung übernommen hat. NULL = Agent älter als diese
|
||||
-- Meldung (meldet nichts).
|
||||
|
||||
ALTER TABLE devices ADD COLUMN agent_sha256 TEXT;
|
||||
|
||||
COMMIT;
|
||||
Reference in new issue
Block a user