homelab-codex-ws/docs/sessions/2026-08-26.md
2026-08-26 23:07:08 +02:00

9.7 KiB
Raw Permalink Blame History

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

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 (003f83d03441a1, 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/*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-1787777887nowy 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

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