104 lines
6.6 KiB
Markdown
104 lines
6.6 KiB
Markdown
|
|
# SESSION: Stabilizacja systemu wieloagentowego homelabu
|
||
|
|
|
||
|
|
**DATE:** 2026-05-27
|
||
|
|
**RESULT:** System NOMINAL (97/97 services, 0 errors)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## PROBLEMS FOUND
|
||
|
|
|
||
|
|
- stability-agent nie generował akcji naprawczych — tylko redeploy, brak container_restart
|
||
|
|
- mosquitto na chelsty-infra padł i nikt go nie restartował (restart policy był `no`)
|
||
|
|
- zigbee2mqtt nigdy nie był wdrożony na chelsty-infra
|
||
|
|
- node-agent był pustym szkieletem — nie emitował `service_healthy`, więc `services.json` zawsze był pusty
|
||
|
|
- ghost services: node-agent używał `c.name` (może zwrócić `<12hex>_real-name`) zamiast etykiety `com.docker.compose.service`
|
||
|
|
- materializer na piha czytał ze swojego lokalnego Redis zamiast z control-plane API — Redis zawierał 80 przestarzałych wpisów z ghost kluczami; "Copy for AI" zwracał stare dane
|
||
|
|
- observer używał jednego globalnego checkpointu zamiast per-node — cicho pomijał katalogi z eventami sortujące się przed aktualnym checkpointem
|
||
|
|
- supervisor nie cancelował resolved actions — pending queue rósł bez końca
|
||
|
|
- `service_healthy` event nie zamykał aktywnych incydentów
|
||
|
|
- NODE_ALIAS_MAP nie był skonfigurowany — mismatch nazw nodów między eventem a topology
|
||
|
|
- chelsty-ha błędnie w scope monitoringu — nie ma na nim node-agenta
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## FIXES SHIPPED (commits in master)
|
||
|
|
|
||
|
|
```
|
||
|
|
7277bdc Fix Copy for AI: materializer fetches from control-plane API instead of Redis
|
||
|
|
b40b832 Fix ghost service keys from hash-prefixed Docker container names
|
||
|
|
28e9534 observer: service_healthy resolves active incidents
|
||
|
|
46ae92b supervisor: also cancel pending actions for services removed from desired state
|
||
|
|
410bfe7 zigbee2mqtt: config goes in data dir (writable), not separate ro mount
|
||
|
|
b3912fe zigbee2mqtt: use extra_hosts host-gateway instead of network_mode: host
|
||
|
|
61e07f4 zigbee2mqtt override: clear ports list for docker-compose v1 host network compat
|
||
|
|
51002d4 Fix pending actions: node_exporter, zigbee2mqtt, chelsty-ha monitoring
|
||
|
|
fb7828b supervisor: auto-cancel pending actions when drift is resolved
|
||
|
|
2f19657 fix(node-agent): unique event IDs per service to prevent same-second overwrites
|
||
|
|
267742c vps/node-agent: add network_mode: host for control-plane health probe
|
||
|
|
4e8968f Fix service health tracking: emit service_healthy, control-plane endpoint, checkpoint migration
|
||
|
|
f4a8db9 fix(observer): per-node-directory checkpoints replace single global checkpoint
|
||
|
|
a5a3e22 fix(node-agent): skip SSH config file in rsync to avoid UID ownership errors
|
||
|
|
2349de5 fix(node-agent): correct VPS_EVENTS_HOST to actual VPS Tailscale IP
|
||
|
|
65bac4e fix(node-agent): mount host SSH key into container for event shipping
|
||
|
|
96bf326 fix(observer+operator-ui): fix stale world state, dict→list API, event time filter
|
||
|
|
ae33cce feat(node-agent): add runtime overrides for piha, solaria, chelsty-infra
|
||
|
|
c5c080b feat(vps): add node-agent runtime override with NODE_NAME=vps
|
||
|
|
01b7758 feat(node-agent): implement health monitor and safe cleanup policy
|
||
|
|
```
|
||
|
|
|
||
|
|
### Szczegóły kluczowych napraw
|
||
|
|
|
||
|
|
**fix(observer): per-node checkpoints**
|
||
|
|
Jeden globalny checkpoint `last_processed_file` cicho pomijał katalogi eventów sortujące się alfabetycznie przed ostatnim przetworzonym węzłem (np. piha/ < vps/). Zastąpiony słownikiem `{"node_checkpoints": {"piha": "...", "vps": "..."}}` per-node.
|
||
|
|
|
||
|
|
**fix(observer): ghost key pruning**
|
||
|
|
`_prune_stale_world()` teraz usuwa wpisy z services.json których klucz serwisu pasuje do wzorca `<12hexchars>_<name>` — artefakty z Docker internal state tracking.
|
||
|
|
|
||
|
|
**fix(node-agent): canonical container name**
|
||
|
|
`check_containers()` teraz używa `com.docker.compose.service` label jako nazwy kanonicznej. Fallback: strip hash prefix z `c.name`. Kontenery w stanie `created` są pomijane (Docker stale-state artifacts).
|
||
|
|
|
||
|
|
**fix(node-agent): service_healthy emission**
|
||
|
|
Node-agent teraz emituje `service_healthy` dla każdego uruchomionego zarządzanego kontenera co cykl. Bez tego `services.json` był zawsze pusty — supervisor generował flood "missing service" redeployów.
|
||
|
|
|
||
|
|
**fix(supervisor): auto-cancel resolved actions**
|
||
|
|
`_cancel_resolved_pending_actions()` przenosi pending akcje do `cancelled/` gdy:
|
||
|
|
- serwis stał się healthy (`drift_resolved_auto`)
|
||
|
|
- serwis został usunięty z desired state (`service_removed_from_desired_state`)
|
||
|
|
|
||
|
|
**fix(supervisor): monitor:false**
|
||
|
|
Pole `monitor: false` w `services.yaml` wyklucza serwis z generowania akcji supervisora. Używane dla `homeassistant` na chelsty-ha (brak node-agenta).
|
||
|
|
|
||
|
|
**fix(agent-system/materializer): control-plane API as source**
|
||
|
|
Materializer na piha teraz fetchuje dane z VPS control-plane API (`CONTROL_PLANE_URL=http://100.95.58.48:18180`) zamiast z lokalnego Redis. Redis zawierał 80 przestarzałych wpisów. Redis path zachowany jako fallback.
|
||
|
|
|
||
|
|
**fix(chelsty-infra/zigbee2mqtt): mosquitto networking**
|
||
|
|
Mosquitto działa z `network_mode: host` — kontenery bridge nie mogą go dosięgnąć przez localhost. Rozwiązanie: `extra_hosts: - "mosquitto:host-gateway"` w override z2m. Nie używamy `network_mode: host` dla z2m bo koliduje z `ports:` w docker-compose v1 (1.29.2 na chelsty-infra).
|
||
|
|
|
||
|
|
**fix(chelsty-infra/zigbee2mqtt): writable config**
|
||
|
|
z2m migruje i nadpisuje `configuration.yaml` przy starcie. Config musi być w katalogu z danymi: `/opt/homelab/data/zigbee2mqtt/data/configuration.yaml` (read-write mount), nie w osobnym `:ro` wolumenie.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## STAN KOŃCOWY
|
||
|
|
|
||
|
|
| Node | Status | Serwisy |
|
||
|
|
|------|--------|---------|
|
||
|
|
| vps | online | control-plane (4), node-agent, node_exporter, stability-agent |
|
||
|
|
| piha | online | agent-system (4), node-agent, stability-agent, monitoring stack |
|
||
|
|
| solaria | online | node-agent, stability-agent, AI workloads |
|
||
|
|
| chelsty-infra | online | mosquitto, zigbee2mqtt (z2m łączy się gdy SLZB-06U wróci online), node-agent, stability-agent |
|
||
|
|
| chelsty-ha | — | homeassistant (monitor:false — brak node-agenta, HA monitorowane pośrednio przez MQTT) |
|
||
|
|
|
||
|
|
**Action queue:** 0 pending, 0 approved, 0 running
|
||
|
|
**Incidents:** 0 active
|
||
|
|
**Ghost service keys:** 0
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ZNANE OGRANICZENIA / TODO
|
||
|
|
|
||
|
|
- SLZB-06U (Zigbee coordinator) offline — `192.168.1.105:6638` EHOSTUNREACH z chelsty-infra. Prawdopodobnie problem sprzętowy/sieciowy po stronie 192.168.1.0/24. z2m startuje i serwuje stronę błędu na :8080 — połączy się automatycznie gdy coordinator wróci.
|
||
|
|
- `ezsp` adapter w konfiguracji z2m jest deprecated — zalecana migracja do `ember`. Nie wymaga nowej konfiguracji, tylko zmiana pola `adapter: ember` w `configuration.yaml`.
|
||
|
|
- chelsty-ha nie ma node-agenta. Dodać gdy będzie dostępna maszyna lub manual bootstrap.
|
||
|
|
- Redis na piha nadal zawiera stare klucze `homelab:nodes:*`, `homelab:incidents:*` etc. — nie są już używane przez materializer w trybie API, można wyczyścić.
|