2026-08-26 17:03:04 +02:00
|
|
|
|
## Session 16:00
|
|
|
|
|
|
|
|
|
|
|
|
Recon floty po 3 tygodniach bez nadzoru (ostatnia sesja 2026-08-06) + sesja
|
|
|
|
|
|
naprawcza: (A) usunięcie watchtowera z LUSTRO jako reliktu spoza GitOps,
|
|
|
|
|
|
(B) higiena kolejek `actions/pending` i zawieszonych incydentów `active` na VPS.
|
|
|
|
|
|
SUPERVISED — checkpointy A/B/C zatwierdzane przez operatora, backup przed
|
|
|
|
|
|
każdą operacją destrukcyjną.
|
|
|
|
|
|
|
|
|
|
|
|
### Commits
|
|
|
|
|
|
|
|
|
|
|
|
Ta sesja nie wprowadziła żadnych commitów w kodzie poza niniejszym logiem —
|
|
|
|
|
|
wyłącznie operacje na nodach (LUSTRO, VPS). Jeden niepowiązany commit
|
|
|
|
|
|
(`003f83d`, kb-publish skill) doszedł na `master` od równoległej sesji
|
|
|
|
|
|
operatora w międzyczasie — poza zakresem tej sesji.
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
(brak commitów tej sesji)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Files changed
|
|
|
|
|
|
|
|
|
|
|
|
Brak zmian w repo.
|
|
|
|
|
|
|
|
|
|
|
|
### Deploys / operacje na nodach
|
|
|
|
|
|
|
|
|
|
|
|
**Recon (read-only, wszystkie 4 węzły: SOLARIA, PIHA, VPS, LUSTRO):**
|
|
|
|
|
|
- Zero nowych commitów na `origin/master` przez 3 tygodnie.
|
|
|
|
|
|
- Soak test R1 (auto-cleanup node-agenta): PIHA 20/20 uruchomień 0 usunięć,
|
|
|
|
|
|
VPS 21/21 uruchomień 0 usunięć, SOLARIA 3/3 0 usunięć, LUSTRO 5/5 —
|
|
|
|
|
|
1 usunięcie (`prune-disposable`, celowy kanarek testowy z 08-06, zgodnie
|
|
|
|
|
|
z zamysłem). Zero ofiar wśród kontenerów chronionych. `rc=23` nie wystąpił
|
|
|
|
|
|
ani razu — fix `0o775` z sesji 08-06 trzyma.
|
|
|
|
|
|
- Zdiagnozowano ciągłą pętlę restartów `pi-watchtower-1` na LUSTRO (API
|
|
|
|
|
|
Docker 1.25 vs wymagane min. 1.40), trwającą nieprzerwanie od co najmniej
|
|
|
|
|
|
2026-08-06 04:31.
|
|
|
|
|
|
|
|
|
|
|
|
**Watchtower LUSTRO — usunięcie (checkpoint A→B, zatwierdzony):**
|
|
|
|
|
|
- Backup: `docker inspect` + `compose.yml` + pusty katalog `/home/pi/watchtower`
|
|
|
|
|
|
→ `/home/pi/watchtower-removal-backup-2026-08-26/` na LUSTRO.
|
|
|
|
|
|
- `docker stop` + `docker rm pi-watchtower-1`, `docker rmi containrrr/watchtower:latest`,
|
|
|
|
|
|
`/home/pi/compose.yml` (jedyne źródło autostartu — brak systemd/cron) przeniesiony
|
|
|
|
|
|
do backupu jako `.disabled`.
|
|
|
|
|
|
- Weryfikacja: `docker ps -a` na LUSTRO czyste; 7 min ciszy zdarzeń
|
|
|
|
|
|
`containers_not_running-watchtower` na VPS (wymagane min. 5 min).
|
|
|
|
|
|
|
|
|
|
|
|
**Higiena kolejek VPS (checkpoint C→wykonanie, zatwierdzony):**
|
|
|
|
|
|
- Backup: `tar czf /opt/homelab/backups/actions-incidents-2026-08-26.tgz`
|
|
|
|
|
|
(`actions/` + `world/incidents.json`), sha256 `ef9afbfa...`.
|
|
|
|
|
|
- 17/18 pending → `cancelled/` (`stale_manual_cleanup`): 16× stare
|
|
|
|
|
|
`alert-node-*`/`alert-ha-*` z czerwca + 1× shadow-mode HA-websocket z 13.08
|
|
|
|
|
|
(kolizja nazwy pliku z niepowiązanym wpisem z 08-06 — zapisany pod nową
|
|
|
|
|
|
nazwą `container-restart-piha-homeassistant-shadowmode-20260813.json`,
|
|
|
|
|
|
żeby nie nadpisać cudzej historii).
|
|
|
|
|
|
- `redeploy-vps-gokapi` **pozostawiony** — realna luka wdrożeniowa (desired
|
|
|
|
|
|
w `hosts/vps/services.yaml`, brak kontenera), nie cruft. Follow-up do
|
|
|
|
|
|
sesji deploy.
|
|
|
|
|
|
- 5 incydentów w `world/incidents.json` ręcznie przełączonych na `resolved`
|
|
|
|
|
|
(`piha-homeassistant`, `solaria-narty27`, `solaria-prune-canary`,
|
|
|
|
|
|
`lustro-prune-canary`, `lustro-watchtower`) — wszystkie zdiagnozowane jako
|
|
|
|
|
|
trwale osierocone (brak mechanizmu auto-resolve dla zniknionej/przeniesionej
|
|
|
|
|
|
usługi, patrz Narrative).
|
|
|
|
|
|
- Sekwencja bez wyścigu: `docker stop control-plane-observer` → edycja pliku
|
|
|
|
|
|
→ `docker start` → weryfikacja >15 s (kilka cykli flush) — bo `_save_world()`
|
|
|
|
|
|
nadpisuje `world/*.json` co 5 s z pamięci procesu, bez merge z dyskiem.
|
|
|
|
|
|
- Efekt uboczny własnego restartu: `inc-...-vps-observer` (1 wystąpienie) —
|
|
|
|
|
|
rozwiązał się sam w ~60 s (poprawny, nieosierocony przypadek).
|
|
|
|
|
|
- Stan końcowy: `active_incidents_count: 0`, `runtime-summary.json status: nominal`.
|
|
|
|
|
|
|
|
|
|
|
|
### Narrative
|
|
|
|
|
|
|
|
|
|
|
|
> _user-provided summary_
|
2026-08-26 23:04:36 +02:00
|
|
|
|
|
|
|
|
|
|
## Session 23:00
|
|
|
|
|
|
|
|
|
|
|
|
Deploy control-plane (observer + supervisor) na VPS: stale-resolve 24h +
|
|
|
|
|
|
flagi `resolve-requests` (commit `71a7af5`), unikalny `action_id`
|
|
|
|
|
|
`container_restart` z bare-id fallbackiem (commit `91db682`), usunięcie
|
|
|
|
|
|
gokapi z desired state (commit `74ff3ee`) — zmerdowane do `master` jako
|
|
|
|
|
|
`f155999` przez operatora tuż przed sesją. SUPERVISED — checkpoint A po
|
|
|
|
|
|
weryfikacji deployu, checkpoint B po teście ścieżki flagi.
|
|
|
|
|
|
|
|
|
|
|
|
### Commits
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
(brak commitów kodu tej sesji — wyłącznie deploy + test na produkcji;
|
|
|
|
|
|
log sesji poniżej dopisany bez pusha)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Files changed
|
|
|
|
|
|
|
|
|
|
|
|
Brak zmian w repo poza niniejszym logiem.
|
|
|
|
|
|
|
|
|
|
|
|
### Deploys / operacje na nodach
|
|
|
|
|
|
|
|
|
|
|
|
**KROK 0 — sanity:** `git pull` na `~/homelab-codex-ws` (SOLARIA, główny
|
|
|
|
|
|
checkout) — już aktualny na `03441a1` (na wierzchu mergu `f155999`).
|
|
|
|
|
|
`git status`/`diff HEAD` czyste. Wcześniej w tej samej sesji (przed
|
|
|
|
|
|
mergem) `git log -1` pokazywał `4fa10f0` — merge jeszcze nie istniał;
|
|
|
|
|
|
zatrzymano się i poczekano na operatora zamiast mergować samodzielnie
|
|
|
|
|
|
(worktree-aware: merge to wyłącznie krok człowieka).
|
|
|
|
|
|
|
|
|
|
|
|
**KROK 1 — deploy control-plane (checkpoint A, zatwierdzony):**
|
|
|
|
|
|
- Rollback tagi: `control-plane-{executor,observer,operator-ui,supervisor}
|
|
|
|
|
|
:rollback-pre-resolvefix` — ten sam wzorzec co `:rollback-pre-dispatchfix`
|
|
|
|
|
|
z 08-06.
|
|
|
|
|
|
- `git pull origin master` na VPS (`003f83d` → `03441a1`, fast-forward),
|
|
|
|
|
|
`docker compose up -d --build --force-recreate`.
|
|
|
|
|
|
- `deploy-local.sh`'s auto-chown krok padł: brak TTY dla hasła sudo,
|
|
|
|
|
|
`/opt/homelab/backups` i `/opt/homelab/events/solaria/*` są `oskar:oskar`
|
|
|
|
|
|
zamiast `aerbot:aerbot` (1000). Sprawdzone: `actions/`, `world/`,
|
|
|
|
|
|
`state/`, `config/` (realna ścieżka zapisu control-plane) już poprawnie
|
|
|
|
|
|
`aerbot:aerbot 775` — ominięto self-heal, `docker compose` odpalony
|
|
|
|
|
|
bezpośrednio bez sudo. Mismatch na `backups/`/`events/solaria/*`
|
|
|
|
|
|
pozostawiony nietknięty (follow-up niżej).
|
|
|
|
|
|
- Weryfikacja: 4/4 kontenery `healthy`, 0 linii error/traceback/exception
|
|
|
|
|
|
od restartu. sha256 `observer.py` (mount `/repo`, żywy) i `supervisor.py`
|
|
|
|
|
|
(wypieczony `/app/src`, wymaga `--build`) == repo HEAD, potwierdzone
|
|
|
|
|
|
osobno przez `docker exec` w obu kontenerach.
|
|
|
|
|
|
- Po 3 cyklach reconcile: `active_incidents: 0`, `world/resolve-requests/`
|
|
|
|
|
|
utworzony przez observera (pusty).
|
|
|
|
|
|
- `redeploy-vps-gokapi` (pending od 07-09) auto-cancelled po pierwszym
|
|
|
|
|
|
cyklu: `cancelled_reason: "service_removed_from_desired_state"` — bez
|
|
|
|
|
|
ponownego wygenerowania. `pending/` pozostał czysty (tylko niezwiązane
|
|
|
|
|
|
alerty HA z piha).
|
|
|
|
|
|
|
|
|
|
|
|
**KROK 2 — test ścieżki flagi na LUSTRO (checkpoint B, zatwierdzony):**
|
|
|
|
|
|
- `docker stop node-exporter` na LUSTRO → observer otworzył
|
|
|
|
|
|
`inc-1787777894-lustro-node-exporter`.
|
|
|
|
|
|
- Flaga: `touch world/resolve-requests/<id>` przez zwykłego SSH
|
|
|
|
|
|
usera **odrzucony permission denied** — katalog `755 aerbot:aerbot`,
|
|
|
|
|
|
brak zapisu grupowego mimo że `oskar` jest w grupie `aerbot`. Obejście:
|
|
|
|
|
|
`docker exec control-plane-observer touch ...` (proces w kontenerze
|
|
|
|
|
|
działa jako uid 1000 = właściciel katalogu). Follow-up niżej.
|
|
|
|
|
|
- Resolve w **1.01 s** od touch (limit ≤10s), `resolved_reason:
|
|
|
|
|
|
manual_operator`, flaga skasowana, `service.incident_id` wyczyszczony,
|
|
|
|
|
|
log INFO `"Manually resolving incident ... via resolve-request flag"`.
|
|
|
|
|
|
- Drift trwał dalej (kontener wciąż stopped) → supervisor wygenerował
|
|
|
|
|
|
`container-restart-lustro-node-exporter-1787777887` — **nowy format
|
|
|
|
|
|
id z COMMIT 2 potwierdzony na produkcji** — oraz równolegle
|
|
|
|
|
|
`redeploy-lustro-node-exporter` (bare id, ścieżka `unhealthy_service`
|
|
|
|
|
|
po wyczyszczeniu `incident_id`).
|
|
|
|
|
|
- Za decyzją operatora: `POST /action/mutate` na `127.0.0.1:18180`
|
|
|
|
|
|
(ten sam endpoint co UI/Telegram) — zatwierdzono restart, odrzucono
|
|
|
|
|
|
redeploy jako nadmiarowy.
|
|
|
|
|
|
- Executor zdispatchował realnie do LUSTRO; node-agent wykonał
|
|
|
|
|
|
`docker restart node-exporter` (log: `"Restarted container
|
|
|
|
|
|
'node-exporter' for action container-restart-lustro-node-exporter
|
|
|
|
|
|
-1787777887"`), akcja `completed`.
|
|
|
|
|
|
- Drift utrzymał się jeszcze chwilę po zatwierdzeniu → drugi, nowy
|
|
|
|
|
|
incydent (`inc-1787777955-...`) i druga, odrębna pending akcja
|
|
|
|
|
|
(`...-1787777950`, inny suffix `started_at`) — dokładnie oczekiwane
|
|
|
|
|
|
zachowanie "różny id przy nowym incydencie". Po powrocie zdrowia
|
|
|
|
|
|
auto-cancelled: `cancelled_reason: "drift_resolved_auto"`, bez
|
|
|
|
|
|
interwencji.
|
|
|
|
|
|
- Stan końcowy: `node-exporter` na LUSTRO `Up`, oba incydenty
|
|
|
|
|
|
`resolved`, `active_incidents: 0`, `pending/` czysty, 4/4 kontenery
|
|
|
|
|
|
control-plane nadal `healthy`, 0 error-ish linii w logach.
|
|
|
|
|
|
|
|
|
|
|
|
### Follow-upy
|
|
|
|
|
|
|
|
|
|
|
|
- **pytest env zepsuty na SOLARII**: `~/.local/bin/pytest` (brak
|
|
|
|
|
|
`_pytest`) i `homelab-codex-ws/.venv` (brak `pytest` w ogóle) oba
|
|
|
|
|
|
niedziałające; działa wyłącznie `/home/oskar/anaconda3/bin/pytest`
|
|
|
|
|
|
(7.4.4). Użyty do pełnego runu przed force-pushem poprawki COMMIT 2
|
|
|
|
|
|
(184 passed control-plane, 70 passed node-agent).
|
|
|
|
|
|
- **`world/resolve-requests/` permissions**: `755 aerbot:aerbot` zamiast
|
|
|
|
|
|
konwencji `775` używanej w `actions/`/`world/`/`state/`/`config/`.
|
|
|
|
|
|
Blokuje operatora SSH przed bezpośrednim `touch` flagi resolve —
|
|
|
|
|
|
manualna ścieżka z 71a7af5 ("operator drops a file") w praktyni wymaga
|
|
|
|
|
|
`docker exec`. Poprawić `chmod 775` / mode przy `os.makedirs` w
|
|
|
|
|
|
observer.py.
|
|
|
|
|
|
- **`backups/` i `events/solaria/*` ownership**: `oskar:oskar` zamiast
|
|
|
|
|
|
`aerbot:aerbot` — nie blokuje funkcjonalnie (czytelne dla "other"), ale
|
|
|
|
|
|
psuje self-heal chown w `deploy-local.sh` (próbuje rekurencyjnego sudo
|
|
|
|
|
|
chown całego `/opt/homelab` bez TTY/hasła). Do ręcznego wyczyszczenia
|
|
|
|
|
|
z hasłem sudo albo do zmiany self-heal na scoped (tylko katalogi
|
|
|
|
|
|
control-plane realnie potrzebuje) zamiast całego drzewa.
|
|
|
|
|
|
- **CLAUDE.md doc drift**: opisuje `events/YYYY-MM-DD/<node>/events.jsonl`,
|
|
|
|
|
|
rzeczywisty layout na VPS to płaskie `events/<node>/evt-*.json` (jeden
|
|
|
|
|
|
plik na zdarzenie, bez partycjonowania po dacie). Do poprawienia przy
|
|
|
|
|
|
najbliższej okazji.
|
|
|
|
|
|
- `redeploy-vps-gokapi` — zamknięty tym deployem (auto-cancelled), nie
|
|
|
|
|
|
wymaga już dalszego follow-upu z sesji 16:00.
|
|
|
|
|
|
|
|
|
|
|
|
### Narrative
|
|
|
|
|
|
|
|
|
|
|
|
> _user-provided summary_
|
2026-08-26 23:07:08 +02:00
|
|
|
|
|
|
|
|
|
|
## Session 23:06
|
|
|
|
|
|
|
|
|
|
|
|
### Commits
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
(brak commitów — sesja bez żadnej pracy poza natychmiastowym zamknięciem)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Files changed
|
|
|
|
|
|
|
|
|
|
|
|
Brak zmian w repo.
|
|
|
|
|
|
|
|
|
|
|
|
### Deploys
|
|
|
|
|
|
|
|
|
|
|
|
None recorded
|
|
|
|
|
|
|
|
|
|
|
|
### Narrative
|
|
|
|
|
|
|
|
|
|
|
|
> _user-provided summary_
|