Standalone operator for Kubeflow Trainer v2. Reconciles the Trainer CR (components.platform.opendatahub.io/v1alpha1) and deploys upstream Kubeflow Trainer resources via kustomize rendering from opendatahub-io/trainer manifests.
- Build time:
hack/get_trainer_manifests.shfetches upstream trainer manifests intoopt/manifests/ - Dockerfile: copies upstream manifests into
/opt/manifests-template/, runtimes into/opt/runtimes-template/, and imagestreams into/opt/imagestreams-template/ - Runtime: copies templates to a writable work dir, applies
RELATED_IMAGEenv var overrides toparams.env, renders the kustomize overlay, applies with Server-Side Apply
- Managed: ensure finalizer → ensure namespace → render manifests → SSA apply → update status (Ready)
- Removed: ensure finalizer → GC cleanup (label-based discovery) → update status (NotReady)
- Deleted: GC cleanup → remove finalizer → CR deleted
The controller uses shared utilities from opendatahub-io/odh-platform-utilities:
api/common— PlatformObject interface, ManagementSpec, Status, Condition typespkg/controller/conditions— Condition Manager with happiness recomputationpkg/controller/gc— GC Collector for label-based resource cleanup via discovery APIpkg/render/kustomize— Kustomize manifest renderingpkg/resources— Server-Side Apply
api/v1alpha1/ CRD types implementing common.PlatformObject
internal/controller/ Reconciler, manifest rendering, params.env handling
cmd/main.go Operator entrypoint
config/ Kustomize manifests (CRDs, RBAC, manager deployment, samples)
hack/ Manifest collection script (get_trainer_manifests.sh)
manifests/runtimes/ ClusterTrainingRuntime definitions (torch, training-hub)
manifests/imagestreams/ ImageStream definitions (CUDA, ROCm, CPU training images)
test/e2e/ End-to-end tests (Kind cluster)
test/e2e/ocp/ End-to-end tests (OCP/real cluster)
test/support/ Shared test client (Client wrapping kubernetes.Interface)
test/utils/ Shell command utilities (make, kind, cert-manager)
- Go 1.25+
- Podman (or Docker via
CONTAINER_TOOL=docker) - kubectl v1.28+
- Access to a Kubernetes v1.28+ cluster
make manifests # Generate CRDs and RBAC from markers
make generate # Generate DeepCopy methods
make fmt # Format code
make vet # Vet code
make lint # Run linter
make lint-fix # Run linter and auto-fix issues
make test # Run unit tests (envtest)
make build # Build the operator binary
make run # Run operator locally against cluster
make docker-build # Build container image (uses podman by default)
make install # Install CRDs into cluster
make deploy IMG=<img> # Deploy operator to clusterTo use Docker instead of Podman, set CONTAINER_TOOL=docker.
Unit tests (controller tests with envtest):
make testE2E tests (creates a Kind cluster, deploys the operator, runs tests, tears down):
make test-e2eThe Kind cluster can also be managed separately:
make setup-test-e2e # Create Kind cluster
make cleanup-test-e2e # Tear down Kind clusterOCP e2e tests (requires a cluster with the operator and JobSet controller deployed):
make test-e2e-ocpmake docker-build docker-push IMG=<some-registry>/odh-trainer-operator:tag
make install
make deploy IMG=<some-registry>/odh-trainer-operator:tag
kubectl apply -k config/samples/kubectl delete -k config/samples/
make uninstall
make undeploy- Edit
api/v1alpha1/trainer_types.go - Run
make manifests generateto regenerate CRDs and DeepCopy methods - Update controller logic in
internal/controller/trainer_controller.go
RBAC rules are derived from // +kubebuilder:rbac: markers in the controller. After adding new markers, run make manifests to regenerate.
The controller SA must hold all permissions that upstream trainer ClusterRoles grant — Kubernetes RBAC escalation prevention blocks creating a ClusterRole with permissions the creator doesn't already have.
Run make lint after any code changes.
Copyright 2026.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.