Skip to content

OSAC-3162: add GpuSpec to ComputeInstance CRD - #217

Merged
omer-vishlitzky merged 3 commits into
osac-project:mainfrom
Tzif-Morgen:feat/OSAC-3162-gpu-spec-crd
Aug 12, 2026
Merged

omer-vishlitzky merged 3 commits into
osac-project:mainfrom
Tzif-Morgen:feat/OSAC-3162-gpu-spec-crd

Conversation

@Tzif-Morgen

@Tzif-Morgen Tzif-Morgen commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

OSAC-3162: add GpuSpec to ComputeInstance CRD

Jira: OSAC-3162
Story type: [DEV]
Epic: OSAC-3158 — GPU ComputeInstance Provisioning

Summary

Adds a GpuSpec struct and optional Gpu field to the ComputeInstance CRD, following the existing ImageSpec/DiskSpec nested struct pattern. This enables the fulfillment reconciler (OSAC-3182) to stamp GPU configuration from InstanceTypes onto ComputeInstance CRs for the operator to consume during provisioning.

Changes

  • osac-operator/api/v1alpha1/computeinstance_types.go — Added GpuSpec struct with PciDeviceSelector (string), ResourceName (string), and Count (int32) fields. Added optional Gpu *GpuSpec field to ComputeInstanceSpec.
  • Kubebuilder validation markers:
    • PciDeviceSelector, ResourceName: Required, MinLength=1
    • Count: Required, Minimum=1, Maximum=16
    • Gpu field: optional with omitempty
  • CRD manifests regenerated via make manifests generate and synced to Helm charts via make helm-crds

Testing

  • Unit tests: Struct-level test verifying GpuSpec field construction and access on ComputeInstanceSpec
  • Envtest CRD validation tests (7 tests):
    • CR with valid GPU spec succeeds
    • CR without GPU spec succeeds (backward compatible)
    • GPU field omitted from JSON when not set (omitempty round-trip)
    • count = 0 rejected (below minimum)
    • count = 17 rejected (above maximum)
    • Empty pciDeviceSelector rejected
    • Empty resourceName rejected
  • Coverage: All behavioral paths through the new GpuSpec type are tested via public interfaces

Acceptance Criteria

  • AC-1: GpuSpec struct with PciDeviceSelector, ResourceName, Count exists in osac-operator
  • AC-2: ComputeInstanceSpec has an optional Gpu field of type *GpuSpec
  • AC-3: ComputeInstance CR with gpu fields passes CRD validation
  • AC-4: ComputeInstance CR without gpu fields passes CRD validation (backward compatible)
  • AC-5: CRD manifests are regenerated with make manifests

Summary by CodeRabbit

  • New Features
    • Added optional GPU passthrough configuration for compute instances.
    • GPU settings support PCI device selection, resource naming, and GPU counts from 1–16.
    • Added validation to require valid GPU configuration values.
    • GPU settings are immutable after creation.

@openshift-ci-robot

openshift-ci-robot commented Aug 9, 2026 •

Copy link
Copy Markdown

@Tzif-Morgen: This pull request references OSAC-3162 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

OSAC-3162: add GpuSpec to ComputeInstance CRD

Jira: OSAC-3162
Story type: [DEV]
Epic: OSAC-3158 — GPU ComputeInstance Provisioning

Summary

Adds a GpuSpec struct and optional Gpu field to the ComputeInstance CRD, following the existing ImageSpec/DiskSpec nested struct pattern. This enables the fulfillment reconciler (OSAC-3182) to stamp GPU configuration from InstanceTypes onto ComputeInstance CRs for the operator to consume during provisioning.

Changes

  • osac-operator/api/v1alpha1/computeinstance_types.go — Added GpuSpec struct with PciDeviceSelector (string), ResourceName (string), and Count (int32) fields. Added optional Gpu *GpuSpec field to ComputeInstanceSpec.
  • Kubebuilder validation markers:
  • PciDeviceSelector, ResourceName: Required, MinLength=1
  • Count: Required, Minimum=1, Maximum=16
  • Gpu field: optional with omitempty
  • CRD manifests regenerated via make manifests generate and synced to Helm charts via make helm-crds

Testing

  • Unit tests: Struct-level test verifying GpuSpec field construction and access on ComputeInstanceSpec
  • Envtest CRD validation tests (7 tests):
  • CR with valid GPU spec succeeds
  • CR without GPU spec succeeds (backward compatible)
  • GPU field omitted from JSON when not set (omitempty round-trip)
  • count = 0 rejected (below minimum)
  • count = 17 rejected (above maximum)
  • Empty pciDeviceSelector rejected
  • Empty resourceName rejected
  • Coverage: All behavioral paths through the new GpuSpec type are tested via public interfaces

Acceptance Criteria

  • AC-1: GpuSpec struct with PciDeviceSelector, ResourceName, Count exists in osac-operator
  • AC-2: ComputeInstanceSpec has an optional Gpu field of type *GpuSpec
  • AC-3: ComputeInstance CR with gpu fields passes CRD validation
  • AC-4: ComputeInstance CR without gpu fields passes CRD validation (backward compatible)
  • AC-5: CRD manifests are regenerated with make manifests

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f7ba035f-e6d9-405f-9c50-5a83c299730b

📥 Commits

Reviewing files that changed from the base of the PR and between f9c1c6f and 5788783.

📒 Files selected for processing (4)
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/internal/controller/computeinstance_validation_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/internal/controller/computeinstance_validation_test.go

Walkthrough

The ComputeInstance API now supports optional GPU passthrough configuration. The CRD validates GPU count, PCI selector, resource name, and immutability. Deepcopy methods and validation tests cover the new field.

Changes

GPU specification

Layer / File(s) Summary
GPU API contract and object copying
osac-operator/api/v1alpha1/computeinstance_types.go, osac-operator/api/v1alpha1/zz_generated.deepcopy.go, osac-operator/api/v1alpha1/computeinstance_types_test.go
Adds GpuSpec and the optional ComputeInstanceSpec.Gpu field. Generated deepcopy methods copy the optional pointer. API tests verify GPU field values.
CRD schema and validation coverage
osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml, osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml, osac-operator/internal/controller/computeinstance_validation_test.go
Adds the optional spec.gpu schema with required fields, count bounds, and immutability. Validation tests cover valid, absent, invalid, and modified GPU configurations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: lgtm

Suggested reviewers: larsks, adriengentil, ygalblum

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding GpuSpec to the ComputeInstance CRD.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed The complete PR diff adds only GPU configuration, validation, and test data; focused scans found no API keys, credentials, private keys, embedded-credential URLs, or long base64/hex secrets.
No-Weak-Crypto ✅ Passed The PR diff adds GPU schema, validation, deepcopy code, and tests only; scans found no introduced MD5, SHA1, DES, RC4, Blowfish, ECB, or crypto comparison usage.
No-Injection-Vectors ✅ Passed The PR adds only Go structs/deep-copy logic, tests, and static CRD YAML; changed files contain no SQL concatenation or listed eval, shell, pickle, YAML, OS, or HTML injection sinks.
Container-Privileges ✅ Passed The PR changes only API types, deepcopy code, tests, and CRD schemas. The merge-base diff adds no privileged, host namespace, SYS_ADMIN, root, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed The PR adds API types, CRD schemas, deepcopy code, and tests only; the complete PR diff contains no logging calls or sensitive-data output.
Ai-Attribution ✅ Passed All three PR commits include Assisted-by: Claude Code <noreply@anthropic.com>; no Co-Authored-By AI trailer appears.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously requested changes Aug 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@osac-operator/api/v1alpha1/computeinstance_types.go`:
- Around line 59-62: Update the PciDeviceSelector validation markers to require
exactly four hexadecimal vendor digits, a colon, and four hexadecimal device
digits using an allow-list pattern; regenerate both CRD manifests from the
updated API type and add a test confirming malformed selectors such as “invalid”
are rejected.

In `@osac-operator/internal/controller/computeinstance_validation_test.go`:
- Around line 509-515: Update the test case around createValidInstance and the
gpu omitempty behavior to marshal the instance using encoding/json, then assert
the serialized JSON does not contain the "gpu" property. Remove the
create-and-get assertions, since they cannot distinguish omission from a null
value.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f36f1b6-cb5f-4835-b1b2-ffe16fb8b620

📥 Commits

Reviewing files that changed from the base of the PR and between bd04c8c and 8a6547b.

📒 Files selected for processing (6)
  • osac-operator/api/v1alpha1/computeinstance_types.go
  • osac-operator/api/v1alpha1/computeinstance_types_test.go
  • osac-operator/api/v1alpha1/zz_generated.deepcopy.go
  • osac-operator/charts/operator-crds/templates/osac.openshift.io_computeinstances.yaml
  • osac-operator/config/crd/bases/osac.openshift.io_computeinstances.yaml
  • osac-operator/internal/controller/computeinstance_validation_test.go

Comment thread osac-operator/api/v1alpha1/computeinstance_types.go

@ygalblum ygalblum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve
/lgtm

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:31 PM UTC · Completed 2:48 PM UTC

Commit: d90176d · View workflow run →

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm

Add XValidation immutability rule to the Gpu field, consistent with
all other hardware fields (cores, memoryGiB, bootDisk, etc.). Fix the
optionality marker from // +optional to // +kubebuilder:validation:Optional
to match codebase convention.

Signed-off-by: Tzif <tmorgens@redhat.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Tzif <tmorgens@redhat.com>
@Tzif-Morgen
Tzif-Morgen force-pushed the feat/OSAC-3162-gpu-spec-crd branch from d90176d to f9c1c6f Compare August 12, 2026 07:00
@openshift-ci openshift-ci Bot removed the lgtm label Aug 12, 2026
@omer-vishlitzky
omer-vishlitzky dismissed stale reviews from coderabbitai[bot] and fullsend-ai-review[bot] August 12, 2026 07:01

Auto-dismissed: only Prow labels gate merging

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 7:02 AM UTC · Ended 7:15 AM UTC

Commit: f9c1c6f · View workflow run →

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Aug 12, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:02 AM UTC · Completed 7:15 AM UTC

Commit: f9c1c6f · View workflow run →

@Tzif-Morgen

Copy link
Copy Markdown
Contributor Author

@ygalblum I Addressed fullsend review feedback - added GPU immutability rule (consistent with cores/memoryGiB/etc.) and fixed the optional marker convention. Can you give another lgtm?

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 12, 2026
Move GPU immutability from field-level self == oldSelf to spec-level
has() check to also block absent-to-present transitions. Add test
for the absent→present case.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Tzif <tmorgens@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 2:27 PM UTC · Ended 2:45 PM UTC

Commit: 5788783 · View workflow run →

@ygalblum ygalblum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Aug 12, 2026
@openshift-ci

openshift-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Tzif-Morgen, ygalblum

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment


Describe("MaxItems validation", func() {
It("should reject creating ComputeInstance with more than 8 networkAttachments", func() {
instance := createValidInstance("test-max-attachments")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] test adequacy

The GPU immutability tests cover 'reject changing gpu' and 'reject adding gpu after creation', but do not cover the symmetric case of removing GPU after creation (creating with GPU set, then updating with Gpu set to nil). The CEL rule has(self.gpu) == has(oldSelf.gpu) correctly rejects this case via the same sub-expression, but the behavior is untested. Other immutable fields in this file test both directions.

Suggested fix: Add a test case 'should reject removing gpu after creation' that creates an instance with a valid GpuSpec, fetches it, sets Gpu to nil, and asserts that Update returns an IsInvalid error containing 'gpu is immutable'.

}

// ComputeInstanceSpec defines the desired state of ComputeInstance
// +kubebuilder:validation:XValidation:rule="has(self.gpu) == has(oldSelf.gpu) && (!has(self.gpu) || self.gpu == oldSelf.gpu)",message="gpu is immutable"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] pattern-divergence

The GPU immutability rule is enforced at the spec level via XValidation on ComputeInstanceSpec using has() checks, while other immutable optional fields use field-level self == oldSelf. The spec-level approach is intentionally more robust for optional struct pointers. A brief code comment explaining this design choice would help future contributors.

Suggested fix: Add a comment above the XValidation rule explaining that has() checks are needed because field-level self == oldSelf does not prevent nil-to-value transitions on optional struct pointer fields.

@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:27 PM UTC · Completed 2:45 PM UTC

Commit: 5788783 · View workflow run →

@omer-vishlitzky
omer-vishlitzky added this pull request to the merge queue Aug 12, 2026
Merged via the queue into osac-project:main with commit 22ab6db Aug 12, 2026
91 of 95 checks passed

This branch was previously deployed

1 inactive deployment
e2e-test — 57887832 Deployed Aug 12, 2026 by Tzif-Morgen via e2e-vmaas-full-install / e2e #1451
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved jira/valid-reference lgtm ready-for-merge All reviewers approved — ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants