Commit Graph

5 Commits

Author SHA1 Message Date
Paul Payne
01819b2984 core: a login at the gateway, and container ports bound to one address
For services with no authentication of their own -- a trace viewer, an admin
UI, an OTLP receiver -- which must not be open to the LAN just because they run
here.

- `expose.http.basic_auth: {user, password_hash}` has the gateway ask for HTTP
  Basic auth (Caddy's `basic_auth`, bcrypt from `caddy hash-password`) before
  proxying, on the internal name and any public one. It is recorded in the
  registry too, so a Caddyfile generated from the registry alone still asks
  rather than serving the route open. Checked against caddy 2.11: 401 without
  credentials, through with them.
- A container's `ports` may give the host side an address, `4318:
  127.0.0.1:4318` -> `-p 127.0.0.1:4318:4318`. A bare port still publishes on
  every interface, as before, and the docs now say that this means the LAN.
2026-10-22 10:13:44 -07:00
Paul Payne
517471605a core: drop two manifest fields that were never wired up
`SystemdSpec.readiness` (ReadinessHttpGet) and `SystemdSpec.requires` were
parsed and validated but read nowhere — no generator, CLI or API touched
either. Both looked load-bearing and were not:

- readiness duplicated `expose.http.health_path`, which wildpc-api already
  polls. wild-life-api.yaml declared both spellings of the same /health
  probe; only one did anything.
- requires would mean systemd `Requires=`, a lifecycle binding (stop
  postgres, stop every dependent). `manage.systemd.after` already gives the
  ordering callers actually want, and a deployment's own `requires:` is the
  relationship model, not systemd wiring.

Unknown keys parse as ignored, so existing deployment YAML keeps loading.
2026-10-16 10:42:54 -07:00
Paul Payne
55c2f269ec core: GPU containers, bind sub-paths, and stop containers on unit stop
- container launcher: `gpus:` passes through as docker `--gpus`.
- requires: `path:` is appended to the bound URL, for consumers that want a
  sub-path as their base (e.g. an OpenAI-compatible server's /v1).
- container services now get `ExecStop=-docker stop wildpc-<name>`. SIGTERM
  only reached the `docker run` client, so a stop/restart left the container
  running unsupervised and holding its name, and the next start failed with
  a name conflict until systemd gave up.
2026-10-16 03:10:01 -07:00
Paul Payne
8a9843658c core: back off and give up on crash-looping services
Generated service units took systemd's default start limit (5 starts in
10s), which can never trip when each failed attempt outlives the window.
openclaw failed ~5s in and restarted every ~5.5s, so the counter reset on
every cycle: 260k restarts at ~7.4s CPU each, over a core burned
continuously for days, with the unit stuck in `activating (auto-restart)`
rather than anything a status check would flag.

Service units now get exponential restart backoff (RestartSteps=8,
RestartMaxDelaySec=300) and a start limit sized against it (10 starts per
hour, in [Unit] where systemd reads it). A broken service retries with a
growing delay for ~17min — wide enough to ride out a boot-time dependency
race — then lands in `failed` where it's visible and stops consuming CPU.
All four values are SystemdSpec fields, overridable per deployment.

Timer-driven oneshot jobs are unaffected; they never restart. systemd
older than 254 ignores RestartSteps/RestartMaxDelaySec with a warning and
keeps the flat RestartSec, so the start limit still applies there.
2026-08-24 09:24:16 -07:00
Paul Payne
05b28cb584 Rename Castle -> Wild PC across the repo
Repo-side rename only (Phases 1-3 of the migration plan); the live box
(~/.castle, systemd units, /data/castle, domains) is a separate cutover.

- Slug `castle` -> `wildpc`: CLI command, module names (wildpc_core/cli/api),
  dist names, entry point `wildpc = wildpc_cli.main:main`.
- Identifiers: CastleConfig/NATSClient/DirError/MDNS -> Wildpc*.
- Env/constants: CASTLE_* -> WILDPC_*; ~/.castle -> ~/.wildpc, castle.yaml ->
  wildpc.yaml, /data/castle -> /data/wildpc.
- Systemd UNIT_PREFIX castle- -> wildpc-; own programs castle-api/gateway/etc.
- Display prose "Castle" -> "Wild PC" in docs, agent-guide files, README, frontend.
- Package dirs and bootstrap yaml renamed via git mv; lockfiles regenerated;
  redundant nested uv.lock files dropped (workspace root lock is authoritative).

Tests: core 273, cli 47, wildpc-api 120 all pass. Frontend type-checks + builds.
Fixed a stale test fixture (secret_env_path kind arg) broken pre-rename.
2026-07-18 22:55:08 -07:00