Skip to content

feat: add ability to configure custom init containers in DevWorkspace pods - #19

Open
akurinnoy wants to merge 13 commits into
mainfrom
task-T7-wave-3
Open

feat: add ability to configure custom init containers in DevWorkspace pods#19
akurinnoy wants to merge 13 commits into
mainfrom
task-T7-wave-3

Conversation

@akurinnoy

Copy link
Copy Markdown
Owner

Summary

This PR adds the ability for platform administrators to configure custom init containers in DevWorkspace pods via the DevWorkspaceOperatorConfig (DWOC) API.

DWOC API Field

The new field config.workspace.initContainers accepts a list of Kubernetes corev1.Container objects. These containers are injected into every DevWorkspace pod managed by the operator, allowing cluster administrators to define custom initialization logic.

init-persistent-home Override Behavior

When a container named init-persistent-home is specified in config.workspace.initContainers, the operator:

  1. Does not automatically add its default init-persistent-home container (which sets up the persistent home volume).
  2. Instead, uses the user-provided container as the home initialization container.
  3. Automatically injects the required persistent-home volume mount into the container.

This allows full customization of the home initialization script (e.g., custom chown commands, pre-population of files, etc.) while preserving the volume wiring.

Validation Error Message

If a container named init-persistent-home is configured with a command other than [/bin/sh, -c], the operator returns a validation error:

init container named 'init-persistent-home' must use command [/bin/sh -c]; got [<actual-command>]

This ensures the container can execute the persistent-home shell script correctly.

Backward Compatibility Guarantee

  • Existing DWOC configurations without initContainers continue to work unchanged — the default init-persistent-home container is added automatically.
  • Existing DevWorkspaces that do not use a DWOC are unaffected.
  • The disableInitContainer flag in PersistUserHome continues to suppress the default init container when set to true, even if DWOC initContainers includes an init-persistent-home container.

Changes

  • controllers/workspace/devworkspace_controller.go — Integrates DWOC initContainers into the reconcile loop with nil-guard for PersistUserHome
  • pkg/library/home/persistentHome.go — Implements EnsureHomeInitContainerFields (validation + volume mount injection) and updates AddPersistentHomeVolume to handle DWOC init container override
  • pkg/library/initcontainers/merge.goMergeInitContainers function merges DWOC-defined containers with operator-generated containers
  • Tests for all new code paths with fixture YAML files

Test plan

  • go build ./... — full repo compiles without errors
  • go test ./pkg/library/home/... ./pkg/library/initcontainers/... — all target tests pass
  • go vet ./... — zero vet issues

Closes CRW-9373, CRW-9367

akurinnoy and others added 13 commits June 29, 2026 16:31
Adds a new 'DWOC init containers' Context block to devworkspace_controller_test.go
with three It() cases: basic custom init injection, init-persistent-home override
when persistent home is enabled, and skipping init-persistent-home when disabled.
Adds a minimal supporting fixture YAML for the new tests.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
The comment claimed the default init container was skipped when custom
init containers were present, but the code only checks DisableInitContainer.
Update the comment to accurately reflect the actual condition.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…itContainerFields

- Add isValidInitPersistentHomeCommand helper that returns true only when
  cmd equals ["/bin/sh", "-c"]
- Fix EnsureHomeInitContainerFields to validate non-empty Command via
  isValidInitPersistentHomeCommand, returning an error for invalid commands
- Fix EnsureHomeInitContainerFields to use append-if-absent pattern for
  VolumeMounts instead of replacing the entire slice, preserving
  pre-existing mounts with other names

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ner in reconcile loop

Add nil check for workspace.Config.Workspace.PersistUserHome before calling
pointer.BoolDeref on PersistUserHome.DisableInitContainer to prevent a nil
pointer panic when PersistUserHome is not configured. Default disableHomeInit
to constants.DefaultDisableHomeInitContainer and only override inside the
nil-guarded block.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Add 4 new test cases to TestMergeInitContainers covering:
- nil base returns patches as result (no panic)
- patch overrides image while preserving args (strategic merge)
- new-named patch containers appended after base containers in patch order
- mixed case: base [A,B] + patches [B-override,C] = [A,B-merged,C]

Total test count: 9 (5 existing + 4 new). All pass with go vet clean.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ontainersFullFlow

Implements table-driven tests for EnsureHomeInitContainerFields covering:
- valid command [/bin/sh, -c]: no error, volumeMount added
- invalid command [/bin/bash, -c]: returns error with exact message
- empty command: set to [/bin/sh, -c], volumeMount added
- idempotency test: container with existing persistent-home AND my-secret
  VolumeMount — asserts no duplicate persistent-home AND my-secret preserved

Also implements TestDWOCMultipleInitContainersFullFlow which constructs a
DevWorkspaceWithConfig with multiple DWOC initContainers (one
init-persistent-home override + one extra-init), calls MergeInitContainers
and EnsureHomeInitContainerFields, and verifies correct ordering, persistent-home
VolumeMount presence, and custom container preservation.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Add three new fixture files for TestPersistentHomeVolume covering:
- DWOC with init-persistent-home initContainers (non-ephemeral, default init added)
- Ephemeral workspace with init-persistent-home in DWOC (NeedsPersistentHomeDirectory=true)
- No DWOC initContainers (backward compat, default stow behavior preserved)

Test count increases from 12 to 15.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
… pods

Implements the ability for platform administrators to configure custom
init containers via the DevWorkspaceOperatorConfig (DWOC) API field
config.workspace.initContainers. This allows clusters to define
additional initialization steps that run before workspace containers
start.

Key changes:
- DWOC initContainers field integration in the reconcile loop
- EnsureHomeInitContainerFields validates and injects persistent-home
  volume mount into user-configured init containers that use the
  init-persistent-home name, requiring the [/bin/sh -c] command format
- MergeInitContainers merges DWOC-defined init containers with
  operator-generated init containers, with DWOC entries taking priority
- Backward compatibility: existing workspaces without DWOC initContainers
  continue to receive the default init-persistent-home container
- Validation error: if a container named init-persistent-home uses a
  command other than [/bin/sh, -c], an error is returned with a clear
  message indicating the required format
- init-persistent-home override: if the DWOC defines a container with
  this name, the default operator container is NOT added automatically,
  allowing full customization of the home initialization script

Closes CRW-9373, CRW-9367
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant