diff --git a/docs/sessions/2026-08-26.md b/docs/sessions/2026-08-26.md index 82b8824..de8c562 100644 --- a/docs/sessions/2026-08-26.md +++ b/docs/sessions/2026-08-26.md @@ -69,3 +69,119 @@ Brak zmian w repo. ### Narrative > _user-provided summary_ + +## 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/` 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//events.jsonl`, + rzeczywisty layout na VPS to płaskie `events//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_