Commit graph

24 commits

Author SHA1 Message Date
oskar da151fc8d3 fix(control-plane): redeploy wykonywalny — dispatch do host-side deploy-runnera
Executor odpalal scripts/deploy/deploy-node.sh <node> <service> wewnatrz
swojego kontenera: skrypt ignoruje oba argumenty i wymaga repo w
${HOME}/homelab-codex-ws (w kontenerze HOME=/home/homelab) -> exit 1 w 18.
linii. Za tym brak git, brak klienta docker w obrazie, a gdyby przeszedl —
deploy calego zestawu uslug hosta executora zamiast wezla z akcji. Kazdy
redeploy padal (recon D14/D15; 18 pending / 0 completed).

Redeploy idzie teraz ta sama sciezka pull co container_restart — VPS nigdy
nie inicjuje polaczenia do wezla:
  executor -> actions/deploy/<node>/<id>.json
  -> deploy-runner (systemd na hoscie) rsync-pull, walidacja, deploy
  -> action_result event -> executor rozlicza completed/failed

- scripts/deploy/deploy-service.sh: deploy jednej uslugi, wspoldzielony z
  deploy-node.sh, wiec inwokacja compose (a przez to nazwa projektu) jest
  identyczna jak przy deployu recznym
- jobs/deploy-runner/: host-level, nie kontener — compose rozwiazuje
  wzgledne bindy i nazwe projektu tak jak przy deployu czlowieka;
  niezalezny od node-agenta, wiec potrafi zredeployowac takze jego
- walidacja: tylko typ redeploy, node musi sie zgadzac, usluga musi byc w
  hosts/<node>/services.yaml, zadna tresc z payloadu nie trafia do shella
- --force-recreate bez --build i bez --remove-orphans: redeploy to
  rekoncyliacja, nie wysylka kodu
- executor: REDEPLOY_TIMEOUT_SECS=900, /repo zjechany do :ro (nieuzywany)

248 testow zielonych; deploy-node.sh przecwiczony na atrapie dockera —
argv compose bez zmian. Instalacja unitow na wezlach i E2E: backlog.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 18:26:30 +02:00
oskar e67868f5da chore(deploy): remove dead deploy-role.sh
The script composes from roles/$ROLE/compose/docker-compose.yml, but no
roles/ directory exists anywhere in the repo (recon B7) and nothing
references the script. Dead since the roles concept was abandoned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 19:15:55 +02:00
oskar b2379e3275 feat(kb): add kb-query service skeleton (search API, no ingress yet)
Module 5 phase 4 step 1 (docs/kb/modules/05-faza4-plan.md, §4): first
user-facing HTTP entry point to the KB. FastAPI wrapping
kb_retrieval.cascade_query/flat_query — GET /search (query_text -> embed via
Ollama@SOLARIA -> cascade/flat -> envelope join -> JSON with per-source
links) and GET /healthz. Search API only, no answer synthesis (phase 5) and
no server-side dist filtering — the 0.45/0.55 colour thresholds are a
frontend concern (plan §7, a later step).

Hard startup invariant (plan §2 decision 2): refuses to start unless the
configured EMBED_MODEL is present in both document_chunk.model and
document_summary.embedding_model. Note the latter: document_summary.model is
the LLM that *wrote* the summary (claude-haiku-4-5/gemma3:12b), not the
embedder — checked live against kb-postgres@PIHA before writing this, see
app/startup.py's docstring. Verified end-to-end with a live docker run: the
invariant crash-loops on a mismatched EMBED_MODEL and passes through to a
real /search hit against the live corpus with a correct model.

Repo-only: no deploy, no npm/OIDC/DNS wiring (plan §8, later step), no local
embed fallback (plan §5, later step) — Ollama@SOLARIA is called directly and
a failure surfaces as 503, not a crash.

Also: scripts/deploy/deploy.sh's gate now builds each service via
`docker compose build` instead of a raw `docker build <svc_dir>`, so a
service whose docker-compose.yml declares a repo-root build context (needed
here to COPY packages/kb-retrieval/, the packages/ Dockerfile convention
already documented in CLAUDE.md) resolves the same way in the gate as it
does at real deploy time (deploy-node.sh's `docker compose ... up --build`).
No behavior change for existing single-context services — verified against
llm-gateway's compose file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-22 16:06:18 +02:00
oskar 77defffc47 fix(deploy-node): warunkowy --build gdy serwis ma Dockerfile — kod nie wchodził bez rebuildu (c858dbc) 2026-07-16 15:05:19 +02:00
Oskar Kapala 3b71707660 fix(deploy): exclude control-plane from node deploy loop — prevents brain teardown via project-name divergence
deploy.sh vps iterates hosts/vps/services.yaml in deploy-node.sh, which
includes control-plane. But control-plane also has a dedicated deploy path
(deploy.sh control-plane → deploy-control-plane.sh → deploy-local.sh) that
runs compose from services/control-plane/. The node loop runs compose from
${REPO_PATH}, so on Compose versions that derive the project name from cwd
the two paths own the containers under different project names. The loop's
`up -d --remove-orphans` then Recreates and tears down the running brain
(observer/supervisor/executor/ui), aborting the loop under set -e. This
wiped the VPS control-plane on 2026-06-25.

Generic guard: skip any service that ships its own services/<svc>/deploy-local.sh.
control-plane stays in services.yaml so the gate (pytest+build) still covers it;
only the destructive loop deploy is skipped. Protects future services with a
dedicated deploy path too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 15:16:42 +02:00
oskar 686aca7060 fix(deploy-node): pass --env-file per-service so env-interpolated binds resolve (fleet-prometheus 0.0.0.0 leak)
Without --env-file, docker compose resolved variables from the repo root
(cwd), not from services/<service>/.env where the file actually lives.
This caused ${TAILSCALE_BIND_IP} to expand to empty string, binding
fleet-prometheus on 0.0.0.0:9090 instead of the Tailscale-only IP —
a security hole on the public VPS.

Guard mirrors the existing override-file pattern: only add --env-file
when the file exists, so services without .env continue to work as
before. Flag is injected into COMPOSE_CMD (before the `up` subcommand)
so docker compose sees it as a global option.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 13:41:55 +02:00
oskar ae739b5037 fix(deploy-node): resolve HOST_DIR via os_hostname lookup, not bare hostname
Replaces the brittle `hosts/$(hostname|lower)` assumption with a scan
of hosts/*/host.yaml for a matching os_hostname field. This fixes VPS
where the OS hostname (ubuntu-4gb-hel1-1) never matched the repo
directory (hosts/vps/), causing a silent "No services found" false-green.

Fallback to lowercase-hostname dir preserved for nodes that haven't yet
received the os_hostname field; exits 1 with a clear message if neither
match nor fallback directory exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 22:24:40 +02:00
Oskar Kapala db592fbc28 feat(deploy): Saturn-side dispatcher wrapper
Replaces the per-node staged framework with a single entry point that
runs from SATURN: preflight (branch/clean-tree/push/SSH), gate (pytest +
docker build per service), execute (control-plane.sh --ssh or remote
deploy-node.sh), verify (docker ps), and one-line report.

Exit codes: 0=ok 1=preflight 2=gate 3=execute 4=verify 5=sudo-handoff.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 16:06:36 +02:00
oskar beb8b5cbaa fix: remove --pull always flag incompatible with docker-compose v1 2026-05-21 22:07:49 +02:00
oskar 898deda05f fix: deploy-frigate.sh use docker-compose v1 for chelsty-infra 2026-05-21 22:05:43 +02:00
oskar f34399a30d feat: add Frigate NVR deployment for chelsty-infra
VAAPI decode via Intel UHD 630, CPU detection, 2x Reolink RLC-540
placeholders. MQTT to local mosquitto (127.0.0.1), 7-day recording
retention. Secrets in /opt/homelab/config/frigate/frigate.env on node.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:19:45 +02:00
oskar b02c8bb50e fix(deploy): inventory-aware orchestration and correct override paths
- orchestrate-deploy.sh: read nodes from inventory/topology.yaml instead of hardcoded list
- orchestrate-deploy.sh: LTE nodes (chelsty-infra, chelsty-ha) use ConnectTimeout=30, non-fatal on failure
- deploy-node.sh: service discovery falls back to services.yaml if no services.txt
- deploy-node.sh: override path corrected to hosts/<node>/runtime/<service>/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 14:50:01 +02:00
oskar f65698925e Fix control plane SSH deploy TTY 2026-05-18 21:41:47 +02:00
oskar 9f20dcae05 Add control plane deploy script and fix UI healthcheck 2026-05-18 21:34:57 +02:00
oskar c299a2cb85 Fix agent fleet verification via Redis container 2026-05-17 23:00:51 +02:00
oskar b129f03837 Fix stability agent fleet deploy scripts 2026-05-17 21:09:06 +02:00
oskar b7faac00c5 Add executable stability agent fleet deploy scripts 2026-05-17 17:32:10 +02:00
oskar c9ddfa9ac1 Roll out stability agent to homelab nodes 2026-05-17 15:54:19 +02:00
Oskar Kapala 431d777989 Implement filesystem-first runtime event system 2026-05-12 13:38:25 +02:00
Oskar Kapala b524a3886a Harden deployment runtime framework 2026-05-11 21:20:13 +02:00
Oskar Kapala 5947ddd03d Implement staged deployment runtime 2026-05-11 21:04:24 +02:00
Oskar Kapala bbdbdb8321 Add node capability model 2026-05-11 20:46:50 +02:00
Oskar Kapala d0540f7eb8 Add infrastructure standards and deployment conventions 2026-05-07 21:16:03 +02:00
Oskar Kapala 2b5d59ae27 Initial homelab workspace structure 2026-05-07 20:17:27 +02:00