Adds the velero CLI to the pinned dev toolbox so operators can run velero backup describe/logs/get through ./infra/devcontainer/dev.sh run .... Before this change, command -v velero in the toolbox found nothing (measured 2026-11-07).
Changes
infra/devcontainer/versions.env: VELERO_VERSION=1.18.2. Lockstep with the server. The CLI and server are version-coupled. I checked the live version read-only: kubectl --context k3s-prod -n velero get deploy velero shows docker.io/velero/velero:v1.18.2, and HelmRelease velero is at chart 12.2.3. The pin has no renovate marker on purpose: bump it in the same PR as any velero chart bump that moves the appVersion, never on its own.
infra/devcontainer/Containerfile: release tarball from vmware-tanzu/velero (same style as flux/helm; no checksum, like every other tool in this file), recorded in /etc/dev-toolchain-versions. In the verify stage, velero is added to the PATH loop and check velero v${VELERO_VERSION} asserts the output of velero version --client-only.
infra/devcontainer/build-image.sh: VELERO_VERSION added to BUILD_ARGS. CI picks it up generically through --print-build-args.
README tool table, plus a short read-only CLI example in runbooks/backup-failure.md.
Sensitive paths: none touched. No .gitea/**, no ci/**.
Verification
Local image build:IMAGE=localhost/home-k3s-dev:velero-wt ./build-image.sh returned rc 0. The verify stage printed ok velero and ok velero v1.18.2, then TOOLBOX VERIFIED. The image was not pushed.
Read-only prod smoke test with that image:velero version shows Client v1.18.2 and Server v1.18.2. velero backup get lists the daily backups, all Completed with 0 errors.
Toolbox gate (worktree, DEV_KUBECONFIG=/dev/null, ENGINE shim mounting .git and the spec repo with SPEC_REPO), HEAD 60e3a24: rc 3 (UNDETERMINED).
Did not run: gitea-settings (no SETTINGS_API_TOKEN, expected locally).
conformance (L2/L3) is SKIPPED because CLUSTER_AVAILABLE is unset, which is expected.
Found while testing (report only, not fixed)
Every daily backup since velero-daily-20261031030050 has 1 warning: gitea-actions: /pods act-runner-5944dfdfb8-69bvq — Skip pod volume data error: pod is not in the expected status ... phase=Failed: pod is not running. gitea-actions holds 11 Evicted (Failed) pods from the old ReplicaSet act-runner-5944dfdfb8, ten of them from 2026-10-30T08:26Z. Removing them is an operator action.
Adds the `velero` CLI to the pinned dev toolbox so operators can run `velero backup describe/logs/get` through `./infra/devcontainer/dev.sh run ...`. Before this change, `command -v velero` in the toolbox found nothing (measured 2026-11-07).
## Changes
- `infra/devcontainer/versions.env`: `VELERO_VERSION=1.18.2`. **Lockstep with the server.** The CLI and server are version-coupled. I checked the live version read-only: `kubectl --context k3s-prod -n velero get deploy velero` shows `docker.io/velero/velero:v1.18.2`, and HelmRelease velero is at chart `12.2.3`. The pin has **no renovate marker on purpose**: bump it in the same PR as any `velero` chart bump that moves the appVersion, never on its own.
- `infra/devcontainer/Containerfile`: release tarball from vmware-tanzu/velero (same style as flux/helm; no checksum, like every other tool in this file), recorded in `/etc/dev-toolchain-versions`. In the verify stage, `velero` is added to the PATH loop and `check velero v${VELERO_VERSION}` asserts the output of `velero version --client-only`.
- `infra/devcontainer/build-image.sh`: `VELERO_VERSION` added to `BUILD_ARGS`. CI picks it up generically through `--print-build-args`.
- README tool table, plus a short read-only CLI example in `runbooks/backup-failure.md`.
- Handoff: `decisions/2026-11-07-devcontainer-velero-cli.md`.
**Sensitive paths: none touched.** No `.gitea/**`, no `ci/**`.
## Verification
- **Local image build:** `IMAGE=localhost/home-k3s-dev:velero-wt ./build-image.sh` returned rc 0. The verify stage printed `ok velero` and `ok velero v1.18.2`, then `TOOLBOX VERIFIED`. The image was not pushed.
- **Read-only prod smoke test with that image:** `velero version` shows Client v1.18.2 and Server v1.18.2. `velero backup get` lists the daily backups, all Completed with 0 errors.
- **Toolbox gate** (worktree, `DEV_KUBECONFIG=/dev/null`, ENGINE shim mounting `.git` and the spec repo with `SPEC_REPO`), HEAD 60e3a24: **rc 3 (UNDETERMINED)**.
- Passed: spec-immutability, lint, l0, l1, render-golden, decisions-log, approval-policy.
- Did not run: `gitea-settings` (no `SETTINGS_API_TOKEN`, expected locally).
- `conformance` (L2/L3) is SKIPPED because `CLUSTER_AVAILABLE` is unset, which is expected.
## Found while testing (report only, not fixed)
Every daily backup since `velero-daily-20261031030050` has **1 warning**:
`gitea-actions: /pods act-runner-5944dfdfb8-69bvq — Skip pod volume data error: pod is not in the expected status ... phase=Failed: pod is not running`.
`gitea-actions` holds 11 Evicted (`Failed`) pods from the old ReplicaSet `act-runner-5944dfdfb8`, ten of them from 2026-10-30T08:26Z. Removing them is an operator action.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The velero CLI and server are version-coupled, so VELERO_VERSION follows the
server running on prod (docker.io/velero/velero:v1.18.2, chart 12.2.3,
verified 2026-11-07). It has no renovate marker on purpose: bump it together
with the chart's appVersion. The verify stage asserts that
`velero version --client-only` reports the pin. The build arg reaches CI
through build-image.sh --print-build-args, so no .gitea/ or ci/ change is
needed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Adds the
veleroCLI to the pinned dev toolbox so operators can runvelero backup describe/logs/getthrough./infra/devcontainer/dev.sh run .... Before this change,command -v veleroin the toolbox found nothing (measured 2026-11-07).Changes
infra/devcontainer/versions.env:VELERO_VERSION=1.18.2. Lockstep with the server. The CLI and server are version-coupled. I checked the live version read-only:kubectl --context k3s-prod -n velero get deploy veleroshowsdocker.io/velero/velero:v1.18.2, and HelmRelease velero is at chart12.2.3. The pin has no renovate marker on purpose: bump it in the same PR as anyvelerochart bump that moves the appVersion, never on its own.infra/devcontainer/Containerfile: release tarball from vmware-tanzu/velero (same style as flux/helm; no checksum, like every other tool in this file), recorded in/etc/dev-toolchain-versions. In the verify stage,velerois added to the PATH loop andcheck velero v${VELERO_VERSION}asserts the output ofvelero version --client-only.infra/devcontainer/build-image.sh:VELERO_VERSIONadded toBUILD_ARGS. CI picks it up generically through--print-build-args.runbooks/backup-failure.md.decisions/2026-11-07-devcontainer-velero-cli.md.Sensitive paths: none touched. No
.gitea/**, noci/**.Verification
IMAGE=localhost/home-k3s-dev:velero-wt ./build-image.shreturned rc 0. The verify stage printedok veleroandok velero v1.18.2, thenTOOLBOX VERIFIED. The image was not pushed.velero versionshows Client v1.18.2 and Server v1.18.2.velero backup getlists the daily backups, all Completed with 0 errors.DEV_KUBECONFIG=/dev/null, ENGINE shim mounting.gitand the spec repo withSPEC_REPO), HEAD60e3a24: rc 3 (UNDETERMINED).gitea-settings(noSETTINGS_API_TOKEN, expected locally).conformance(L2/L3) is SKIPPED becauseCLUSTER_AVAILABLEis unset, which is expected.Found while testing (report only, not fixed)
Every daily backup since
velero-daily-20261031030050has 1 warning:gitea-actions: /pods act-runner-5944dfdfb8-69bvq — Skip pod volume data error: pod is not in the expected status ... phase=Failed: pod is not running.gitea-actionsholds 11 Evicted (Failed) pods from the old ReplicaSetact-runner-5944dfdfb8, ten of them from 2026-10-30T08:26Z. Removing them is an operator action.🤖 Generated with Claude Code