Commit Graph

8 Commits

Author SHA1 Message Date
Kavi d5508249f2 test: SHA normalization and registry-loader unit tests
Regression coverage for:
- Bug #3: sha256: prefix comparison — tests the stripSha helper and the
  imageMatch logic as used in verifyStatelessRecreated()
- Bug #7 / #6: registry file must exist and have all required fields;
  no app may use deploy_mode=webhook (webhook path retired)
  Run: REGISTRY_FILE=<path> node --test test/registry-loader.test.js

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 04:34:30 -04:00
Kavi 6a583a8572 fix(deploy): SHA normalization + kua-vault wrap in verifyStatelessRecreated; retire webhook mandatory check; add /api/v1/apps/registry endpoint
- verifyStatelessRecreated(): strip sha256: prefix before comparing image SHAs
  (same fix already applied to runtime-status in 2551af4, completeSelfRecreate
  in 06852c2; now consistent across all three verify paths)
- verifyStatelessRecreated(): add kua-vault wrap on compose images/ps calls
  (mirrors 2551af4 runtime-status fix; env interpolation was causing empty
  output for vault-injected apps, making the verify always fail with
  'no running container')
- start(): downgrade missing WEBHOOK_SECRET from fatal error to warning; the
  Forgejo webhook path is retired in favour of the admin API — handler stays
  but the startup guard no longer blocks kua-deploy from booting
- Add GET /api/v1/apps/registry so kua-mcp-core can fetch the full app list
  over HTTP without depending on a filesystem path inside its container

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 04:29:26 -04:00
claude-v2-deploy-coordination 58733939e2 fix(runtime-status): strip sha256: prefix in stale comparison (was always-stale false positive) 2026-05-21 22:36:21 -04:00
claude-v2-deploy-coordination 2551af4051 fix(runtime-status): kua-vault wrap on compose config/images/ps (was the real reason services list returned empty) 2026-05-21 22:07:01 -04:00
kua-deploy-split db647bcd0a fix(self-recreate): capture built image SHA via docker images tag, normalize SHA comparison
The prior expected_image_sha was captured via docker compose images, which returns the image of the existing (pre-recreate) container — not the freshly-built one. Switch to docker images ${project}-${service}:latest --quiet --no-trunc which returns the post-build image SHA. Also normalize sha256: prefix in completeSelfRecreate comparison so docker compose images output (sha256-prefixed) and docker inspect output (also sha256-prefixed) match cleanly.
2026-05-21 18:35:37 -04:00
kua-deploy-split 06852c227c feat: self-recreate handoff for kua-deploy + startup completeSelfRecreate()
When kua-deploy is recreating itself (target appName == kua-deploy on same host), the OLD process is about to be killed by the docker daemon mid-flight. Without a handoff, progress would be stuck at deploy:running forever and release-app would poll until timeout.

Self-recreate path: (1) pre-mark progress phase=self_recreate_pending with the freshly-built image SHA + deployStartTs + stateless services list; (2) fire-and-forget recreateService (do not await its return — the OLD process is dying anyway); (3) sleep 90s as a ceiling — if were still alive, recreate failed and we throw.

On startup, completeSelfRecreate() reads progress-kua-deploy.json; if phase is self_recreate_pending, queries its own container via docker inspect, compares running image SHA to the pre-recreate expected SHA, checks StartedAt > recreate_started_at + state=running, then writes phase=succeeded (or failed) plus a verify struct on the deploy step. Idempotent — no-op if no marker is found.
2026-05-21 18:31:45 -04:00
kua-deploy-split 9169c84381 feat: recreateService transient-container helper + use it in deploy() + rollback()
Replaces the runOnServer("docker compose up -d --force-recreate") pattern with a one-shot transient docker:cli container that runs OUTSIDE kua-deploy lifecycle. Solves the self-recreate chicken-and-egg: when the target is kua-deploy itself, the recreate completes because the transient survives kua-deploy stopping (docker daemon does the actual work).

Secrets are fetched via kua-vault export, written to a 600-perm tempfile on /app/data, passed via --env-file (docker CLI reads it from kua-deploys perspective; never on the docker run command line). Tempfile is unlinked in finally{}.

Replaces: deploy() stateless recreate (force=true), deploy() stateful up (force=false), rollback() recreate (force=true with all-services svcList).

Build step keeps runOnServer (local exec on bruno) since build doesnt kill kua-deploy. envPrefix/kvPrefix vars retained for the build command.
2026-05-21 18:24:13 -04:00
kua-deploy-split 26804c692e feat: initial commit — extracted from coder-core/services/kua-deploy
Split rationale: kua-deploy used to be a service in coder-core/services/kua-services/docker-compose.yml, which meant every release-app coder-core rebuilt+force-recreated kua-deploy as a side-effect. The recreate-self path is structurally racy (the compose-up process is killed mid-flight when its own container stops), causing silent false-success deploys.

This split makes kua-deploy its own deploy unit (own repo, own compose project, own release-app entry), so coder-core releases no longer touch it. Phase A (transient-container recreateService pattern) will follow to make deliberate kua-deploy self-updates also reliable.

Handoff: v2-deploy-coordination -> kua-deploy-split (.sessions.md 2026-05-21 21:35).
2026-05-21 18:04:45 -04:00