What you would like to be added?
Replace the current Clients struct in the e2e test framework containing six separate client fields with a single K8s struct:
// Before — e2e/k8s/clients.go
type Clients struct {
Clientset kubernetes.Interface
DynamicClient dynamic.Interface
GroveClient groveclient.Interface
RestMapper meta.RESTMapper
RestConfig *rest.Config
CRClient client.Client
}
// After — e2e/k8s/k8s.go
type K8s struct {
client.Client
RestConfig *rest.Config
}
The controller-runtime client.Client handles all use cases currently spread across four client types in the e2e codebase:
- Clientset (Pods, Nodes, ConfigMaps, Events) → k8s.Get/List/Create/Update with typed core objects
- GroveClient (PodCliqueSet, PCSG, PodClique) → same, with Grove types registered in the scheme
- CRClient → this IS already a client.Client, currently duplicated as a separate field
- DynamicClient (YAML apply, unstructured resources) → client.Client supports unstructured.Unstructured natively
- RestMapper → embedded inside client.Client, not needed as a separate field
RestConfig is kept only for e2e operations requiring raw HTTP access (log streaming, port-forward, exec).
The work should:
- Register all needed types (core, Grove CRDs, KAI scheduling) in a single scheme during K8s creation
- Replace Clientset calls like clientset.CoreV1().Pods(ns).List(...) with k8s.List(ctx, podList, client.InNamespace(ns))
- Replace GroveClient calls like groveClient.GroveV1alpha1().PodCliqueSets(ns).Create(...) with k8s.Create(ctx, pcs)
- Replace DynamicClient YAML apply with unstructured objects through the same client
- Remove GetClients(), GetCRClient() from SharedClusterManager — expose only K8s()
- Update all e2e managers (PodManager, NodeManager, ResourceManager, WorkloadManager, etc.) to accept *K8s instead of *Clients
Why is this needed?
The e2e test framework currently uses four client types talking to the same API server, creating cognitive overhead — every e2e function must decide which client to accept, and test authors must know which one to pass. This shows up concretely: SharedClusterManager stores both individual fields and a bundled struct, e2e/utils functions take raw clientset/dynamicClient params, and 29
NewForConfig calls across the e2e codebase create redundant client instances per call. The controller-runtime client.Client was designed as the single unified Kubernetes client — it handles typed objects, unstructured objects, and any GVK in its scheme. Converging on one client eliminates the "which client do I use" question from e2e test code, shrinks the struct from six fields to
two, simplifies every e2e function signature that currently threads client params, and gives the waiter package a clean foundation — WaitFor[T] fetch functions just call k8s.List regardless of resource type.
What you would like to be added?
Replace the current Clients struct in the e2e test framework containing six separate client fields with a single K8s struct:
// Before — e2e/k8s/clients.go
type Clients struct {
Clientset kubernetes.Interface
DynamicClient dynamic.Interface
GroveClient groveclient.Interface
RestMapper meta.RESTMapper
RestConfig *rest.Config
CRClient client.Client
}
// After — e2e/k8s/k8s.go
type K8s struct {
client.Client
RestConfig *rest.Config
}
The controller-runtime client.Client handles all use cases currently spread across four client types in the e2e codebase:
RestConfig is kept only for e2e operations requiring raw HTTP access (log streaming, port-forward, exec).
The work should:
Why is this needed?
The e2e test framework currently uses four client types talking to the same API server, creating cognitive overhead — every e2e function must decide which client to accept, and test authors must know which one to pass. This shows up concretely: SharedClusterManager stores both individual fields and a bundled struct, e2e/utils functions take raw clientset/dynamicClient params, and 29
NewForConfig calls across the e2e codebase create redundant client instances per call. The controller-runtime client.Client was designed as the single unified Kubernetes client — it handles typed objects, unstructured objects, and any GVK in its scheme. Converging on one client eliminates the "which client do I use" question from e2e test code, shrinks the struct from six fields to
two, simplifies every e2e function signature that currently threads client params, and gives the waiter package a clean foundation — WaitFor[T] fetch functions just call k8s.List regardless of resource type.