Skip to content

feat(kubelet): preStop hook, exec v5 protocol, init container statuses, EmptyDir test#47

Open
indyjonesnl wants to merge 3 commits into
calfonso:mainfrom
indyjonesnl:upstream/kubelet-improvements
Open

feat(kubelet): preStop hook, exec v5 protocol, init container statuses, EmptyDir test#47
indyjonesnl wants to merge 3 commits into
calfonso:mainfrom
indyjonesnl:upstream/kubelet-improvements

Conversation

@indyjonesnl
Copy link
Copy Markdown

Changes

Three kubelet behavior fixes + one regression test.

`feat(kubelet): preStop hook, accurate exit status, WebSocket exec v5`

  • preStop lifecycle hook: HTTP and Exec preStop hooks now run before container termination. Pod `terminationGracePeriodSeconds` bounds the total wait; if the preStop exceeds it, the container is force-killed.
  • Accurate exit status: container statuses now report the real exit code from runtime introspection instead of always reporting 0 on graceful termination.
  • WebSocket exec v5: `exec` upgrades that negotiate v5 of the streaming protocol get the v5 framing (stdin/stdout/stderr/error multiplexed on a single channel) so newer kubectl versions don't downgrade or fail.

`fix(kubelet): publish init container status transitions to storage`

Init containers ran but their `initContainerStatuses` were only updated at terminal transitions, breaking watchers observing the initialization progress (and the `PodInitialized` condition that depends on it). Publish status on every state change (Waiting → Running → Terminated) like regular containers.

`test(kubelet): pin EmptyDir mode 0o777 chmod path against regression`

Regression test that asserts `EmptyDir` volumes are `chmod 0o777` after creation (matching the kubelet contract for shared writability). This caught a recent refactor that dropped the chmod.

Verification

`cargo build --workspace --locked` clean. Depends on #32 for green CI.

Note

The companion `fix(kubelet): preserve pod status fields` commit shipped with this work locally but depends on a helper (`pod_status_equal`) introduced in the idempotency batch — that pair is sent in a separate PR alongside the other no-op-status-write fixes.

indyjonesnl and others added 3 commits May 14, 2026 18:27
EmptyDir conformance tests [Conformance].*EmptyDir.*(mode|0644|0666|0777)
rely on the volume directory being mode 0o777 on the host. The
chmod was already in create_volume but inlined and untested, so a
silent regression would only surface during a full conformance run.

- Extract the create_dir_all + chmod 0o777 path into a pure
  setup_emptydir_dir helper, idempotent for stale dirs.
- Add four unit tests covering new dir, stale-perms re-chmod,
  nested parents, and the full Linux rwx bit pattern.

The 4 failing macOS conformance tests are a virtiofs limitation
(host mode bits not propagated through Podman Machine / Docker
Desktop shared FS); on Linux CI the chmod path verified here is
sufficient.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WebSocket exec now implements v5.channel.k8s.io protocol with stdin (channel 0),
stdout (1), stderr (2), error (3), resize (4), plus v5 close-stream control.
Kubelet runtime captures container exit code via bollard inspect for
lastState.terminated.exitCode. PreStop lifecycle handler invoked before SIGTERM
and respects terminationGracePeriodSeconds.

Closes conformance gap (Unit 12): preStop, container exit status,
exec over websockets.
Persist init container status updates between actions so watches observe
each transition (Running, Terminated, CrashLoopBackOff). Without these
updates, a failing init container's Terminated state was never written
before container removal, so get_init_container_statuses fell back to
the Running prev state on retry. That suppressed CrashLoopBackOff
reporting and pinned restart_count at 0, hanging the K8s conformance
tests that wait for restart_count >= 3 and for the failed-init pod
to reach Failed.

- Publish Running state after start_container, Terminated after a
  successful wait, Terminated/error before remove_container on failure.
- Extract refresh_init_container_statuses helper to eliminate four
  near-identical pod-read / get_init_container_statuses / pod-write
  blocks.
- RestartPolicy=Never still propagates the error immediately, so
  remaining init containers do not run and the pod transitions to
  Failed via the existing kubelet.rs error handler.

Targets Kubernetes v1.35 conformance:
- [Conformance] InitContainer should not start app containers if init
  containers fail on a RestartNever pod
- [Conformance] InitContainer should restart with CrashLoopBackOff on
  a RestartAlways pod
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