151 lines
6.8 KiB
Markdown
151 lines
6.8 KiB
Markdown
---
|
|
id: "03-docker-lifecycle"
|
|
title: "Real Kubernetes Docker lifecycle tests"
|
|
status: completed
|
|
wave: 3
|
|
depends_on:
|
|
- "02-full-worker-image"
|
|
plan: "plan.md"
|
|
requirements:
|
|
- REQ-EXECUTORS-K8S-DOCKER-001
|
|
- REQ-EXECUTORS-K8S-DOCKER-002
|
|
- REQ-EXECUTORS-K8S-DOCKER-003
|
|
acceptance_criteria:
|
|
- AC-EXECUTORS-K8S-DOCKER-001.3
|
|
- AC-EXECUTORS-K8S-DOCKER-001.4
|
|
- AC-EXECUTORS-K8S-DOCKER-002.2
|
|
- AC-EXECUTORS-K8S-DOCKER-002.3
|
|
- AC-EXECUTORS-K8S-DOCKER-002.4
|
|
- AC-EXECUTORS-K8S-DOCKER-003.1
|
|
- AC-EXECUTORS-K8S-DOCKER-003.2
|
|
- AC-EXECUTORS-K8S-DOCKER-003.3
|
|
- AC-EXECUTORS-K8S-DOCKER-003.4
|
|
system_design:
|
|
- ../../specs/executors/system-design/kubernetes-docker-workloads.md
|
|
---
|
|
|
|
# Task 03: Real Kubernetes Docker lifecycle tests
|
|
|
|
## Summary
|
|
|
|
Exercise the new template and full worker through the existing Kind-backed
|
|
Kandev fixture. Verify the actual agent workspace, Docker filesystem behavior,
|
|
visible results and resource lifecycle before staging a production rollout.
|
|
|
|
## In scope
|
|
|
|
- New `kubernetes-docker-workloads.spec.ts` in the `containers` project; reuse
|
|
existing fixture ownership, pinned Kubernetes tools and mock-agent transport.
|
|
- Load exact task 02 image inputs into the disposable Kind node. Use only a
|
|
bounded test host selected in task 02, never the production cluster/context.
|
|
- Real API-defaulted mount grants, daemon readiness failure, actual source and
|
|
Docker smoke, Compose bind writes visible in the Kandev terminal/diff.
|
|
- Ordinary Stop retains Pod/PVC/daemon; Resume retains result and uncommitted
|
|
edit. Lost-Pod replacement uses the original snapshot and PVC after a profile
|
|
edit, while Docker caches/test containers are disposable.
|
|
- Two test Pods have independent daemons; API inventory counts one Pod each.
|
|
Record nested process cgroup ancestry/counters and bounded CPU/memory load.
|
|
- Terminal cleanup removes exact owned resources and nested compute; an
|
|
operator-owned existing claim is untouched. Persist sanitized evidence.
|
|
- Update E2E documentation and any duration/shard catalog required by the
|
|
existing runner, without widening worker concurrency.
|
|
|
|
## Out of scope
|
|
|
|
Production credentials, new production control plane, deployment,
|
|
full-suite execution, UI layout changes or full Docker plugin compatibility.
|
|
|
|
## Acceptance
|
|
|
|
1. Source, Chromium, Docker build/run and Compose tests execute, with actual
|
|
workspace read/write assertions and Kandev-visible results.
|
|
2. Daemon failure is finite and visible; Stop/Resume/replacement and destructive
|
|
cleanup obey the selected persistence model with no foreign resource deletion.
|
|
3. Recorded evidence proves daemon separation and nested resource accounting
|
|
for the tested runtime; limitations remain explicit for untested runtimes.
|
|
|
|
## Verification
|
|
|
|
Run from the repository root. These are new tests; first add failing cases,
|
|
then make the selected flow pass. Do not run against an active production instance.
|
|
|
|
```bash
|
|
(cd apps && pnpm install --frozen-lockfile)
|
|
(cd apps/web && KANDEV_E2E_CONTAINERS=1 pnpm e2e:run --host --shards 1 --project containers tests/kubernetes/kubernetes-docker-workloads.spec.ts)
|
|
(cd apps/backend && GOMAXPROCS=2 go test -p 1 ./internal/agent/kubernetes ./internal/agent/runtime/lifecycle -count=1)
|
|
git diff --check
|
|
```
|
|
|
|
Name the browser cases `full worker returns source and Docker results`,
|
|
`unavailable daemon fails preparation`, `resume and replacement retain workspace`,
|
|
and `isolated daemons clean up with owned Pods`. Keep each independently
|
|
reclaimable on assertion failure. The first case runs the new
|
|
`k8s/worker-images/full/smoke.sh --all` inside the agent container.
|
|
Attach exact fixture/runtime/image versions and command results to Results.
|
|
|
|
## Files likely touched
|
|
|
|
- `apps/web/e2e/tests/kubernetes/kubernetes-docker-workloads.spec.ts` (new)
|
|
- `apps/web/e2e/fixtures/kubernetes-worker-images.ts`
|
|
- `apps/web/e2e/fixtures/kubernetes-test-base.ts`, only needed shared fixture hooks
|
|
- `apps/web/e2e/README.md` and applicable runner catalog
|
|
- `k8s/worker-images/full/` for defects proven by these cases
|
|
|
|
## Dependencies
|
|
|
|
Tasks 01 and 02.
|
|
|
|
## Risks
|
|
|
|
Privileged nested Docker can behave differently under Kind's outer container
|
|
and other runtimes. Kind evidence does not establish production compatibility. Agent-only temp/HOME binds
|
|
are outside the shared workspace; tests must not conceal incompatible paths.
|
|
|
|
## Parallelism
|
|
|
|
`sequential`
|
|
|
|
## Inputs
|
|
|
|
- [System design](../../specs/executors/system-design/kubernetes-docker-workloads.md), Lifecycle and evidence.
|
|
- Existing `kubernetes-executor.spec.ts`, `kubernetes-worker-presets.spec.ts`,
|
|
`kubernetes-test-base.ts` and the E2E skill/README.
|
|
|
|
## Results
|
|
|
|
All four opt-in browser cases passed on Linux/amd64 with Kind v0.32.0,
|
|
Kubernetes v1.36.1 and Docker 29.1.5. The focused run used one worker and
|
|
completed in 3.3 minutes:
|
|
|
|
- `full worker returns source and Docker results` passed in 44.4 seconds,
|
|
including source builds/tests, Chromium, an image build/run, HTTPS transfer,
|
|
Compose RO/RW binds and Kandev-visible workspace output.
|
|
- `unavailable daemon fails preparation` passed in 5.1 seconds with a finite,
|
|
visible preparation failure and no agent start.
|
|
- `resume and replacement retain workspace` passed in 14.4 seconds, preserving
|
|
the result through Stop/Resume and a lost-Pod replacement while discarding
|
|
daemon state.
|
|
- `isolated daemons clean up with owned Pods` passed in 20.0 seconds, proving
|
|
distinct daemon identities, nested cgroup ancestry/counter movement, one Pod
|
|
per session and exact cleanup without deleting the existing claim fixture.
|
|
|
|
The exact implementation revision was exercised with image config digest
|
|
`sha256:101d44047de5238b7846295a2e175c162c79328b42db9a2693d568a9ac59a0f6`.
|
|
Required Kubernetes and lifecycle Go packages, changed-file ESLint and test
|
|
discovery also passed. This evidence applies to the recorded Kind/runtime
|
|
combination; other container runtimes still require their own cgroup validation.
|
|
|
|
A later Kubernetes acceptance run exposed two retained-workspace portability
|
|
gaps. A non-root workload could copy a checkout onto a group-writable,
|
|
root-owned PVC and then fail when `cp -a` restored metadata on the mount root.
|
|
The preparation scripts now copy checkout contents recursively without
|
|
restoring source ownership or timestamps. The same run also showed that a
|
|
credential-free GitHub HTTPS origin and the equivalent GitHub SSH origin were
|
|
compared literally during lost-Pod replacement. Preparation now normalizes
|
|
those GitHub URL forms before comparison while continuing to reject a different
|
|
repository. Runtime resolution upgrades exact persisted copies of the two
|
|
Kandev-supplied scripts; any customized script remains byte-for-byte unchanged.
|
|
Focused lifecycle regressions exercise both the built-in Kubernetes script and
|
|
the full worker script, preserve retained files, and reproduce the restricted
|
|
copy boundary with the real `cp` implementation.
|