119 lines
5.1 KiB
Markdown
119 lines
5.1 KiB
Markdown
|
|
# Sesja 2026-06-25 — fleet-prometheus etap 1: uruchomienie na VPS + incydent mózgu
|
||
|
|
|
||
|
|
## Cel
|
||
|
|
|
||
|
|
Domknięcie etapu 1 "Prometheus jako źródło prawdy liveness floty": uruchomienie
|
||
|
|
`fleet-prometheus` na VPS i potwierdzenie nasłuchu na Tailscale IP. Kontynuacja
|
||
|
|
wątku z sesji 2026-06-24 (scaffold gotowy, kontener nie powstał przez rozjazd stanu).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ZROBIONE
|
||
|
|
|
||
|
|
### fix(deploy-node): warunkowy `--env-file` per-serwis (commit `686aca7`)
|
||
|
|
|
||
|
|
**Problem złapany przed deployem**: `deploy-node.sh` wywoływał `docker compose up` bez
|
||
|
|
`--env-file`, więc `${TAILSCALE_BIND_IP}` interpolował się do pustego stringa →
|
||
|
|
bind `0.0.0.0:9090` (publicznie otwarty port na VPS). Złapane lekturą skryptu przed
|
||
|
|
deployem — verify-before-fix zarobił.
|
||
|
|
|
||
|
|
**Fix**: dodano guard `if [ -f "services/<svc>/.env" ]` i przekazanie `--env-file
|
||
|
|
services/<svc>/.env` do `compose up`. Worktree `task/deploy-envfile-fix`, merge ff-only.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### test(control-plane): fix flaky `test_incident_lifecycle.py` (commit `992ff7c`)
|
||
|
|
|
||
|
|
**Root cause** okazał się inny niż pierwsza hipoteza (globalny `EVENTS_DIR` leak):
|
||
|
|
`OBSERVER_STATE_FILE` (`observer.py:62` = `STATE_DIR/observer_checkpoint.json`)
|
||
|
|
jest wyprowadzany przy imporcie modułu. Helpery patchowały `STATE_DIR`, ale NIE
|
||
|
|
`OBSERVER_STATE_FILE` — `run_once → _save_checkpoint` pisał checkpointy z ścieżkami
|
||
|
|
otagowanymi numerem przebiegu (`pytest-0`, `pytest-5`) na **realny dysk**
|
||
|
|
`/opt/homelab/state/`. Kolejny przebieg odczytywał je i stringa-compare ścieżek różniących
|
||
|
|
się tylko numerem przebiegu zwracał `False` → false-negative.
|
||
|
|
|
||
|
|
**Fix**: autouse monkeypatch fixture redirectujący WSZYSTKIE ścieżki stanu, w tym
|
||
|
|
`OBSERVER_STATE_FILE` (auto-revert po każdym teście); usunięto nieużywany buggy
|
||
|
|
`_make_observer`. Posprzątano też zatruty realny `/opt/homelab/state/observer_checkpoint.json`.
|
||
|
|
|
||
|
|
**Weryfikacja**: 6/6 przebiegów → 28 passed. Worktree `task/fix-flaky-incident-tests`,
|
||
|
|
merge ff-only.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Swap 4 GB na VPS — aktywny i trwały
|
||
|
|
|
||
|
|
Potwierdzono: `/swapfile` aktywny, wpis w `/etc/fstab`, `vm.swappiness=10` w `sysctl.conf`.
|
||
|
|
Host-level one-off wykonany wcześniej (sesja 2026-06-22); w tej sesji zweryfikowany
|
||
|
|
jako warunek wstępny pod fleet-prometheus na RAM-ciasnym VPS (3.7 GB RAM, wcześniej swap=0).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### fleet-prometheus uruchomiony i zweryfikowany na VPS (trzykrotnie)
|
||
|
|
|
||
|
|
Po naprawie `--env-file` w `deploy-node.sh` kontener wystartował. Bind **zweryfikowany
|
||
|
|
trzykrotnie** różnymi metodami:
|
||
|
|
|
||
|
|
1. `ss -tlnp | grep 9090` → `100.95.58.48:9090` (NIE `0.0.0.0`).
|
||
|
|
2. `docker ps` ports → `100.95.58.48:9090->9090/tcp`.
|
||
|
|
3. Kontrola odwrotna: `curl http://135.181.153.108:9090` (publiczny IP VPS) → głucho.
|
||
|
|
|
||
|
|
Scrape żywy: self + `fleet-node` (node_exporter VPS) oba `health: up`.
|
||
|
|
|
||
|
|
Etap "uruchomienie scaffoldu" domknięty. Image: `prom/prometheus:v3.5.0`, status: healthy.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Sudo/ownership na VPS — samoistnie naprawione
|
||
|
|
|
||
|
|
`deploy-local.sh` woła `sudo chown` tylko gdy `find /opt/homelab` znajdzie plik nie-1000.
|
||
|
|
Znalazł historyczne rootowe pliki i naprawił je bez ręcznej interwencji. Po naprawie
|
||
|
|
`/opt/homelab` w całości `1000:1000`, `find` pusty, deploy przestał wymagać hasła.
|
||
|
|
Obserwować, czy producent rootowych plików nie wróci.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## INCYDENT: `deploy.sh vps` rozwalił control-plane
|
||
|
|
|
||
|
|
### Co się stało
|
||
|
|
|
||
|
|
`deploy.sh vps` próbował deployować control-plane przez pętlę `deploy-node.sh`.
|
||
|
|
Pętla używa `COMPOSE_PROJECT_NAME` wywodzący się z `REPO_PATH` — inny niż
|
||
|
|
`deploy-local.sh` (który ma `cwd=services/control-plane`). Niezgodność project-name
|
||
|
|
→ state-divergence → Compose wyemitował `Recreate`, padł przy odtwarzaniu observera
|
||
|
|
(`No such container: <hash>_control-plane-observer`), `set -e` przerwał pętlę.
|
||
|
|
|
||
|
|
**Skutek**: observer, supervisor, executor i operator-ui zniknęły z VPS.
|
||
|
|
|
||
|
|
### Jak odtworzono mózg
|
||
|
|
|
||
|
|
```bash
|
||
|
|
ssh -t vps 'cd ~/homelab-codex-ws && git pull && \
|
||
|
|
cd services/control-plane && bash deploy-local.sh'
|
||
|
|
```
|
||
|
|
|
||
|
|
4 kontenery zbudowane i `Up (healthy)`. Fleet-prometheus deployowany potem punktowo
|
||
|
|
przez `ssh -t vps` + `deploy-node.sh` (z pominięciem zepsutej pętli).
|
||
|
|
|
||
|
|
### Dlaczego to krytyczne
|
||
|
|
|
||
|
|
Control-plane jest w `hosts/vps/services.yaml` jako zwykły serwis pętli, a ma własną
|
||
|
|
ścieżkę deploy (`deploy-local.sh`). Każdy `deploy.sh vps` rozkłada mózg.
|
||
|
|
Szczegóły w backlogu — pkt A.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Wnioski
|
||
|
|
|
||
|
|
- **Verify-before-fix zarobił trzykrotnie**: env-file leak złapany lekturą zanim wystawił
|
||
|
|
port; root-cause flaky testów inny niż pierwsza hipoteza (STATE_FILE, nie EVENTS_DIR);
|
||
|
|
fleet-prometheus wykazany jako nieistniejący przez panel mimo rejestracji.
|
||
|
|
- **`deploy.sh vps` = mina** dopóki control-plane jest w pętli serwisów. Krytyczny bug
|
||
|
|
(backlog A) — używać tylko `deploy.sh control-plane` / `deploy-local.sh` oddzielnie.
|
||
|
|
- **Ghost hash-prefixed kontenery** powodują fałszywy `System Status ERROR` w panelu
|
||
|
|
mimo zdrowego mózgu — inny objaw tego samego project-name divergence (backlog B).
|
||
|
|
- **Supervisor nie enqueue'uje remediacji** przy `error`-state — Action Queue pusta
|
||
|
|
(powtórka sygnału z 2026-06-19, backlog C).
|
||
|
|
- Etap 1 fleet-prometheus domknięty; następne etapy: targety `100.x` floty, reguły
|
||
|
|
liveness (`up==0 for: 5m`), brain-watchdog drugie wejście.
|