Check-in speichert ansible_weg (ADR-0046 Schritt 2), Migration 0068

Der Agent meldet seit 54f76f1, ob er den Ansible-Stand als Archiv von
anode, per Git oder per Git-Rückfall bezogen hat. Nur die drei bekannten
Werte werden gespeichert; Gerätelisten liefern das Feld mit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-10-21 09:40:42 +02:00
1 parent 4e1fae12d0
commit 999b197dd5
2 files changed
+23 -3

No files matched your search

+12 -3
View File
@@ -64,6 +64,8 @@ SPIEGEL_GIT_TIMEOUT_SECONDS = 120
# Je Stufe ausgelieferte Stände: der aktuelle und zwei vorige - ein Gerät,
# das seinen Stand kurz vor einer Freigabe erfahren hat, kann ihn noch holen.
SPIEGEL_STAENDE_JE_STUFE = 3
# Meldung des Agenten, wie er den Stand bezogen hat (Check-in "ansible_weg").
ANSIBLE_WEGE = ("archiv", "git", "git-rueckfall")
# Dateien, die Agent-Wechsel und Neuinstallation aus provisioning-agent holen.
AGENT_FASSUNG_DATEIEN = ("agent.py", "firstboot.sh", "tuxflotte-agent.service", "tuxflotte-firstboot.service")
ADMIN_TOKEN = os.environ.get("TUXFLOTTE_ADMIN_TOKEN", "")
@@ -221,6 +223,10 @@ class AgentCheckinRequest(BaseModel):
# 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
# Weg zum Ansible-Stand (ADR-0046): "archiv", "git" oder "git-rueckfall".
# Wie agent_sha256 ohne Prüfung im Modell, unbekannte Werte verwirft
# agent_checkin().
ansible_weg: str | None = None
class AgentReportEntry(BaseModel):
@@ -3018,10 +3024,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.agent_sha256"""
d.health_collected_at, d.agent_sha256, d.ansible_weg"""
def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, load15, collected_at, agent_sha256) -> dict:
def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, load15, collected_at, agent_sha256, ansible_weg) -> 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
@@ -3034,6 +3040,7 @@ def _health_felder_aus_row(debug_mode_until, disk, ram, uptime, load1, load5, lo
return {
"debug_mode_until": debug_mode_until.isoformat() if ist_noch_aktiv else None,
"agent_sha256": agent_sha256,
"ansible_weg": ansible_weg,
"health": {
"disk_used_percent": disk,
"ram_used_percent": ram,
@@ -7350,7 +7357,8 @@ def agent_checkin(
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,
agent_sha256 = COALESCE(%(agent_sha256)s, agent_sha256)
agent_sha256 = COALESCE(%(agent_sha256)s, agent_sha256),
ansible_weg = COALESCE(%(ansible_weg)s, ansible_weg)
WHERE id = %(device_id)s
RETURNING debug_mode_until, hostname
""",
@@ -7368,6 +7376,7 @@ def agent_checkin(
if payload.agent_sha256 and re.fullmatch(r"[0-9a-f]{64}", payload.agent_sha256)
else None
),
"ansible_weg": payload.ansible_weg if payload.ansible_weg in ANSIBLE_WEGE else None,
"device_id": payload.device_id,
},
)