kubeflow / kubeflow/notebooks

[TASK] Add podMetadata and statefulSetMetadata to WorkspaceKind podConfig options

Open
#1,401 1 comment 0 reactions 1 assignee Claimed by @christian-heusel View on GitHub
kind/plan-task
Dominant language
No language data
Stars
84
Forks
149
Avg merge
5d 15h
Merged PRs (30d)
29

Description

### Certification

- [x] I certify I am an Epic Owner for Kubeflow Notebooks 2.0 and expected to create planning-related issues.

### Description

Add optional `podMetadata` and `statefulSetMetadata` fields to `PodConfigSpec` so that admins can attach labels and annotations that only apply when a specific podConfig is selected (e.g. routing GPU-tier Workspaces to a Kueue `LocalQueue`, tagging spot-capacity pods with a cost center). The types and validation rules are the same as the existing top-level fields introduced by #1351 — this task reuses those types verbatim rather than defining new ones.

`imageConfig` is intentionally out of this task. See the parent feature for the rationale; `ImageConfig` / `ImageConfigValue` / `ImageConfigSpec` must not gain equivalent fields.

#### Key Files to Modify

```
| File | Role |
|------|------|
| `workspaces/controller/api/v1beta1/workspacekind_types.go` | Add `PodMetadata` and `StatefulSetMetadata` to `PodConfigSpec` (reusing `WorkspaceKindPodMetadata` / `WorkspaceKindStatefulSetMetadata`) |
| `workspaces/controller/internal/webhook/workspacekind_webhook.go` | Extend admission validation to the new maps, matching the existing `validatePodTemplatePodMetadata` / `validatePodTemplateStatefulSetMetadata` helpers |
| `workspaces/controller/internal/controller/workspace_controller.go` | Layer per-podConfig metadata over WorkspaceKind-level metadata when composing the desired Pod and StatefulSet |
| `workspaces/controller/manifests/kustomize/samples/*.yaml` | Optionally exercise the new fields in a sample to serve as documentation |

Regenerated artifacts (`zz_generated.deepcopy.go`, the CRD manifest, backend `swagger.json` / `docs.go`) are produced by the normal `make generate` / `make manifests` / `make swagger` flow and are not called out separately.
```

#### Expected Behavior

`PodConfigSpec` gains two optional pointer fields, both omitted-by-default so existing WorkspaceKinds are unaffected. Admission validates Kubernetes label and annotation syntax on both maps using the same helpers `validatePodTemplatePodMetadata` / `validatePodTemplateStatefulSetMetadata` already apply to the top-level fields; no additional key-name restrictions are introduced.

At reconcile time, the effective metadata applied to the Pod (and independently to the StatefulSet) is the union of the WorkspaceKind-level map and the selected podConfig-level map, with the podConfig winning on key conflicts. Controller-owned keys (e.g. `notebooks.kubeflow.org/workspace-name`) are applied last via the same `labels.Merge` pattern #1351 uses, so they remain authoritative regardless of what an admin puts in either map.

When a Workspace's selected podConfig changes, or when the podConfig entry on the WorkspaceKind is edited, the controller must re-derive and apply the new effective metadata — including *removing* keys that were previously contributed by a now-deselected podConfig, and *adding* keys that only the newly-selected podConfig contributes. The additive-key fix that #1351 applied to `copyLabelFields` / `copyAnnotationFields` is expected to cover the StatefulSet side; verify this during implementation and file a follow-up if it turns out to be insufficient.

#### Backend / API surface

No backend changes are required. The new fields reach the OpenAPI schema through the controller types embedded in the create/update request bodies in `types_write.go`, so regenerated swagger picks them up automatically. None of the existing `GET /workspacekinds` or `/listvalues` response bodies expose per-`podConfig` specs today, and extending them to include the new fields — if ever wanted — is a separate task.

### Acceptance Criteria

- [ ] `PodConfigSpec` gains `PodMetadata *WorkspaceKindPodMetadata` (JSON `podMetadata`) and `StatefulSetMetadata *WorkspaceKindStatefulSetMetadata` (JSON `statefulSetMetadata`), reusing the existing types from #1351 rather than defining new ones.
- [ ] Admission validates Kubernetes label and annotation syntax on both new maps, matching how `validatePodTemplatePodMetadata` / `validatePodTemplateStatefulSetMetadata` validate the top-level fields.
- [ ] Effective precedence on both the Pod and the StatefulSet is **controller-owned > podConfig-level > WorkspaceKind-level** on key conflicts, and is enforced by `labels.Merge`-style construction rather than by ordering conventions in call sites.
- [ ] When a Workspace's selected podConfig changes, keys contributed only by the previous podConfig are removed from both the Pod and the StatefulSet on the next reconcile.
- [ ] When a podConfig entry on the WorkspaceKind gains a new label/annotation, that key appears on already-running Workspaces using that podConfig on the next reconcile — without requiring any other spec change to trigger it.
- [ ] No changes to `ImageConfig`, `ImageConfigValue`, or `ImageConfigSpec`; no per-Workspace override of the new fields is introduced; frontend `src/generated/` is not regenerated in this task.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.