diff --git a/.claude/skills/node-onboarding/SKILL.md b/.claude/skills/node-onboarding/SKILL.md index d18d632..703c2f4 100644 --- a/.claude/skills/node-onboarding/SKILL.md +++ b/.claude/skills/node-onboarding/SKILL.md @@ -125,6 +125,7 @@ Always run `--dry-run` first; dry-run must print real commands (`run()` propagat | `yaml_get` keeps inline YAML comments | Strip with `s/[[:space:]]\+#.*$//` after extraction (requires ≥1 space before `#`) | | dry-run stops at orchestrator level | `run()` wrapper + `export DRY_RUN=1` propagated to all step scripts; probes execute for real | | rsync push Permission denied to VPS events/ | ssh-user must be in the **group that owns `/opt/homelab/events/`** (aerbot/1000 on VPS). Symptom: silent WARNING in node-agent log, 292k files backlog, panel stale. Fix: `usermod -aG 1000 ` on VPS + re-login | +| node-agent SSH key mount target | Mount the push key under the **container's HOME**: `/home/homelab/.ssh` (uid 1000 `homelab`), **NOT `/root/.ssh`** — ssh in `_ship_events_to_vps()` has no `-i` and only looks in `$HOME/.ssh`; a `/root/.ssh` mount is blind → `Permission denied` (lustro 2026-06-11, fix `a5a1352`). The new node's pubkey must also land in `authorized_keys` of `oskar@VPS` | | observer not seeing new node after topology.yaml edit | `_load_inventory()` runs once at `__init__`. After `git pull` on VPS (bind-mount is live), **`docker restart control-plane-observer`** is required — no redeploy needed | | worktree on wrong branch | Always check `git branch --show-current` on entry. One task = one worktree (`agent.sh new`). Never manually `git checkout` between task branches in the same worktree | diff --git a/docs/backlog.md b/docs/backlog.md index 736ad94..8d9e007 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -6,6 +6,69 @@ Centralny tracker tech-długu i znanych usterek. Wpisy ze sesji — dodawaj z da ## Aktywne +### 🔴 BLOKUJĄCE — FLOTA-BOMBA: node-agent SSH mount ślepy po recreate + +**Data**: 2026-06-11 +**Źródło**: sesja lustro ssh shipping fix +**Problem**: solaria/piha/chelsty to stare **root** kontenery node-agenta (piha Created +2026-05-27, uid 0) — sprzed dodania `user: "1000:1000"` do bazowego compose. Ich override +montuje klucz SSH w `/root/.ssh`, co działa tylko dla uid 0. Pierwszy `--force-recreate` / +reboot hosta / update obrazu przełączy kontener na uid 1000 (`homelab`, HOME=/home/homelab) +i shipping eventów na VPS padnie z "Permission denied" — dokładnie jak na lustrze +(naprawione `a5a1352`). `ssh` w `_ship_events_to_vps()` nie ma `-i` i szuka klucza +w `$HOME/.ssh`. +**⚠️ NIE RECREATE node-agenta na solaria/piha/chelsty przed fixem.** +**Fix**: ujednolicić mount → `/home/homelab/.ssh` we wszystkich +`hosts/*/runtime/node-agent/docker-compose.override.yml` (wzór: `hosts/lustro/`) +ALBO dodać `-i $HOME/.ssh/id_rsa` w `_ship_events_to_vps()`. + +--- + +### ha-diag-agent deploy ZABLOKOWANY (placeholder token) + +**Data**: 2026-06-11 +**Źródło**: sesja — deploy config merged (`5e9db5c`), `.env` na piha utworzony +(`/opt/homelab/config/ha-diag-agent/.env`, chmod 600) ale token = PLACEHOLDER. +**Blokada**: chelsty-ha offline → brak tokenu i połączenia. +**Do decyzji**: cel HA — chelsty-ha vs HA Ken (`homeassistant5` na piha; z kontenera +NIE `localhost`). +**Przed `shadow_mode=false`**: target restartu w supervisorze = nazwa kontenera +`homeassistant5`; curl endpointu HA z tokenem = HTTP 200. + +--- + +### observer-poison-quarantine — review brancha (`78c9e4a`) + +**Data**: 2026-06-11 +**Źródło**: sesja — patch Codexa zachowany na `task/observer-poison-quarantine`, NIE w master. +**Do zrobienia**: zweryfikować, czy observer realnie wiesza się na malformed evencie +(poison NIE był przyczyną awarii lustra — hipoteza niezweryfikowana, obalona przez +verify-before-fix). Realny bug → merge; inaczej → drop brancha i worktree. + +--- + +### node_agent.py — drobne sprzątanie shippingu + +**Data**: 2026-06-11 +**Źródło**: sesja lustro ssh shipping fix +1. **Stale komentarz** `node_agent.py:546-548` — twierdzi, że kontener "runs as root"; + nieaktualne od `user: "1000:1000"`. +2. **Sukces shippingu na `logger.debug`** → podnieść do `info` lub dodać licznik — + działający shipping jest niewidoczny w logach przy INFO, co utrudniało diagnozę + (cicha awaria wyglądała identycznie jak ciche działanie). + +--- + +### event-bloat: wyczyścić spłynięty backlog lustro na VPS + +**Data**: 2026-06-11 +**Źródło**: sesja — po fixie shippingu 7600+ plików backlogu spłynęło do +`/opt/homelab/events/lustro/` na VPS. +**Fix**: wyczyścić stare pliki (observer już je przetworzył); docelowo polityka retencji +w event-store. + +--- + ### rsync `--omit-dir-times` (node-agent) **Data**: 2026-06-09 @@ -15,6 +78,9 @@ zwraca EPERM (oskar nie jest właścicielem katalogu; aerbot jest). Pliki są ko ale exit 23 zaśmieca logi i może maskować prawdziwe błędy. **Fix**: dodać `--omit-dir-times` do wywołania `rsync` w `node-agent.py`. **Lokalizacja**: `services/node-agent/src/node_agent.py` — wywołanie rsync w pętli push. +**Update 2026-06-11**: potwierdzone flotowo — każdy node loguje fałszywe +"Event shipping failed" (rsync code 23) co cykl, mimo że pliki przechodzą; katalogi +`/opt/homelab/events/*` na VPS należą do `aerbot`, klient nie ustawi na nich czasów. --- diff --git a/docs/sessions/2026-06-11-lustro-ssh-shipping.md b/docs/sessions/2026-06-11-lustro-ssh-shipping.md new file mode 100644 index 0000000..197e5ef --- /dev/null +++ b/docs/sessions/2026-06-11-lustro-ssh-shipping.md @@ -0,0 +1,81 @@ +# Sesja 2026-06-10/11 — lustro SSH shipping fix + ha-diag-agent piha + +## Cel + +Naprawa shippingu eventów lustro → VPS; domknięcie deploy-configu ha-diag-agent na piha; +zachowanie poison-quarantine (Codex) do osobnego review. + +--- + +## GŁÓWNE: LUSTRO event shipping — NAPRAWIONY (merged `a5a1352`) + +### Root cause + +`_ship_events_to_vps()` (`services/node-agent/src/node_agent.py`) woła `ssh` **bez `-i`**, +więc klucz jest szukany w `$HOME/.ssh` = `/home/homelab/.ssh` (kontener działa jako +uid 1000 `homelab` od dodania `user: "1000:1000"` do bazowego +`services/node-agent/docker-compose.yml`). Override lustra montował klucz w `/root/.ssh` +— **ślepy mount**, ssh tam nie patrzy → `oskar@100.95.58.48: Permission denied`. + +### Fix + +`hosts/lustro/runtime/node-agent/docker-compose.override.yml`: + +```yaml +- /home/pi/.ssh:/home/homelab/.ssh:ro # było: /root/.ssh — ślepe +``` + +Klucz `pi@pimirror2` dodany do `authorized_keys` `oskar@VPS`. +uid match (pi=1000 = homelab=1000) spełnia strict ownership check OpenSSH. + +### Weryfikacja + +- 5 nodów NOMINAL w world state; lustro w `/opt/homelab/world/nodes.json` (online, świeży `last_seen`) +- 7600+ eventów backlogu spłynęło na VPS (`/opt/homelab/events/lustro/`) +- Staging na lustrze drenowany do zera (`--remove-source-files` działa) +- "Permission denied" zniknął z logów node-agenta + +### Diagnoza — lekcja verify-before-fix + +Oba agenty (Claude Code, Codex) błędnie wskazały observer (poison event / race) +na **nieaktualnym stanie** (`events=2` z ręcznego testu). Verify-before-fix obalił +obie hipotezy: `events/lustro` na VPS było puste → problem w warstwie **dostarczania** +(klucz SSH), nie w observerze. + +--- + +## ha-diag-agent piha — deploy config merged (`5e9db5c`), deploy NIEDOKOŃCZONY + +- `.env` utworzony na piha: `/opt/homelab/config/ha-diag-agent/.env`, chmod 600 +- **ALE token = PLACEHOLDER** — chelsty-ha offline → brak tokenu i połączenia +- Przed `shadow_mode=false`: target restartu w supervisorze = nazwa kontenera + `homeassistant5`; curl endpointu z tokenem musi dać HTTP 200 +- Decyzja PENDING: cel HA = chelsty-ha vs HA Ken (`homeassistant5` na piha — + z kontenera NIE `localhost`) + +--- + +## observer poison-quarantine (Codex) + +Zachowany na branchu `task/observer-poison-quarantine` (`78c9e4a`) — **NIE w master**. +Do osobnego review: czy observer realnie wiesza się na malformed evencie +(poison NIE był przyczyną lustra; hipoteza niezweryfikowana). +Realny bug → merge; inaczej → drop. + +--- + +## 🔴 FLOTA-BOMBA — odkryta, NIE naprawiona (backlog, BLOKUJĄCE) + +solaria / piha / chelsty to wciąż **stare root kontenery** node-agenta +(piha Created 2026-05-27, uid 0). Ich mount `/root/.ssh` działa tylko dlatego, +że kontenery są sprzed `user: "1000:1000"`. Pierwszy `--force-recreate` / reboot +hosta / update obrazu przełączy je na uid 1000 i shipping padnie jak na lustrze. +**NIE RECREATE bez fixu.** Szczegóły i fix: `docs/backlog.md`. + +--- + +## Tech-debt złapany w sesji + +→ wpisany do `docs/backlog.md` (flota-bomba, ha-diag-agent blocked, +poison-quarantine review, `--omit-dir-times`, stale komentarz node_agent.py, +shipping success na `logger.debug`, event-bloat lustro na VPS).