Architecture
Big picture
The composable-resource-operator is a kubebuilder and controller-runtime operator. main (cmd/main.go:61) builds one controller-runtime Manager and registers three reconcilers plus one validating webhook on it: ComposabilityRequestReconciler (cmd/main.go:167), ComposableResourceReconciler (cmd/main.go:176), UpstreamSyncerReconciler (cmd/main.go:186), and, unless ENABLE_WEBHOOKS is false (cmd/main.go:196), the webhook via SetupWebhookWithManager (cmd/main.go:197). The operator sits between a higher-level trigger (a scaler or a user) and a vendor CDI fabric manager that physically switches devices.
The wider data plane, from the org profile README, works like this:
Components
ComposabilityRequest reconciler
The user-facing control loop. Reconcile (internal/controller/composabilityrequest_controller.go:72) reads a ComposabilityRequest (desired count, model, allocation policy) and creates or deletes internal ComposableResource objects so the live set matches the request. It runs a state machine (None to NodeAllocating to Updating to Running) and watches child ComposableResource status changes.
ComposableResource reconciler
The per-device control loop. Reconcile (internal/controller/composableresource_controller.go:82) drives one device through Attaching, Online, Detaching. This is the loop that calls the CDI provider to add or remove real hardware and then nudges the GPU stack to notice.
Upstream syncer
A drift detector. UpstreamSyncerReconciler (internal/controller/upstreamsyncer_controller.go:40) runs as a background goroutine on a one-minute ticker (internal/controller/upstreamsyncer_controller.go:61) and reconciles what the CDI fabric reports against the cluster's ComposableResource objects.
Validating webhook
ComposabilityRequestCustomValidator (internal/webhook/v1alpha1/composabilityrequest_webhook.go:60) rejects conflicting requests before they are admitted.
CDI provider layer
internal/cdi holds the vendor abstraction. The CdiProvider interface (internal/cdi/client.go:34) is implemented by Fujitsu FTI_CDI (Composition Manager and Fabric Manager under internal/cdi/fti), SNIA Sunfish (internal/cdi/sunfish), and NEC (internal/cdi/nec).
How a request flows
Creating a ComposabilityRequest for two GPUs flows like this:
- Admission: the webhook's
validateRequest(internal/webhook/v1alpha1/composabilityrequest_webhook.go:100) rejects a duplicate type and model, or atarget_nodecombined with thedifferentnodepolicy. ComposabilityRequestReconciler.Reconcile(internal/controller/composabilityrequest_controller.go:72) sees an empty state, sohandleNoneState(internal/controller/composabilityrequest_controller.go:197) adds a finalizer and sets stateNodeAllocating(internal/controller/composabilityrequest_controller.go:207).handleNodeAllocatingState(internal/controller/composabilityrequest_controller.go:213) picks target nodes per the allocation policy, then moves toUpdating(internal/controller/composabilityrequest_controller.go:481).handleUpdatingState(internal/controller/composabilityrequest_controller.go:487) creates oneComposableResourceper desired device and requeues until all reportOnline, at which point it setsRunning(internal/controller/composabilityrequest_controller.go:552).- For each
ComposableResource,handleAttachingState(internal/controller/composableresource_controller.go:209) callsadapter.CDIProvider.AddResource(resource)(internal/controller/composableresource_controller.go:231). - The child status change is picked up by the parent through a watch (
internal/controller/composabilityrequest_controller.go:684) filtered byresourceStatusUpdatePredicate(internal/controller/composabilityrequest_controller.go:658).
The Internals page walks the attach path down into the Fabric Manager HTTP call.
Key design decisions
- Two-stage reconcile. A request carries "how many plus a policy"; the operator splits it into N single-device objects, each with its own state machine. This isolates per-device failure and retry from the aggregate request.
- Vendor abstraction. The
CdiProviderinterface (internal/cdi/client.go:34) hides per-vendor management APIs.NewComposableResourceAdapter(internal/controller/composableresource_adapter.go:40) picks the implementation fromCDI_PROVIDER_TYPE, and FTI_CDI further branches onFTI_CDI_API_TYPEinto Composition Manager or Fabric Manager (internal/controller/composableresource_adapter.go:63). - Drift detection over trust. Rather than assume the cluster and the fabric agree, the upstream syncer re-reads the fabric every minute and reconciles, tracking orphan devices with a grace period before detaching them.
Extension points
- Two CRDs in API group
cro.hpsys.ibm.ie.com(api/v1alpha1/groupversion_info.go:29):ComposabilityRequest(user-facing) andComposableResource(operator-managed). - The
CdiProviderinterface (internal/cdi/client.go:34) is the seam for adding a new hardware backend. - A validating admission webhook for
ComposabilityRequest. - Runtime behaviour is driven by environment variables (
CDI_PROVIDER_TYPE,FTI_CDI_API_TYPE,DEVICE_RESOURCE_TYPE,ENABLE_WEBHOOKS, and provider endpoints), read in the adapter andmain.