73 lines
3.9 KiB
Markdown
73 lines
3.9 KiB
Markdown
---
|
|
id: "02-lifecycle"
|
|
title: "Kubernetes lifecycle and recovery"
|
|
status: completed
|
|
wave: 2
|
|
depends_on: ["01-backend-foundation"]
|
|
plan: "plan.md"
|
|
spec: "../../specs/kubernetes-executor/spec.md"
|
|
---
|
|
|
|
# Task 02: Kubernetes lifecycle and recovery
|
|
|
|
- **Acceptance:** CreateInstance provisions/verifies storage and Pod, injects
|
|
agentctl/config/auth through exec, binds a loopback forward, and completes the
|
|
existing health/nonce handshake.
|
|
- **Acceptance:** restart/reconnect verifies exact Pod/PVC UIDs and ownership
|
|
labels, rotates local forwarding, and surfaces deterministic remote status.
|
|
Exact-Pod reconnect is independent of the current profile row; replacement
|
|
of a missing retained Pod uses the recorded non-secret workload snapshot,
|
|
even after that profile is edited or deleted.
|
|
- **Acceptance:** ordinary stop preserves resources; terminal/forced cleanup is
|
|
idempotent, fails closed, and never deletes an existing claim.
|
|
- **Verification:** `cd apps/backend && go test -race ./internal/agent/runtime/lifecycle/...`
|
|
- **Files likely touched:** `apps/backend/internal/agent/runtime/lifecycle/executor_kubernetes*.go`,
|
|
`executor_backend.go`, `manager_launch.go`, liveness/status files, and adjacent tests.
|
|
- **Dependencies:** Task 01.
|
|
- **Parallelism:** parallel-safe with Tasks 03 and 04 after Task 01; owns
|
|
lifecycle files and metadata allowlists.
|
|
- **Inputs:** spec State machine/Persistence/Failure modes; ADR exact identity
|
|
rules; Docker and SSH reconnect/cleanup patterns.
|
|
|
|
## Results
|
|
|
|
Implemented the real Kubernetes lifecycle behind the existing
|
|
`ExecutorBackend` boundary. Fresh launch now composes and admission-validates
|
|
the exact Pod/PVC, persists provisional and admitted identities before later
|
|
fallible phases, materializes agentctl/auth/config/skills through exec, starts
|
|
a loopback-only WebSocket-primary/SPDY-fallback forward, and completes the
|
|
managed health/nonce handshake. The streaming transport honors Kubernetes REST
|
|
auth, proxy, TLS, and custom dial hooks; cancellation closes a blocked
|
|
handshake without coupling a successful upgraded stream to its deadline.
|
|
|
|
The live Kind launch also established the secret-store boundary used by that
|
|
bootstrap: lifecycle internals receive the raw store so private
|
|
`kandev-runtime:*` nonce/auth records can be materialized, while SSH, Sprites,
|
|
credential providers, and other user-visible consumers receive the filtered
|
|
`UserVisibleStore`. This keeps runtime-only records inaccessible through public
|
|
secret surfaces without blocking managed Kubernetes startup.
|
|
|
|
Reconnect, restart, active refresh, model switch, and sibling-session reuse use
|
|
the recorded six-field resource identity and immutable workload snapshot.
|
|
Exact UID/resource-version and complete ownership-label checks guard deletion.
|
|
Ordinary stop retains resources, terminal cleanup preserves durable inventory
|
|
when teardown fails, existing claims are never deleted, and restart recovery
|
|
can reconstruct cleanup without an in-memory execution.
|
|
|
|
Verification completed on 2026-08-24:
|
|
|
|
- `cd apps/backend && golangci-lint run ./...` passed with `0 issues` after
|
|
behavior-preserving complexity, duplication, nesting, constant, and test-file
|
|
refactors.
|
|
- `cd apps/backend && go test -race ./internal/agent/runtime/lifecycle/...`
|
|
passed (`lifecycle` 43.627 seconds; `lifecycle/skill` 1.052 seconds).
|
|
- `cd apps/backend && go test -race ./internal/agent/kubernetes -count=1`
|
|
passed, including blocked WebSocket/SPDY cancellation, post-upgrade survival,
|
|
REST custom-dial preservation, and cancellation/detach race coverage.
|
|
- `cd apps/backend && go test ./internal/orchestrator/...` and
|
|
`go test ./internal/backendapp -run 'Test.*Kubernetes' -count=1` passed.
|
|
- `cd apps/backend && go test ./internal/backendapp -run
|
|
'TestLifecycleSecretStoresSeparateRuntimeAndUserCredentialSecrets|Test.*Kubernetes'
|
|
-count=1` passed after the live Kind secret-store correction.
|
|
- `gofmt`, `go mod tidy -diff`, `go mod verify`, and `git diff --check` passed.
|