Skip to content

OSAC-1270: Design - Base OS Management for Bare Metal Instances - #197

Merged
openshift-merge-bot[bot] merged 17 commits into
mainfrom
design/OSAC-1270
Aug 19, 2026
Merged

openshift-merge-bot[bot] merged 17 commits into
mainfrom
design/OSAC-1270

Conversation

@adriengentil

@adriengentil adriengentil commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Design: Base OS Management for Bare Metal Instances

Jira: https://redhat.atlassian.net/browse/OSAC-1270
PRD: prd.md

Summary

This design integrates the DiskImage resource (OSAC-2540) into the BMaaS provisioning path. BareMetalInstanceSpec.image (inline OCI URL) is replaced by a disk_image reference to a governed DiskImage. The fulfillment-service reconciler resolves the DiskImage's source_ref and injects it as imageURL in the template parameters — no changes to the bare-metal-fulfillment-operator CRD or osac-aap provisioning templates. DiskImage deletion protection is extended to bare_metal_instances and bare_metal_instance_catalog_items via an updated database trigger.

Requesting Review On

  • Trigger replacement approach — the check_disk_image_not_in_use function from OSAC-2540 is dropped and recreated with BMI table checks added; reviewers should verify this is safe and consistent with how the instance_type trigger was handled in migration 56.
  • JSONB key casing — OSAC-2540's compute trigger uses camelCase keys (diskImage, specDefaults), while the DAO's UseProtoNames: true setting produces snake_case. Implementors must verify the actual persisted key for disk_image in bare_metal_instances before writing the migration SQL — a mismatch silently breaks deletion protection with no error at write time.
  • imageSourceType dropped — mutateBMI currently injects both imageURL and imageSourceType from spec.image. This design drops imageSourceType on the grounds that DiskImage abstracts the source type and AAP templates do not consume it. Reviewers should confirm the BMaaS provisioning templates truly do not need imageSourceType; if they do, it should be derived from DiskImage.source_type.
  • No disk_image on BareMetalInstanceTemplate — defaults are carried only on BareMetalInstanceCatalogItem.field_definitions. This is a locked decision from the PRD; reviewers should flag if this is too restrictive for operator workflows.
  • guest_os_family not forwarded to AAP — the DiskImage's OS family is not injected as a template parameter. Reviewers should confirm the BMaaS provisioning templates do not need it today.

Documents

  • design.md — technical design document

How to Review

  • Comment inline on specific sections
  • Approve when the design accurately reflects a viable implementation approach

…Instances

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@openshift-ci-robot

openshift-ci-robot commented Aug 7, 2026 •

Copy link
Copy Markdown

@adriengentil: This pull request references OSAC-1270 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 feature to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Design: Base OS Management for Bare Metal Instances

Jira: https://redhat.atlassian.net/browse/OSAC-1270
PRD: prd.md

Summary

This design integrates the DiskImage resource (OSAC-2540) into the BMaaS provisioning path. BareMetalInstanceSpec.image (inline OCI URL) is replaced by a disk_image reference to a governed DiskImage. The fulfillment-service reconciler resolves the DiskImage's source_ref and injects it as imageURL in the template parameters — no changes to the bare-metal-fulfillment-operator CRD or osac-aap provisioning templates. DiskImage deletion protection is extended to bare_metal_instances and bare_metal_instance_catalog_items via an updated database trigger.

Requesting Review On

  • Trigger replacement approach — the check_disk_image_not_in_use function from OSAC-2540 is dropped and recreated with BMI table checks added; reviewers should verify this is safe and consistent with how the instance_type trigger was handled in migration 56.
  • JSONB key casing — the design notes that the BMI trigger uses snake_case (disk_image) consistent with the existing instance_type trigger, while OSAC-2540 uses camelCase (diskImage) for compute resources. Implementors should verify the actual JSONB key before applying.
  • No disk_image on BareMetalInstanceTemplate — defaults are carried only on BareMetalInstanceCatalogItem.field_definitions. This is a locked decision from the PRD; reviewers should flag if this is too restrictive for operator workflows.
  • guest_os_family not forwarded to AAP — the DiskImage's OS family is not injected as a template parameter. Reviewers should confirm the BMaaS provisioning templates do not need it today.

Documents

  • design.md — technical design document

How to Review

  • Comment inline on specific sections
  • Approve when the design accurately reflects a viable implementation approach

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 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@adriengentil, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 36 minutes

Limit details: You’ve used all 1 included review currently available under your plan.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 1dab46f5-0282-4834-85c1-18dfa803eedb

📥 Commits

Reviewing files that changed from the base of the PR and between a7b5c43 and 3ecca58.

📒 Files selected for processing (1)
  • enhancements/OSAC-1270-base-os-management-bmaas/design.md

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: Pro Plus

Run ID: e5748db5-4f35-4f22-a8b7-767ae777801c

📥 Commits

Reviewing files that changed from the base of the PR and between 86ca04c and a7b5c43.

📒 Files selected for processing (1)
  • enhancements/OSAC-1270-base-os-management-bmaas/design.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • enhancements/OSAC-1270-base-os-management-bmaas/design.md

Walkthrough

Changes

The design replaces inline bare-metal image data with immutable DiskImage references. It defines API changes, CatalogItem defaulting, validation, reconciliation, deletion protection, client updates, testing, migration, rollout, and operational procedures.

BMaaS DiskImage integration

Layer / File(s) Summary
API contract and migration scope
enhancements/OSAC-1270-base-os-management-bmaas/design.md
The public and private APIs reserve removed image fields, add immutable disk_image, and add warnings to create and CatalogItem responses.
Creation validation and reconciliation
enhancements/OSAC-1270-base-os-management-bmaas/design.md
Creation applies CatalogItem defaults and validates DiskImage existence, visibility, and lifecycle. Reconciliation resolves source_ref into imageURL.
Reference integrity and security
enhancements/OSAC-1270-base-os-management-bmaas/design.md
The design defines tenant visibility checks, database reference validation, deletion protection, trigger behavior, and migration ordering.
Client rollout and operational validation
enhancements/OSAC-1270-base-os-management-bmaas/design.md
The design specifies UI and CLI updates, tests, rollout and downgrade procedures, version-skew handling, troubleshooting, rejected alternatives, and provenance metadata.

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

Merge Risk: ⚪ Minimal · up to a7b5c

This design change is merge-ready after normal checks and review; no actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant BMaaSAPI
  participant CatalogItem
  participant DiskImage
  participant Reconciler
  Client->>BMaaSAPI: Create BareMetalInstance with disk_image
  BMaaSAPI->>CatalogItem: Apply CatalogItem defaults
  BMaaSAPI->>DiskImage: Validate reference and lifecycle
  BMaaSAPI-->>Client: Return instance and warnings
  Reconciler->>DiskImage: Resolve disk_image
  DiskImage-->>Reconciler: Return source_ref
  Reconciler->>Reconciler: Set imageURL template parameter
Loading

Suggested reviewers: jhernand, tzvatot

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
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 PR adds only design.md; scans found no private-key material, credential-bearing URLs, long secret-shaped blobs, or literal credential assignments.
No-Weak-Crypto ✅ Passed The PR adds only a design document. Its complete diff contains no MD5, SHA-1, DES, RC4, Blowfish, ECB, custom crypto, or secret-comparison implementation.
No-Injection-Vectors ✅ Passed The diff changes only design.md; added lines contain proto/documentation text and no SQL concatenation, shell=True, eval/exec, unsafe YAML/pickle, os.system, or dangerouslySetInnerHTML.
Container-Privileges ✅ Passed The PR adds only a design.md document; searches found no container/Kubernetes manifest with privileged, host namespace, SYS_ADMIN, root, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed The cumulative diff adds only a design document. It introduces no logging implementation or sensitive values; its observability text only references existing structured logs and generic reconciliat...
Ai-Attribution ✅ Passed All 12 commits in the PR range include an Assisted-by: Claude Code trailer, and none includes a Co-Authored-By trailer for an AI tool.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the design change and its scope for base OS management in bare-metal instances.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch design/OSAC-1270

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

github-actions Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 7/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Excellent implementation depth. Full proto schemas with field numbers and annotations, complete SQL trigger code with TOCTOU protection, Go code snippets for reconciler and server handler, specific error codes (InvalidArgument, NotFound, PermissionDenied, FailedPrecondition) for every failure mode. All CRUD lifecycle operations covered. Risks are specific and technical (trigger replacement atomicity, JSONB key case mismatch, migration ordering) with concrete mitigations. Drawbacks section steel-
Testability 2/2 Strong test plan with 12 specific unit test scenarios covering validation, immutability, reconciler behavior, and trigger behavior. 5 integration test scenarios with concrete workflows (lifecycle, deletion protection, catalog defaults, tenant isolation). 3 E2E scenarios following user-observable paths. Graduation criteria present with Dev Preview/Tech Preview/GA stages — Dev Preview criteria are concrete but Tech Preview and GA stages are somewhat vague ('production-hardened with validated deplo
Scope 1/2 Boundaries are clear and PRD is referenced via frontmatter. Non-goals are specific (5 explicit exclusions with rationale). Four real alternatives with balanced pros/cons analysis. However, Goals are framed as implementation tasks ('Replace BareMetalInstanceSpec.image with disk_image', 'Keep the bare-metal-fulfillment-operator CRD unchanged') rather than user-visible outcomes. Summary is 2 sentences rather than the 3-5 guideline. Cross-cutting dimensions from osac-dimensions.md are mostly address
Architecture 2/2 Follows all OSAC patterns. Tenant isolation enforced at application layer with database-level referential integrity as backup. Proto changes use reserved field numbers for removed fields, follow standard object shape. Reconciler follows existing patterns — DiskImage resolution injected as templateParameters, keeping operator CRD unchanged. Dependencies clearly identified: OSAC-2540 must merge first, migration ordering enforced. Cross-component analysis correct: changes contained within fulfillme

Verdict: A thorough, well-structured design that follows OSAC patterns with deep implementation detail; held back from a perfect score by goals framed as implementation tasks rather than user-visible outcomes.

Feedback: Reframe the Goals section as user-visible outcomes rather than implementation tasks — e.g., 'Tenants select base OS images from a governed DiskImage catalog when provisioning bare-metal instances' rather than 'Replace BareMetalInstanceSpec.image with disk_image'. Expand the Summary to 3-5 sentences covering what's added, why it's valuable, and key capabilities. Consider resolving the JSONB key case ambiguity (snake_case vs camelCase in the trigger SQL) before merge rather than leaving it as a documented risk — this is a correctness issue that integration tests should catch early.

Critical (0)

None.

Important (3)

  1. Goals are implementation tasks rather than user-visible outcomes. All five goals describe internal changes ('Replace BareMetalInstanceSpec.image with disk_image', 'Keep the CRD unchanged', 'Extend deletion protection via database triggers'). Reframe as tenant/admin-visible outcomes: 'Tenants select base OS images from a governed catalog', 'DiskImage deletion is blocked when bare-metal resources reference it'.
  2. Summary is 2 sentences, below the 3-5 sentence guideline. Missing: why this is valuable (governance gap), key capabilities (lifecycle validation, deletion protection, catalog defaults).
  3. JSONB key case ambiguity is documented as a risk but should be resolved before merge. The trigger uses snake_case (data->'spec'->>'disk_image') while OSAC-2540 uses camelCase (data->'spec'->>'diskImage'). This is a correctness issue — if wrong, the deletion trigger silently fails to protect bare-metal instances.

Suggestions (3)

  1. Graduation criteria for Tech Preview ('validated in multi-tenant environment') and GA ('production-hardened with validated deployment feedback') could be more measurable — specify concrete conditions like 'N tenants with isolated DiskImage catalogs' or 'zero deletion-protection bypasses in staging'.
  2. The installation dimension from osac-dimensions.md is not explicitly addressed. While no CRD or Helm changes are needed, stating 'Installation: N/A — no CRD changes, no new Helm values, no new prerequisites' would close the gap.
  3. Consider noting in the workflow description what happens to existing BareMetalInstances with the old 'image' field at upgrade time — the Upgrade/Downgrade section covers this but a brief note in the workflow would prevent reviewer questions.

Review cost

Model: claude-opus-4-6
Cost: $0.9381
Tokens: 10 in / 6.8k out
Cache: 197.5k read
Active time: 2m 35s
API calls: 0

@github-actions github-actions Bot added the rfe-creator-auto-reviewed EP was reviewed by AI label Aug 7, 2026

@avishayt avishayt 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.

Two minor items, neither blocking — approve after addressing:

1. UX Alignment: @temp-api file exists

The section states "No @temp-api file exists at osac-ux/libs/ui-components/src/api/v1/baremetal-instance.ts" — but this file does exist. It defines useCreateBareMetalInstance with a hardcoded spec shape that will need diskImage added. The generated @osac/types will pick up the proto field automatically via pnpm gen-types, but the hardcoded mutation body in the hooks file needs a manual update. Please correct the section and add a brief mapping note (proto disk_image → TS diskImage).

2. Documentation dimension

This is a breaking public API change (removing BareMetalInstanceSpec.image, adding disk_image). Please add a line addressing whether API docs / CLI help text updates are in scope or deferred.

- UX Alignment: correct claim that @temp-api file doesn't exist;
  baremetal-instance.ts exists and useCreateBareMetalInstance needs
  diskImage added to its hardcoded spec type. Add field mapping table
  (proto disk_image → TS diskImage).
- Documentation: add Documentation subsection noting REST API reference,
  CLI help text (--image/--image-source-type → --disk-image), and
  migration notes are in scope; full docs deferred to GA.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@adriengentil

Copy link
Copy Markdown
Contributor Author

Both items addressed in 629e7cd:

  1. UX Alignment: Corrected — baremetal-instance.ts exists. The section now documents that @osac/types is updated automatically via pnpm gen-types, but useCreateBareMetalInstance's hardcoded spec type needs a manual diskImage?: string addition. Added the field mapping table (proto spec.disk_image → TS spec.diskImage).

  2. Documentation: Added a ### Documentation subsection noting that REST API reference, CLI help text (--image/--image-source-type → --disk-image), and migration notes are in scope. Full user-facing documentation deferred to GA per graduation criteria.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@openshift-ci openshift-ci Bot added lgtm and removed lgtm labels Aug 10, 2026
@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Exceptionally detailed implementation: names exact functions (validateAndApplyCatalogItem, mutateBMI, applyFieldDefinitions), specifies all error codes (InvalidArgument, NotFound, FailedPrecondition, PermissionDenied), provides full proto schemas with field numbers and annotations, complete SQL migration with bidirectional triggers and FOR SHARE locking, and covers all lifecycle operations (create, get, list, update-immutability, delete-protection). Risks are specific technical risks (trigger re
Testability 2/2 Comprehensive test plan at all three levels: 12 specific unit test scenarios (required validation, not-found, obsolete, deprecated, tenant visibility, catalog item defaults, immutability, catalog item validation, reconciler resolution, reconciler error, deletion trigger, insertion trigger), 5 integration tests (full lifecycle, deletion protection for BMI and CatalogItem, CatalogItem default end-to-end, tenant isolation), and 3 E2E scenarios (image selection, catalog default, deprecated warning).
Scope 2/2 Tightly bounded scope with clear PRD reference in frontmatter. Five specific non-goals with rationale (custom upload, in-place upgrade, template field, guest_os_family, DiskImage changes). Four real alternatives with detailed pros/cons and rejection rationale (coexistence, template defaults, CRD extension, separate triggers). Cross-cutting dimensions addressed: BMaaS (primary), Provisioning (reconciler path), Documentation (CLI/API/migration notes), UI (UX Alignment section with field mapping),
Architecture 2/2 Follows all OSAC patterns: proto field reservation for removed fields, IMMUTABLE annotation on disk_image, standard object shape, spec-only user fields. Tenant isolation validated at application layer (visibility check) and database layer (FOR SHARE locking). Controller pattern preserved (reconciler resolves DiskImage, injects as templateParameter). No CRD changes needed — operator is unchanged. Dependencies clearly identified (OSAC-2540 must merge first, migration ordering). Breaking change cal

Verdict: An exemplary design document that provides deep, implementation-ready technical detail while maintaining tight scope boundaries, following all OSAC architectural patterns, and including a comprehensive multi-level test plan.

Feedback: The design is strong across all dimensions. Two minor improvements: (1) GA graduation criteria could be more measurable — 'production-hardened with validated deployment feedback' is vague compared to the concrete Dev Preview and Tech Preview conditions; consider specifying metrics thresholds or minimum deployment duration. (2) The reconciler fetches DiskImage source_ref at reconciliation time, meaning a DiskImage's source_ref update would silently change the imageURL on next reconciliation of existing BareMetalInstances — document whether this is intentional behavior or whether source_ref is also immutable on DiskImage.

Critical (0)

None.

Important (0)

None.

Suggestions (3)

  1. GA graduation criteria ('production-hardened with validated deployment feedback') is vaguer than the Dev Preview and Tech Preview criteria. Consider adding measurable conditions such as 'zero P1 bugs for N weeks' or 'successful multi-tenant deployment with M tenants'.
  2. The reconciler resolves DiskImage source_ref at reconciliation time. If DiskImage source_ref is mutable, updating it would change the imageURL for existing BareMetalInstances on next reconcile — clarify whether this is intentional or whether source_ref immutability is guaranteed by OSAC-2540.
  3. The JSONB key casing risk (snake_case disk_image vs camelCase diskImage) is well-identified with a mitigation to verify before merge. Consider adding the specific verification step (e.g., 'inspect DAO serialization in generic_dao.go' or 'check a persisted row') directly in the Implementation Details to make it easier for implementors to follow.

Review cost

Model: claude-opus-4-6
Cost: $0.6483
Tokens: 6 in / 4.9k out
Cache: 172.4k read
Active time: 1m 54s
API calls: 0

@adriengentil
adriengentil marked this pull request as ready for review August 11, 2026 08:47
@openshift-ci
openshift-ci Bot requested review from jhernand and tzvatot August 11, 2026 08:47
@adriengentil

Copy link
Copy Markdown
Contributor Author

@avishayt the fix mentioned in my comment above was not part of this PR 🤦‍♂️

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 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 `@enhancements/OSAC-1270-base-os-management-bmaas/design.md`:
- Around line 311-317: Add a catalog-item write trigger alongside the existing
deletion-reference check that extracts referenced DiskImage IDs from
catalog-item inserts and updates, then acquires FOR SHARE locks on each
referenced DiskImage before the write completes. Cover both insert and update
paths, and add concurrency tests proving catalog-item creation cannot race with
DiskImage deletion; preserve existing deletion validation and error behavior.
- Around line 513-516: The downgrade procedure must restore OSAC-2540’s
check_disk_image_not_in_use function and deletion trigger before removing
BMaaS-specific database additions. Update the migration rollback steps to
preserve deletion protection for compute resources, removing only the BMaaS
changes rather than leaving the original trigger and function absent.
- Around line 511-518: Add an upgrade migration path for persisted legacy inline
images in the reconciliation and instance-creation flows: preserve reading
BareMetalInstanceSpec.image and BareMetalInstanceTemplateSpecDefaults.image,
convert or backfill them to governed DiskImages and disk_image references, or
add a preflight check that blocks upgrades when such data exists. Update the
upgrade strategy and tests to cover pending instances and existing templates.
- Line 537: Update the fenced code block containing the osac baremetal-instances
command to use the shell language identifier, changing the opening fence to
```shell while preserving the command and closing fence.
- Around line 115-125: Define a repeated warnings field on the private
BareMetalInstancesCreateResponse and specify the mapping from private to public
responses so PrivateBareMetalInstancesServer.Create() warnings are preserved.
Also document warning propagation for CatalogItem Create and Update, including
how those warnings reach the API caller without being dropped.
- Around line 520-524: Correct the Version Skew Strategy documentation to state
that reserved field 7 prevents schema reuse but old clients may still send image
as an unknown wire field; document the server’s unknown-field handling policy,
and specify that InvalidArgument is returned only when disk_image is absent. Add
a compatibility test covering an old client sending image to a new server.
- Around line 279-317: Verify the persisted JSONB key casing used by
compute_instances, compute_instance_templates, bare_metal_instances, and both
catalog-item resources before finalizing the deletion trigger; align each JSONB
lookup with the actual stored schema rather than assuming camelCase or
snake_case. Add integration tests that create an active reference for each
resource and assert that deleting the referenced DiskImage raises the expected
protection error.
🪄 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: c552d7d1-8099-451d-864e-8e6ba3b0bf59

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2722a and f37b5a7.

📒 Files selected for processing (1)
  • enhancements/OSAC-1270-base-os-management-bmaas/design.md

Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md Outdated
- Add warnings field to private BareMetalInstancesCreateResponse and
  to catalog-item create/update responses (public and private); document
  private-to-public propagation
- Document FOR SHARE locking in validateFieldDefinitionsDiskImage for
  catalog-item write-side TOCTOU protection; explain why DB trigger is
  impractical for opaque field_definitions JSONB
- Add integration tests for compute resource deletion protection
  (regression), JSONB key casing verification requirement, and
  write-side TOCTOU tests for BareMetalInstance and CatalogItem
- Fix upgrade strategy: document that pending instances with spec.image
  but no disk_image fail reconciliation after upgrade; add preflight
  requirement
- Fix downgrade strategy: down migration must recreate OSAC-2540's
  original trigger (not remove it entirely) before dropping BMaaS
  additions
- Fix version skew: reserved field 7 causes unknown-field discard, not
  InvalidArgument; server returns InvalidArgument only when disk_image
  is absent; add compatibility test requirement
- Add shell language identifier to fenced code block (MD040)

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@github-actions

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Exceptional implementation depth: full proto schema changes with field numbers and annotations, Go code snippets for server and reconciler, complete SQL trigger and migration code. Error codes specified per validation step. TOCTOU protection via FOR SHARE locking. Risks are specific (JSONB key case mismatch, trigger replacement atomicity, migration ordering) with concrete mitigations. Drawbacks section steel-mans governance burden, reconciler latency, and trigger coupling.
Testability 2/2 12 specific unit test cases covering validation, error codes, immutability, reconciler behavior, and trigger behavior. 8 integration scenarios including TOCTOU verification and cross-resource regression testing (confirms compute protections survive trigger replacement). 3 E2E scenarios covering image selection, CatalogItem defaults, and deprecated image warnings. Graduation criteria have measurable conditions per Dev Preview / Tech Preview / GA stage.
Scope 2/2 Clear boundaries with PRD reference in frontmatter and inline link. Five specific non-goals each with rationale (custom upload, in-place upgrade, template disk_image, guest_os_family, DiskImage API changes). Four real alternatives with pros/cons and rejection rationale. Relevant cross-cutting dimensions addressed: BMaaS service, provisioning, documentation (with GA deferral), UI (UX Alignment with field mapping), E2E testing. Installation correctly skipped per triage rule (no CRD/Helm changes).
Architecture 2/2 All OSAC patterns followed: proto reserved fields for removed message, IMMUTABLE annotation, owner reference correctly omitted (DiskImage has no parent resource), tenant isolation validated at application layer, controller-runtime reconciler pattern for DiskImage resolution. Dependencies clearly enumerated within the mono-repo (fulfillment-service proto + server + reconciler + migration). Breaking change migration well-documented with reserved field numbers for wire compatibility. Terminology co

Verdict: A very strong design document with exceptional implementation depth, clear scope boundaries, comprehensive test coverage, and full alignment with OSAC architectural patterns — one of the better-calibrated designs for a narrow integration feature.

Feedback: Minor improvements: the Summary section is only 2 sentences where the template recommends 3-5 — consider expanding to explicitly state the key capabilities (governed image catalog for BMaaS, deletion protection, CatalogItem defaults). Goals are implementation-focused ('Replace BareMetalInstanceSpec.image with disk_image') rather than user-visible outcomes ('Enable tenants to select pre-approved OS images from a curated catalog'); rewording would better align with the rubric. The JSONB key case mismatch risk is well-identified — consider adding an explicit pre-merge verification step to the integration test plan (e.g., 'inspect persisted row to confirm actual JSONB key before running trigger tests').

Critical (0)

None.

Important (0)

None.

Suggestions (4)

  1. Summary section is 2 sentences; template recommends 3-5 — expand to cover key capabilities (governed catalog, deletion protection, CatalogItem defaults).
  2. Goals are implementation tasks ('Replace BareMetalInstanceSpec.image with disk_image') rather than user-visible outcomes ('Tenants select from a governed DiskImage catalog when provisioning bare metal'). Consider rewording to lead with user value.
  3. The JSONB key case mismatch risk (snake_case vs camelCase) is acknowledged with a mitigation note, but adding an explicit pre-merge verification step to the integration test plan would strengthen confidence — e.g., a setup step that inspects a persisted row's actual JSONB structure before asserting trigger behavior.
  4. Consider briefly noting Cloud Infrastructure Admin's relationship to this feature (e.g., 'Cloud Infrastructure Admins manage the infrastructure that DiskImages reference but are not directly impacted by this integration') for completeness in persona coverage.

Review cost

Model: claude-opus-4-6
Cost: $1.0135
Tokens: 12 in / 6.0k out
Cache: 334.0k read
Active time: 2m 23s
API calls: 0

Replace implementation-framed goals with user-value-led statements:
tenants selecting from a catalog, admins governing lifecycle, actionable
feedback on deprecated/obsolete images, deletion protection, and
catalog-defaulted images.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@adriengentil

Copy link
Copy Markdown
Contributor Author

Good call. Rewrote the Goals section to lead with user-visible outcomes (tenants selecting from a governed catalog, admins governing lifecycle, actionable feedback on deprecated/obsolete images, deletion protection, catalog-defaulted provisioning) rather than implementation tasks. Applied in the latest commit.

@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Deep technical detail throughout: full proto schema changes with field numbers and annotations, concrete Go code for reconciler DiskImage resolution, complete SQL trigger functions with FOR SHARE locking for TOCTOU protection, specific error codes per failure mode (InvalidArgument, NotFound, PermissionDenied, FailedPrecondition), named source files and functions (mutateBMI, validateAndApplyCatalogItem, applyFieldDefinitions). All lifecycle operations covered — create with DiskImage validation, i
Testability 2/2 Excellent test plan with 12 unit tests, 8 integration tests, and 3 E2E tests — all with specific scenarios and expected assertions. Unit tests cover DiskImage validation (required, not found, obsolete, deprecated, tenant visibility), CatalogItem default application, immutability enforcement, reconciler DiskImage resolution, and migration trigger behavior with specific SQLSTATEs (Z0003, Z0002). Integration tests include TOCTOU protection (concurrent create + soft-delete), deletion protection regr
Scope 2/2 Well-bounded scope: replaces inline image field with DiskImage reference and extends deletion protection to BMaaS — narrow integration point clearly stated. Summary is concise (3 sentences). Goals are user-visible outcomes (governed catalog selection, lifecycle feedback, deletion protection). Five specific non-goals with clear rationale (custom upload, in-place upgrade, template defaults, guest_os_family, DiskImage API changes). Four real alternatives analyzed with pros/cons and explicit rejecti
Architecture 2/2 All OSAC patterns followed. Tenant isolation enforced at application layer (DiskImage visibility: global or same-tenant) and documented in RBAC section. No new owner-reference needed — DiskImage has no parent resource, consistent with OSAC-2540. API conventions followed: disk_image in spec (desired state, immutable), source_ref resolved by reconciler (system-controlled), standard response with warnings field matching ComputeInstancesCreateResponse pattern. Proto schema uses reserved field number

Verdict: A thorough, implementation-ready design that follows all OSAC patterns with deep technical specificity — proto schemas, SQL triggers, Go code, concrete error codes, and a comprehensive test plan covering unit, integration, and E2E levels with specific scenarios.

Feedback: The design is strong across all dimensions. Two minor improvements: (1) Resolve the JSONB key casing uncertainty (snake_case disk_image vs camelCase diskImage) definitively in the design rather than deferring to implementation — inspect existing bare_metal_instances rows or the DAO serialization code now and pin the correct key in the trigger SQL. (2) The Observability section could note whether existing dashboards or alerts would surface DiskImage resolution failures during reconciliation, or whether operators should add a specific alert rule for the 'failed to fetch disk image' error pattern described in Support Procedures.

Critical (0)

None.

Important (1)

  1. JSONB key casing is flagged as a risk but not resolved: the trigger uses data->'spec'->>'disk_image' (snake_case) while OSAC-2540 uses camelCase for compute resources. The design asks implementors to 'verify the actual JSONB key by inspecting a persisted bare_metal_instances row' — resolving this before merge review would eliminate a class of silent failure where the deletion trigger silently does not match any rows.

Suggestions (2)

  1. Observability section says 'no new observability changes' but the design adds a reconciler DB round-trip that can fail with 'failed to fetch disk image'. Consider noting whether existing controller metrics and structured logs are sufficient for operators to detect this failure mode in production monitoring, or whether a dedicated alert rule should be recommended in Support Procedures.
  2. Graduation criteria GA stage ('production-hardened with validated deployment feedback, documentation complete') would benefit from more measurable conditions — e.g., 'all Support Procedures scenarios exercised in staging, CLI help text updated, REST API reference published'.

Review cost

Model: claude-opus-4-6
Cost: $0.7487
Tokens: 10 in / 7.5k out
Cache: 248.0k read
Active time: 2m 53s
API calls: 0

OSAC-2540's design is the source of truth: compute resources use
camelCase (diskImage/specDefaults), bare-metal resources use snake_case
(disk_image). Remove 'implementors must verify' hedges; update Risk
entry and integration test note accordingly.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Exceptionally specific implementation detail. Proto schemas shown with field numbers, types, and annotations. Server handler changes name exact functions (validateAndApplyCatalogItem, applyFieldDefinitions, validateSpec, mutateBMI) with step-by-step validation logic and specific gRPC error codes (InvalidArgument, NotFound, PermissionDenied, FailedPrecondition). Database migration includes complete SQL for index creation, extended deletion-protection trigger, and write-side TOCTOU trigger with FO
Testability 2/2 Comprehensive test plan at all three levels. Unit tests: 12 specific scenarios covering DiskImage validation (required, not found, obsolete, deprecated), tenant visibility, CatalogItem defaults, immutability enforcement, reconciler resolution, and database triggers (both deletion and insertion). Integration tests: 9 scenarios including full lifecycle with DiskImage, deletion protection for both BareMetalInstance and CatalogItem, compute regression testing (confirms extended trigger still protect
Scope 2/2 Well-bounded design that integrates an existing resource (DiskImage from OSAC-2540) into an existing path (BMaaS provisioning). Summary concisely states what's added, why, and key capabilities. Goals are user-visible outcomes (tenants select from catalog, admins manage lifecycle, warnings on deprecated images). Five specific non-goals with clear rationale (e.g., 'Adding disk_image to BareMetalInstanceTemplate — defaults are carried on the CatalogItem'). Four real alternatives with specific pros/
Architecture 2/2 All OSAC patterns followed precisely. Tenant isolation enforced at application layer (visibility check) and database layer (triggers with FOR SHARE locking). Proto schema changes follow standard object shape with proper field reservation (field 7 reserved, field 10 added as IMMUTABLE). Controller pattern maintained — reconciler resolves DiskImage and injects source_ref as imageURL template parameter, keeping the CRD and operator unchanged. Dependencies clearly enumerated: OSAC-2540 must land fir

Verdict: This is a high-quality design document that demonstrates deep familiarity with OSAC patterns, provides implementation-ready detail (proto schemas, SQL triggers, Go code), clearly bounds its scope relative to OSAC-2540, and includes a thorough multi-level test plan — scoring full marks across all four criteria.

Feedback: The design is ready for merge as-is. Two minor polish opportunities: (1) the Summary could expand from one sentence to 3-5 sentences to better match the template guidance — explicitly listing key capabilities (governed catalog selection, lifecycle warnings, deletion protection, CatalogItem defaults) would help readers who skim. (2) The Installation dimension could get an explicit one-line 'No installation changes required — no new CRDs, operators, or Helm values are introduced' to preempt reviewer questions, even though the answer is obvious from context.

Critical (0)

None.

Important (0)

None.

Suggestions (3)

  1. Summary section is a single sentence — the template guidance suggests 3-5 sentences covering what's added, why it's valuable, and key capabilities. Expanding it slightly would improve scannability for reviewers who read only the top of the document.
  2. The Installation cross-cutting dimension is not explicitly addressed. While no installation changes are needed (no new CRDs, operators, or Helm values), adding a one-line statement would preempt reviewer questions and follow the osac-dimensions.md guidance to 'address or explicitly defer' relevant dimensions.
  3. The Upgrade/Downgrade Strategy notes that existing BareMetalInstances with spec.image must be 'resolved before upgrade' but doesn't mention whether a pre-upgrade script or migration hook could automate this detection — consider suggesting 'osac baremetal-instances list --filter' as a pre-upgrade verification step for operators.

Review cost

Model: claude-opus-4-6
Cost: $0.7534
Tokens: 9 in / 4.2k out
Cache: 387.6k read
Active time: 1m 52s
API calls: 0

@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Implementation details are highly specific: full proto schema changes with field numbers and annotations, complete SQL DDL for triggers and indexes, Go code snippets for the reconciler and server changes, and specific error codes for every failure path (InvalidArgument, NotFound, FailedPrecondition, PermissionDenied). TOCTOU protection is addressed with FOR SHARE locking matching OSAC-2540's pattern. All lifecycle operations are covered: create (with DiskImage validation), get/list (inherited fr
Testability 2/2 Test plan is comprehensive at all three levels. Unit tests: 12 specific scenarios covering DiskImage validation (required, not found, OBSOLETE, DEPRECATED, tenant visibility), CatalogItem defaults, immutability enforcement, reconciler resolution, and DB trigger behavior. Integration tests: 8 scenarios including full lifecycle, deletion protection for both BareMetalInstances and CatalogItems, compute regression verification, JSONB casing regression, TOCTOU concurrency tests, catalog default end-t
Scope 2/2 Well-bounded scope: integrates an existing DiskImage resource (OSAC-2540) into the BMaaS provisioning path. PRD referenced in frontmatter and inline. Five specific non-goals with clear reasoning (custom upload, in-place OS upgrade, template field, guest_os_family exposure, DiskImage API changes). Four real alternatives considered with substantive pros/cons and rationale for rejection. All relevant cross-cutting dimensions addressed: BMaaS service, personas (Cloud Provider Admin, Tenant Admin, Te
Architecture 2/2 All OSAC patterns followed correctly. Tenant isolation is enforced at the application layer (visibility check) and inherited from existing generic server filtering. Owner reference absence is justified (DiskImage has no parent resource, consistent with OSAC-2540). Spec/status separation is correct: disk_image is spec (user-controlled, immutable), source_ref resolution is system-side in the reconciler. Dependencies are clearly enumerated: fulfillment-service (proto + server + reconciler + migrati

Verdict: This is an exceptionally well-crafted design document that follows all OSAC patterns, provides deep implementation detail (full proto schemas, SQL DDL, Go code), covers all lifecycle operations with specific error codes, and includes a comprehensive test plan at all levels — earning full marks across all four criteria.

Feedback: The summary section should be expanded from one sentence to 3-5 sentences per template guidance — cover what's added, why it's valuable, and key capabilities separately. Graduation criteria for Tech Preview and GA stages would benefit from more measurable conditions (e.g., 'multi-tenant DiskImage isolation passes E2E with N concurrent tenants' rather than 'validated in multi-tenant environment'). Minor: the CLI changes (replacing --image/--image-source-type flags with --disk-image) are mentioned in Documentation but not detailed in Implementation Details — consider adding a brief CLI implementation section or noting it follows existing CLI patterns.

Critical (0)

None.

Important (0)

None.

Suggestions (4)

  1. Summary is one sentence; template guidance recommends 3-5 sentences covering what's added, why, and key capabilities
  2. Graduation criteria for Tech Preview ('validated in multi-tenant environment') and GA ('production-hardened with validated deployment feedback') could be more measurable — specify concrete pass/fail conditions
  3. CLI implementation (--image → --disk-image flag replacement) is mentioned in Documentation but not detailed in Implementation Details — consider adding a brief section or referencing the existing CLI command pattern
  4. The UX Alignment section claims a temp-api file exists at osac-ux but does not discuss whether the UI work is in scope for this milestone or deferred — consider clarifying the UI timeline

Review cost

Model: claude-opus-4-6
Cost: $0.5556
Tokens: 10 in / 5.3k out
Cache: 501.2k read
Active time: 2m 12s
API calls: 0

- Add CLI implementation section: --image/--image-source-type →
  --disk-image flag replacement, following the kubectl-style pattern
  and referencing the compute instance precedent from OSAC-2540
- Clarify UI scope in UX Alignment: form changes deferred until
  OSAC-2540's DiskImage picker component is available; @osac/types
  update (pnpm gen-types) can land with the backend

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@adriengentil

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Aug 11, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 Exceptionally detailed: proto schemas with field numbers and annotations, Go code snippets for reconciler changes, full SQL for database triggers/indexes, specific error codes for every failure path, sequence diagram, and concrete data structure names. All lifecycle operations covered. Risks are specific and technical (DDL atomicity, UUID substring safety, migration ordering) with concrete mitigations. Drawbacks section steel-mans three arguments. Even identifies a bug in OSAC-2540's JSONB key c
Testability 2/2 Strong test plan with 12 specific unit test scenarios, 9 integration tests (including TOCTOU race condition and compute regression tests), and 3 E2E user-journey scenarios. Graduation criteria present for Dev Preview/Tech Preview/GA, though GA criteria are somewhat generic ('production-hardened with validated deployment feedback').
Scope 2/2 Well-bounded: 5 specific non-goals with rationale, 4 real alternatives with pros/cons, PRD referenced in frontmatter. Cross-cutting dimensions addressed (provisioning, inventory, tenant onboarding, UI, E2E testing, documentation). Summary is slightly under the 3-5 sentence guideline but communicates scope clearly.
Architecture 2/2 Follows all OSAC patterns: standard proto conventions (IMMUTABLE, reserved fields, public/private duplication), correct spec/status ownership, existing reconciler pattern extended, tenant isolation at application layer with DB-level deletion protection. Dependencies on OSAC-2540 clearly identified with migration ordering. Breaking change handled with upgrade/downgrade/version-skew strategies. No new CRDs or cross-repo changes needed.

Verdict: A thorough and implementation-ready design that follows OSAC patterns consistently, provides exceptional technical detail (proto schemas, SQL triggers, Go code, sequence diagrams), and includes a strong test plan with specific scenarios at all levels — one of the strongest designs reviewed against this rubric.

Feedback: Minor improvements: expand the Summary to 3-5 sentences covering key capabilities (currently 1 sentence + PRD link); make GA graduation criteria more measurable (e.g., 'zero DiskImage-related incidents over N days in staging' rather than 'production-hardened'); and add a brief note in Observability about specific log messages or metrics operators should watch for when DiskImage resolution fails in the reconciler (currently says 'no new observability changes' but new failure modes warrant at least naming the existing signals that surface them).

Critical (0)

None.

Important (2)

  1. Graduation criteria for GA are vague ('Production-hardened with validated deployment feedback. Documentation complete.') — should specify measurable conditions like 'zero DiskImage-related reconciler failures in staging over N deployment cycles' or 'all CRUD + deletion-protection paths validated in a multi-tenant staging environment'.
  2. Summary is 1 sentence rather than the template-recommended 3-5 sentences — should expand to cover key capabilities (DiskImage reference replaces inline image, lifecycle validation with warnings, deletion protection, CatalogItem defaults) so readers get the full picture without reading the Motivation section.

Suggestions (3)

  1. The Observability section states 'No new observability changes' but the design introduces a new reconciler failure mode (DiskImage resolution failure causing requeue). Consider naming the specific existing metrics and log fields that surface this (e.g., controller reconciliation error counter, structured log fields) so operators know what to watch.
  2. The reconciler requeues indefinitely when DiskImage resolution fails. Consider noting whether controller-runtime's default exponential backoff is sufficient or whether a max-requeue or condition-based alert should be added for stuck BareMetalInstances.
  3. Consider adding an explicit Terminology subsection defining 'DiskImage', 'source_ref', 'imageURL', and 'field_definitions' for readers unfamiliar with OSAC-2540's vocabulary — terms are used consistently but never formally defined in this document.

Review cost

Model: claude-opus-4-6
Cost: $0.7054
Tokens: 10 in / 6.9k out
Cache: 217.3k read
Active time: 2m 34s
API calls: 0

@adriengentil

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…umbers

Remove server handler logic, reconciler Go code, CLI flag details, and
SQL migrations. Keep proto schema changes only, without field numbers.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@openshift-ci-robot

openshift-ci-robot commented Aug 14, 2026 •

Copy link
Copy Markdown

@adriengentil: This pull request references OSAC-1270 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 feature to target the "5.1.0" version, but no target version was set.

Details

In response to this:

Design: Base OS Management for Bare Metal Instances

Jira: https://redhat.atlassian.net/browse/OSAC-1270
PRD: prd.md

Summary

This design integrates the DiskImage resource (OSAC-2540) into the BMaaS provisioning path. BareMetalInstanceSpec.image (inline OCI URL) is replaced by a disk_image reference to a governed DiskImage. The fulfillment-service reconciler resolves the DiskImage's source_ref and injects it as imageURL in the template parameters — no changes to the bare-metal-fulfillment-operator CRD or osac-aap provisioning templates. DiskImage deletion protection is extended to bare_metal_instances and bare_metal_instance_catalog_items via an updated database trigger.

Requesting Review On

  • Trigger replacement approach — the check_disk_image_not_in_use function from OSAC-2540 is dropped and recreated with BMI table checks added; reviewers should verify this is safe and consistent with how the instance_type trigger was handled in migration 56.
  • JSONB key casing — the design notes that the BMI trigger uses snake_case (disk_image) consistent with the existing instance_type trigger, while OSAC-2540 uses camelCase (diskImage) for compute resources. Implementors should verify the actual JSONB key before applying.
  • No disk_image on BareMetalInstanceTemplate — defaults are carried only on BareMetalInstanceCatalogItem.field_definitions. This is a locked decision from the PRD; reviewers should flag if this is too restrictive for operator workflows.
  • guest_os_family not forwarded to AAP — the DiskImage's OS family is not injected as a template parameter. Reviewers should confirm the BMaaS provisioning templates do not need it today.

Documents

  • design.md — technical design document

How to Review

  • Comment inline on specific sections
  • Approve when the design accurately reflects a viable implementation approach

Summary by CodeRabbit

  • New Features

  • Bare-metal instances can use governed, immutable DiskImage references instead of inline image URLs.

  • CatalogItem defaults can automatically provide a DiskImage reference.

  • Image references are validated for existence, visibility, and lifecycle status.

  • Create and CatalogItem responses include warnings for deprecated or invalid image usage.

  • DiskImage references are resolved consistently during instance reconciliation.

  • Bug Fixes

  • Prevents deletion of images still referenced by bare-metal instances.

  • Preserves selected image references throughout the instance lifecycle.

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.

@github-actions

github-actions Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 The design is technically solid. It builds on the well-defined OSAC-2540 DiskImage pattern with a narrow integration point: the fulfillment-service reconciler resolves the DiskImage source_ref and injects it as imageURL in template parameters — no CRD, operator, or AAP changes needed. The trigger replacement approach (DROP + CREATE within a single migration transaction) is atomic in PostgreSQL and follows the established instance_type trigger pattern. The dependency chain on OSAC-2540 is clearly
Testability 2/2 One of the strongest test plans reviewed. Unit tests cover all validation paths (required field, not found, obsolete, deprecated, tenant visibility, catalog item defaults, immutability). Integration tests include deletion protection regression for compute resources (ensuring the trigger replacement doesn't break OSAC-2540), TOCTOU concurrency races with FOR SHARE locking, JSONB key casing verification, and end-to-end catalog item default resolution. E2E tests cover the provisioning golden path,
Scope 2/2 Well-defined boundaries with clear goals and non-goals. The design explicitly states what changes (API, server, reconciler, DB trigger) and what does not (CRD, operator, AAP templates). UX alignment section identifies the specific UI changes needed with a field mapping table. Documentation scope is defined inline. Upgrade/downgrade strategy is thorough, including the requirement to handle existing BareMetalInstances with the old image field before upgrade.
Architecture 2/2 Follows established OSAC patterns throughout: DiskImage reuse from OSAC-2540, template parameter injection for operator integration, database-level deletion protection with triggers, application-level tenant isolation, and warnings on create responses. Alternatives are well-considered with honest trade-off analysis. The single-trigger consolidation approach is justified over separate triggers. The decision to not add disk_image to BareMetalInstanceTemplate (carrying defaults only on CatalogItem

Verdict: A well-crafted design that cleanly extends the OSAC-2540 DiskImage pattern to BMaaS with narrow, well-understood integration points, comprehensive test coverage, and strong adherence to established OSAC architectural patterns.

Feedback: The proto snippet (Implementation Details) reserves only the name 'image' but not the field number — add 'reserved 7;' alongside 'reserved "image";' and include the field number assignment for disk_image (field 10) in the snippet, since the Version Skew section references these numbers but the proto code doesn't show them. The JSONB key casing discrepancy flagged in the PR description (OSAC-2540 indexes use camelCase 'diskImage' while this design's test plan asserts 'all snake_case' enforced by UseProtoNames: true) should be resolved in the design text itself — either confirm the casing after checking the actual DAO serialization, or note it as an implementation-time verification step rather than asserting snake_case as fact. Consider adding a brief note in Risks about what happens if OSAC-2540 changes its trigger function signature after OSAC-1270 merges — since the coupling is at the DB function level, a future OSAC-2540 refactor could silently break BMaaS deletion protection.

Critical (0)

None.

Important (2)

  1. JSONB key casing inconsistency: OSAC-2540 design shows camelCase JSONB indexes (data->'spec'->>'diskImage') while this design's test plan (line 342) asserts 'all snake_case: disk_image' enforced by UseProtoNames: true. The PR description flags this as a review point, but the design body should not assert snake_case as fact until the actual DAO serialization is verified — one of these designs has the wrong casing, and a mismatch would cause the deletion trigger to silently miss references.
  2. Proto snippet omits field number reservation: the Implementation Details proto snippet shows 'reserved "image"' but not 'reserved 7;', and does not show the field number for disk_image (which the Version Skew section identifies as field 10). Implementers following only the proto snippet would miss the numeric reservation, risking wire-format reuse of field 7.

Suggestions (2)

  1. Add a Risks entry for forward-coupling to OSAC-2540's trigger: if OSAC-2540 later refactors check_disk_image_not_in_use (e.g., changing its signature, splitting it, or moving to a different migration), the BMaaS additions could be silently dropped. A brief note suggesting that the trigger function include a version comment or that both designs document the shared function contract would help future maintainers.
  2. The Drawbacks section mentions 'one reconciler DB round-trip' but could quantify the expected latency — even a rough estimate (e.g., '<5ms for a single-row PK lookup') would help reviewers judge whether this is truly negligible or worth caching.

Review cost

Model: claude-opus-4-6
Cost: $2.0920
Tokens: 5.3k in / 13.1k out
Cache: 1.1M read
Active time: 4m 27s
API calls: 0

reserved "image" alone doesn't prevent number reuse — add reserved 7/1
to BareMetalInstanceSpec and BareMetalInstanceTemplateSpecDefaults.
Remove stale field 10 reference from Version Skew section.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@github-actions

github-actions Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 All technical claims verified against the codebase: BareMetalInstanceSpec.image (field 7) exists, check_disk_image_not_in_use trigger covers only compute resources (confirmed extension needed), mutateBMI reconciler already injects imageURL via templateParameters, ComputeInstancesCreateResponse.warnings pattern exists to follow, BareMetalInstanceCatalogItem.field_definitions mechanism exists. The approach of resolving DiskImage in the reconciler and injecting source_ref as imageURL is sound and r
Testability 2/2 Comprehensive three-tier test plan: 12 specific unit test scenarios covering validation paths, immutability, CatalogItem defaults, reconciler resolution, and migration triggers; 8 integration tests including TOCTOU race conditions, compute regression after trigger replacement, JSONB key casing regression, and tenant isolation; 3 E2E tests covering the provisioning flow, catalog defaults, and deprecated image warnings. Scenarios are specific enough to implement directly.
Scope 2/2 Well-bounded: integrates DiskImage (OSAC-2540) into BMaaS without modifying DiskImage itself. Non-goals are explicit and justified (no template support, no guest_os_family forwarding, no tenant upload). Breaking API change is acknowledged with upgrade/downgrade steps. UI scope and documentation scope are stated. Dependency on OSAC-2540 merging first is clearly declared. Four alternatives considered and rejected with reasoning.
Architecture 2/2 Follows established OSAC patterns: reuses DiskImage lifecycle from OSAC-2540, warnings pattern from ComputeInstances, templateParameters injection, CatalogItem field_definitions defaults, FOR SHARE TOCTOU protection. Maintains clean separation between fulfillment-service and bare-metal-fulfillment-operator. Proto conventions followed (reserved fields, IMMUTABLE behavior). Trigger coupling to OSAC-2540 is acknowledged as a drawback. Security model correctly inherited.

Verdict: A thorough, well-structured design that correctly maps to the existing codebase, follows established OSAC patterns, and provides a comprehensive test plan — minor gaps around imageSourceType handling and JSONB key casing resolution are the only notable weaknesses.

Feedback: Two items need explicit resolution before implementation: (1) The design omits what happens to the imageSourceType template parameter — currently mutateBMI injects both imageURL and imageSourceType, but the design only addresses imageURL. State whether imageSourceType is dropped, derived from DiskImage's source_type, or handled another way. (2) The JSONB key casing inconsistency between OSAC-2540 compute triggers (which use diskImage camelCase paths) and this design's snake_case disk_image is flagged in the PR description but not resolved in the design itself — confirm the actual JSONB serialization key before implementing the trigger, and document the expected key in the design.

Critical (0)

None.

Important (2)

  1. The design does not address the imageSourceType template parameter. Currently mutateBMI (baremetalinstance_reconciler_function.go) injects both imageURL and imageSourceType from the inline spec.image field. The design only describes injecting imageURL from DiskImage's source_ref. If imageSourceType is being dropped (since DiskImage abstracts it away), this should be stated explicitly; if it should be derived from DiskImage's source_type, document that path.
  2. JSONB key casing between OSAC-2540's compute triggers and the BMI trigger is inconsistent — the PR description correctly flags this as needing verification, but the design body assumes snake_case without confirming the actual serialization key produced by UseProtoNames:true for the DiskImage reference field. Mismatched keys would silently break deletion protection.

Suggestions (3)

  1. The disk_image field is proposed as optional string (flat ID), while compute instances reference DiskImage via a nested JSONB path (data->'spec'->'disk_image'->>'id'), suggesting a message wrapper. Consider documenting why a flat string is preferred for BMI to avoid confusion during implementation.
  2. The Documentation section mentions replacing --image and --image-source-type CLI flags but only specifies the replacement for --image (--disk-image ). Clarify whether --image-source-type is simply dropped with no replacement.
  3. Source traceability markers (per section-guidance.md) are used well for locked decisions but could be added to a few non-obvious choices, such as the decision to use templateParameters injection rather than a CRD field (which is justified in Alternatives but not traced in the Proposal).

Review cost

Model: claude-opus-4-6
Cost: $1.9337
Tokens: 50 in / 11.4k out
Cache: 1.8M read
Active time: 4m 49s
API calls: 0

mutateBMI currently injects both imageURL and imageSourceType from
spec.image. Explicitly state that imageSourceType is removed since
DiskImage abstracts the source type and AAP templates don't consume it.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@github-actions

github-actions Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 The design is technically sound and builds on proven patterns from OSAC-2540. The integration point is narrow (reconciler injects imageURL as a JSON template parameter), requiring no changes to the bare-metal-fulfillment-operator CRD or osac-aap provisioning templates. Database trigger replacement follows the existing InstanceType pattern with atomic DDL in a single migration transaction. Proto schema changes use proper field reservation. The JSONB key casing discrepancy is correctly flagged as
Testability 2/2 Comprehensive test plan with concrete scenarios across unit, integration, and E2E layers. Covers happy paths, error cases, and edge cases including TOCTOU race conditions, concurrent deletion/creation, and deletion protection regression tests for OSAC-2540's compute protections after trigger replacement. JSONB key casing regression tests are explicitly called out. Each test scenario specifies expected outcomes (SQLSTATE codes, error types, response fields).
Scope 2/2 Well-defined and appropriately sized. The design narrows to extending DiskImage to BMaaS and updating deletion protection — no overreach. Non-goals are clear (no custom upload, no template disk_image field, no guest_os_family forwarding). Breaking API change is acknowledged with upgrade/downgrade strategy. UI scope and documentation scope are explicitly addressed. Hard dependency on OSAC-2540 is declared and ordering enforced via Jira.
Architecture 2/2 Follows established OSAC patterns consistently: InstanceType lifecycle for DiskImage, bidirectional database triggers for deletion protection, generic server for CRUD, FOR SHARE locking for TOCTOU prevention. No new abstractions introduced. Proto conventions are correct (reserved field numbers, reserved names, standard enum naming). Security model inherited without modification — appropriate for the narrow scope. Alternatives are well-analyzed with clear rejection rationale. Coupling risk with O

Verdict: A high-quality, well-structured design that cleanly extends OSAC-2540's DiskImage governance to the BMaaS provisioning path with thorough test coverage, sound architectural decisions, and clear risk identification.

Feedback: The JSONB key casing discrepancy between this design and OSAC-2540 is the most important implementation risk — OSAC-2540's migration SQL uses camelCase keys (diskImage, specDefaults) in JSONB path expressions, while this design's integration tests assert snake_case (disk_image, spec_defaults) based on UseProtoNames: true. Before writing migration SQL, verify the actual persisted keys in the database; a mismatch silently breaks deletion protection with no error at write time. Additionally, the claim that AAP templates do not consume imageSourceType for bare-metal provisioning should be verified with evidence (e.g., grep the AAP role templates) — if any role uses it, dropping it breaks provisioning. Consider including the actual trigger function SQL in the design to make the migration reviewable before implementation.

Critical (0)

None.

Important (2)

  1. JSONB key casing discrepancy: OSAC-2540's migration SQL uses camelCase (diskImage, specDefaults) in JSONB paths, but this design's integration tests assert snake_case (disk_image, spec_defaults) claiming UseProtoNames: true. The design correctly flags this as a review point, but one of the two designs has the wrong casing. A mismatch silently breaks deletion protection — the trigger queries the wrong key path and finds no references, allowing deletion of in-use DiskImages.
  2. imageSourceType removal lacks evidence: The design asserts AAP provisioning templates do not consume imageSourceType for bare-metal, but provides no evidence (no codebase reference, no grep, no link to the AAP role). If any role uses imageSourceType, dropping it from template parameters silently breaks bare-metal provisioning.

Suggestions (3)

  1. Include the actual SQL for the extended check_disk_image_not_in_use trigger function in the Implementation Details section. The current description is prose-only; showing the SQL would make the migration reviewable at design time and catch casing issues early.
  2. Source markers ([PRD], [Locked], [Codebase], [Assumption]) are used for some decisions but absent from others. Key design decisions like 'imageSourceType is dropped' and 'reconciler fetches DiskImage at reconciliation time' would benefit from explicit source attribution per section-guidance.md.
  3. Consider adding a test scenario for the migration down path to validate the downgrade strategy — specifically that OSAC-2540's original trigger function is correctly restored and compute resource deletion protection remains intact after downgrade.

Review cost

Model: claude-opus-4-6
Cost: $0.7257
Tokens: 14 in / 4.5k out
Cache: 574.1k read
Active time: 1m 48s
API calls: 0

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
useCreateBareMetalInstance uses MessageInitShape<typeof BareMetalInstanceSchema>
(generated), not a hardcoded spec. pnpm gen-types handles the hook;
only the form component needs updating.

Assisted-by: Claude Code <noreply@anthropic.com>
Signed-off-by: Adrien Gentil <agentil@redhat.com>
@github-actions

github-actions Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 The design is implementable with clear, specific technical details. Proto schema snippets are concrete with correct reserved-field handling. The database trigger replacement strategy (DROP + CREATE in a single migration transaction) leverages PostgreSQL DDL transactional guarantees. The integration point is narrow — DiskImage resolution in the reconciler injects imageURL as a template parameter the downstream stack already consumes, requiring zero changes to the CRD or AAP templates. TOCTOU prot
Testability 2/2 Comprehensive and specific test plan across all three layers. 12 unit test scenarios cover happy path, all error codes (InvalidArgument, NotFound, FailedPrecondition, PermissionDenied), immutability enforcement, CatalogItem validation, reconciler behavior, and both database triggers (deletion and insertion). 8 integration tests include end-to-end lifecycle, deletion protection with compute regression verification, explicit TOCTOU concurrency tests for both BareMetalInstance and CatalogItem paths
Scope 2/2 Well-bounded scope with clear in/out-of-scope delineation. Non-goals explicitly exclude custom OS upload, in-place upgrades, template disk_image field, guest_os_family forwarding, and DiskImage API changes — each with justification. The breaking change (BareMetalInstanceSpec.image removal) is acknowledged with thorough upgrade/downgrade procedures. UI scope is in-scope for Dev Preview with specific component changes identified. Documentation scope is enumerated. Graduation criteria define Dev Pr
Architecture 2/2 Follows established OSAC patterns consistently. DiskImage integration mirrors the OSAC-2540 VMaaS pattern — governed catalog, lifecycle validation, deletion protection triggers. The narrow integration point (reconciler-only, no CRD changes) minimizes blast radius. Trigger consolidation (single function vs separate triggers) is justified with an alternative considered and rejected. Tenant isolation follows OSAC conventions with application-layer validation plus database-level referential integrit

Verdict: A well-crafted design document that extends an existing pattern (OSAC-2540 DiskImage) to a new resource type (BMaaS) with narrow integration scope, thorough failure handling, comprehensive test coverage, and honest trade-off analysis across four substantive alternatives.

Feedback: The JSONB key casing risk (camelCase vs snake_case due to UseProtoNames: true) is called out in the PR body as a review concern and covered by integration tests, but should also appear in the Risks and Mitigations section — silent deletion-protection failure is serious enough to warrant a documented risk with the mitigation being pre-implementation verification and the explicit regression test. The support procedure for 'DiskImage deletion returns FailedPrecondition' should mention CatalogItem references alongside BareMetalInstance references, since the deletion trigger checks both tables but the resolution steps only show how to find BareMetalInstances.

Critical (0)

None.

Important (1)

  1. JSONB key casing risk (camelCase vs snake_case from UseProtoNames: true) is acknowledged in the PR body and covered by integration tests, but is absent from the design's Risks and Mitigations section. A mismatch silently breaks deletion protection with no error at write time — this warrants a documented risk entry with the mitigation being pre-implementation JSONB key verification and the explicit regression test already in the test plan.

Suggestions (2)

  1. The support procedure for 'DiskImage deletion returns FailedPrecondition' lists only BareMetalInstance lookup steps (osac baremetal-instances list --filter), but the deletion trigger also checks bare_metal_instance_catalog_items. Add a CatalogItem lookup step so support engineers can identify all blocking references.
  2. Consider documenting imageSourceType removal as a risk with a mitigation of verifying AAP bare-metal provisioning templates before implementation, since the PR body explicitly asks reviewers to confirm the templates do not consume it.

Review cost

Model: claude-opus-4-6
Cost: $0.5364
Tokens: 12 in / 5.1k out
Cache: 468.8k read
Active time: 1m 59s
API calls: 0

@carbonin carbonin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Do we want to do any checking or labeling to show that some images can be used only with VMaaS or BMaaS? Do we know this beforehand?


## Proposal

`BareMetalInstanceSpec.disk_image` replaces the inline `image` field as a reference to a DiskImage by ID. At creation time, the server resolves the DiskImage reference (from the user or from the CatalogItem's `field_definitions`), validates it against the DiskImage lifecycle and visibility rules, and persists the BareMetalInstance. The reconciler then fetches the DiskImage's `source_ref` and injects it as `params["imageURL"]` — the same JSON template parameter the AAP provisioning roles already consume. `imageSourceType`, previously injected alongside `imageURL` from the inline `spec.image.source_type`, is dropped: DiskImage abstracts the source type, and AAP provisioning templates do not consume `imageSourceType` for bare-metal provisioning. This keeps the operator CRD and all downstream provisioning code unchanged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

How do we want to handle the default mechanism? Will the disk image be required when creating a bare metal instance?

I would prefer to always require an image, but this would mean changes to aap and CI jobs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In this scope, when I talk about "default", it's set by the catalog item, not by the template/ansible which we should remove. I'll try to make it clearer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. disk_image is now always required — creation fails with InvalidArgument if neither the user nor the CatalogItem supplies it. There is no system-level default. The only default mechanism is CatalogItem field_definitions (what I was referring to as 'default' earlier). The design now explicitly documents that the AAP provisioning template's current hardcoded default imageURL must be removed as part of this feature, so the template relies entirely on the value injected by the reconciler.


User->>API: Create BareMetalInstance (disk_image=<id> or omitted)
API->>DB: Get CatalogItem → applyFieldDefinitions
Note over API: disk_image default applied if not provided

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same as previous comment, do we really want this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

See reply to the first comment — updated to explicitly require disk_image with no system fallback.

Comment thread enhancements/OSAC-1270-base-os-management-bmaas/design.md
@adriengentil

adriengentil commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Do we want to do any checking or labeling to show that some images can be used only with VMaaS or BMaaS? Do we know this beforehand?

The mid/long term is to have the same diskimage for VMaaS and BMaaS. @vladikr added OCI artifact support in kubevirt, so VMaaS can consume the same disk format as BMaaS. On the long term, we want to support bootc images directly for both.

I also know there's discussion to allow users to import their own OS Images, that would be a good entry point to accommodate different expected formats for a single image.

We can add a label or an annotation to make the image compatible only for one or the other service, but it's not the direction we want to take on the long term. I think that should be part of another feature as this design is about DiskImage integration in BMaaS. I think image compatibility (or capabilities), or checks should be part of DiskImage itself and decisions be aligned with VMaaS.

- disk_image is required: creation fails (InvalidArgument) if neither
  user nor CatalogItem provides it — no system-level fallback
- Non-Goals: explicitly exclude system/Ansible-provided default
- Goals: clarify CatalogItem field_definitions is the only default source
- Summary and Implementation Details: document that osac-aap templates
  currently carry a hardcoded default imageURL that must be removed as
  part of this feature (AAP change lands in same PR as fulfillment-service)
- Sequence diagram note: precise about CatalogItem default path and
  InvalidArgument when disk_image is still missing after defaults

Addresses: carbonin's review comments at lines 52, 77, 96

Assisted-by: Claude Code <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

AI Design Review: EP-197

Score: 8/8 | Verdict: PASS

Criterion Score Notes
Feasibility 2/2 The design identifies a narrow, well-understood integration point: the fulfillment-service reconciler resolves DiskImage and injects imageURL as a template parameter, leaving the CRD and bare-metal-fulfillment-operator unchanged. Proto changes use correct reserved-field patterns, the DB trigger replacement runs within a single DDL transaction (atomically safe in PostgreSQL), TOCTOU protection uses FOR SHARE locking consistent with OSAC-2540, and the OSAC-2540 dependency ordering is explicitly st
Testability 2/2 Comprehensive test plan with 12 specific unit test scenarios (all validation paths, reconciler resolution, migration triggers), 9 integration tests (lifecycle, deletion protection across BareMetalInstance/CatalogItem/compute regression, JSONB key casing regression, TOCTOU concurrency, tenant isolation), and 3 E2E scenarios (full provision path, catalog defaults, deprecated warnings). The JSONB key casing regression test and compute deletion-protection regression test are particularly valuable gi
Scope 2/2 Goals and non-goals are clearly enumerated and locked to PRD decisions. The breaking API change (removal of BareMetalInstanceSpec.image) is explicitly acknowledged with upgrade/downgrade procedures. UI scope is defined and placed in the Dev Preview timeline. AAP template changes are correctly scoped to the same PR. No scope creep into adjacent problems (custom uploads, OS upgrades, template defaults).
Architecture 2/2 Reuses patterns established by OSAC-2540 for consistency (DiskImage lifecycle validation, deletion protection triggers, tenant visibility checks). Minimal blast radius by injecting imageURL through existing templateParameters rather than adding CRD fields. Four alternatives are evaluated and rejected with clear reasoning. Security model is inherited without modification while closing a governance gap (arbitrary OCI URLs). Failure handling covers all concrete failure modes with specific error cod

Verdict: A thorough, well-structured design that extends the existing OSAC-2540 DiskImage pattern to BMaaS with minimal blast radius, comprehensive test coverage, and sound architectural decisions — the main actionable gap is that the JSONB key casing mismatch risk is flagged only in the PR description and should be surfaced in the design document's own Risks section.

Feedback: The JSONB key casing concern (OSAC-2540's compute trigger uses camelCase keys while UseProtoNames: true produces snake_case) is only called out in the PR description's 'Requesting Review On' section — add it to the Risks and Mitigations section of the design document itself, since a mismatch silently breaks deletion protection without any error at write time. Consider adding a down-migration test to the Test Plan: the downgrade procedure must recreate OSAC-2540's original trigger function (compute-only), and verifying that the down migration correctly restores compute deletion protection would reduce risk on a particularly coupled migration step. The CLI transition story (replacing --image/--image-source-type flags with --disk-image) could be mentioned in the Version Skew Strategy to guide client-side migration tooling.

Critical (0)

None.

Important (2)

  1. JSONB key casing mismatch risk (camelCase in OSAC-2540 trigger vs snake_case from UseProtoNames: true) is documented only in the PR description, not in the design document's Risks and Mitigations section — a silent deletion-protection bypass deserves a first-class risk entry with explicit verification steps for implementors.
  2. The down migration must recreate OSAC-2540's original check_disk_image_not_in_use function covering only compute resources before dropping BMaaS additions — this is described in Upgrade/Downgrade Strategy but the Test Plan has no corresponding down-migration test, leaving the most coupled migration step unverified.

Suggestions (2)

  1. Add a note in Version Skew Strategy about the CLI flag transition (--image → --disk-image) — old CLI versions sending the removed flags will get a generic InvalidArgument rather than a helpful migration message, which could be improved by detecting the old field presence.
  2. The reconciler's additional DB round-trip for DiskImage resolution is correctly identified as negligible; if BMaaS scale increases, consider whether the reconciler could cache or batch DiskImage lookups in a future follow-up.

Review cost

Model: claude-opus-4-6
Cost: $0.6985
Tokens: 13 in / 5.0k out
Cache: 457.1k read
Active time: 2m 2s
API calls: 0

@openshift-ci

openshift-ci Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: adriengentil, avishayt, carbonin

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:
  • OWNERS [adriengentil,avishayt,carbonin]

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

@openshift-merge-bot
openshift-merge-bot Bot merged commit b8f467c into main Aug 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants