OPRUN-4666,OPRUN-4671,OPRUN-4672,OPRUN-4673,OPRUN-4674,OPRUN-4659: Synchronize From Upstream Repositories + Remove spec.serviceAccount tests + remove demo e2e - #772
Conversation
…back (#2791) - Upgrade go.opentelemetry.io/otel/exporters/otlp/otlptrace, otlptracegrpc, and otel/sdk from v1.43.0 to v1.44.0 to match otel, otel/metric, and otel/trace already at v1.44.0 - Move E2E_TIMEOUT fallback from target-specific ?= into the e2e-run-% recipe via $(or $(E2E_TIMEOUT),20m) so the 20m default is explicit and the 25m override from test-experimental-e2e is unambiguous Signed-off-by: Todd Short <tshort@redhat.com> Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.6 to 0.21.7. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Commits](google/go-containerregistry@v0.21.6...v0.21.7) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-version: 0.21.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Convert terminal demos from standalone shell scripts recorded via asciinema to Godog BDD scenarios that generate asciicast v2 files programmatically. This makes demos into verified tests that can never silently break while producing terminal recordings. The recording infrastructure captures kubectl commands and their stdout/stderr with real execution timing during @demo-tagged scenario execution. Per-step dedup handles polling transparently so only successful results appear in the recording. Step text is emitted as comments and commands are colored for readability. Demo scenarios: - ClusterCatalog Quickstart: queries the operatorhubio catalog API - SingleNamespace Install Mode: installs mariadb-operator with a separate watch namespace, verifies rolebindings - OwnNamespace Install Mode: installs mariadb-operator with watch namespace equal to install namespace - Webhook Support: installs telegraf-operator, verifies mutating webhook injects sidecar container into test pod Not converted (no matching demo scenarios): - Synthetic User Permissions: feature gate disabled in experimental - Helm Chart Support: blocked by OCPBUGS-95281 The update-demos Makefile target now builds OLM from source using the experimental e2e infrastructure, deploys with all feature gates and operatorhubio catalog, runs demo scenarios, converts recordings to SVG via svg-term-cli, and tears down the cluster. Demo recordings are embedded in docs via the mkdocs-asciinema-player plugin and served from GitHub Pages, removing the dependency on asciinema.org for hosting recordings. Demo scenarios are excluded from regular e2e test runs via ~@demo filter. CI workflow (update-demos.yaml): - On PR: generates demos, uploads asciicast and SVG files as job artifacts - On merge to main: generates demos, deploys docs with updated recordings via make deploy-docs Old demo shell scripts, the asciinema generate-asciidemo.sh wrapper, and hack/demo/ resource files have been removed. Co-authored-by: Claude <noreply@anthropic.com>
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.38.0 to 0.55.0. - [Commits](golang/net@v0.38.0...v0.55.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.55.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/sigstore/fulcio](https://github.com/sigstore/fulcio) from 1.8.5 to 1.8.6. - [Release notes](https://github.com/sigstore/fulcio/releases) - [Changelog](https://github.com/sigstore/fulcio/blob/main/CHANGELOG.md) - [Commits](sigstore/fulcio@v1.8.5...v1.8.6) --- updated-dependencies: - dependency-name: github.com/sigstore/fulcio dependency-version: 1.8.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: jjaruszewski <jjaruszewski@man.poznan.pl>
GitHub Actions does not support expressions in the permissions block. The dynamic expression was causing every workflow run to fail with "workflow file issue" before any job could start. Use static contents:write (matching pages.yaml convention). The deploy step is already gated by `if: github.event_name == 'push'`. Co-authored-by: Claude <noreply@anthropic.com>
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.4.0 to 6.5.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@v6.4.0...v6.5.0) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.21.3 to 11.0. - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](facelessuser/pymdown-extensions@10.21.3...11.0) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-version: '11.0' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.21.1 to 3.21.2. - [Release notes](https://github.com/helm/helm/releases) - [Commits](helm/helm@v3.21.1...v3.21.2) --- updated-dependencies: - dependency-name: helm.sh/helm/v3 dependency-version: 3.21.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](actions/setup-python@v6.2.0...v6.3.0) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Track ClusterObjectSets in addedResources when applied, matching the pattern established for ClusterExtensions in #2783. This removes the special-case cleanup block in ScenarioCleanup and ensures multiple ClusterObjectSets per scenario are all cleaned up correctly. Co-authored-by: Per G. da Silva <pegoncal@redhat.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The HelmChartSupport feature gate (alpha, default off) and all code for detecting, pulling, caching, and loading native Helm chart bundles from OCI registries is removed. The path forward on the next bundle format is unclear and may not be Helm, so maintaining this code is not justified. The Helm backend that converts registry+v1 bundles into Helm chart objects for installation (RegistryV1HelmChartProvider) is unaffected. Co-authored-by: Claude <noreply@anthropic.com>
Bumps [click](https://github.com/pallets/click) from 8.4.1 to 8.4.2. - [Release notes](https://github.com/pallets/click/releases) - [Changelog](https://github.com/pallets/click/blob/main/CHANGES.md) - [Commits](pallets/click@8.4.1...8.4.2) --- updated-dependencies: - dependency-name: click dependency-version: 8.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) from 1.20.2 to 1.20.3. - [Release notes](https://github.com/cert-manager/cert-manager/releases) - [Changelog](https://github.com/cert-manager/cert-manager/blob/master/RELEASE.md) - [Commits](cert-manager/cert-manager@v1.20.2...v1.20.3) --- updated-dependencies: - dependency-name: github.com/cert-manager/cert-manager dependency-version: 1.20.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.46.0 to 0.47.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](golang/tools@v0.46.0...v0.47.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-version: 0.47.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [regex](https://github.com/mrabarnett/mrab-regex) from 2026.5.9 to 2026.6.28. - [Changelog](https://github.com/mrabarnett/mrab-regex/blob/hg/changelog.txt) - [Commits](mrabarnett/mrab-regex@2026.5.9...2026.6.28) --- updated-dependencies: - dependency-name: regex dependency-version: 2026.6.28 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.18.6 to 1.19.0. - [Release notes](https://github.com/klauspost/compress/releases) - [Commits](klauspost/compress@v1.18.6...v1.19.0) --- updated-dependencies: - dependency-name: github.com/klauspost/compress dependency-version: 1.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.2.0 to 4.3.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](docker/login-action@v4.2.0...v4.3.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](dorny/paths-filter@v4.0.1...v4.0.2) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: 4.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.21.0 to 0.22.0. - [Commits](golang/sync@v0.21.0...v0.22.0) --- updated-dependencies: - dependency-name: golang.org/x/sync dependency-version: 0.22.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* shift to file-based cache, leveraging existing metas indexer * review comments Signed-off-by: grokspawn <jordan@nimblewidget.com> * bounds-protect type evaluation depth Signed-off-by: grokspawn <jordan@nimblewidget.com> * more review comments Signed-off-by: grokspawn <jordan@nimblewidget.com> --------- Signed-off-by: grokspawn <jordan@nimblewidget.com>
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.3.0 to 4.4.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](docker/login-action@v4.3.0...v4.4.0) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 11.0 to 11.0.1. - [Release notes](https://github.com/facelessuser/pymdown-extensions/releases) - [Commits](facelessuser/pymdown-extensions@11.0...11.0.1) --- updated-dependencies: - dependency-name: pymdown-extensions dependency-version: 11.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat(api): deprecate spec.serviceAccount and adopt cluster-admin scope Mark spec.serviceAccount as deprecated in the ClusterExtension API. Remove PreAuthorizer integration, SA-scoped RBAC templates, and restconfig action. Simplify the controller to use cluster-admin scope directly. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * feat: add ValidatingAdmissionPolicy for serviceAccount deprecation warning Create VAP and VAPB resources that emit a warning when spec.serviceAccount is set on a ClusterExtension. Add integration test infrastructure for warning collection. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * test: clean up e2e tests for serviceAccount deprecation Remove SA-specific e2e test scenarios, SA RBAC templates, and the extension developer test suite. Simplify test steps to use cluster-admin scope. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * refactor: remove per-SA infrastructure and feature gates Delete authentication and authorization packages, feature gates, k8smaintainer tool, SA demo scripts, and documentation. Remove k8s.io/kubernetes dependency and unnecessary k8s staging replace directives. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * refactor: replace contentmanager with shared TrackingCache Delete the contentmanager package and replace it with boxcutter's shared TrackingCache. Simplify revision engine factory to use the base config directly. Remove SA label constants. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * docs: update documentation for cluster-admin scope Remove SA-related documentation, tutorials, and demo scripts. Clean up remaining ServiceAccount references from unit tests. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> * Add documentation examples for using ValidatingAdmissionPolicy to protect OLMv1 API access. Signed-off-by: Daniel Franz <dfranz@redhat.com> Co-Authored-By: Predrag Knezevic <pknezevi@redhat.com> Co-Authored-By: Daniel Franz <dfranz@redhat.com> Co-Authored-By: Claude <noreply@anthropic.com> * docs: rewrite cluster-admin scope section in design decisions doc Also updates go.mod/go.sum to fix k8s.io/client-go version. --------- Signed-off-by: Daniel Franz <dfranz@redhat.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Daniel Franz <dfranz@redhat.com> Co-authored-by: Joe Lanford <joe.lanford@gmail.com>
Bumps [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases) - [Commits](marocchino/sticky-pull-request-comment@v3.0.4...v3.0.5) --- updated-dependencies: - dependency-name: marocchino/sticky-pull-request-comment dependency-version: 3.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the k8s-dependencies group with 1 update: [sigs.k8s.io/structured-merge-diff/v6](https://github.com/kubernetes-sigs/structured-merge-diff). Updates `sigs.k8s.io/structured-merge-diff/v6` from 6.4.0 to 6.4.1 - [Changelog](https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/RELEASE.md) - [Commits](kubernetes-sigs/structured-merge-diff@v6.4.0...v6.4.1) --- updated-dependencies: - dependency-name: sigs.k8s.io/structured-merge-diff/v6 dependency-version: 6.4.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/stale](https://github.com/actions/stale) from 10.3.0 to 10.4.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](actions/stale@v10.3.0...v10.4.0) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.47.0 to 0.48.0. - [Release notes](https://github.com/golang/tools/releases) - [Commits](golang/tools@v0.47.0...v0.48.0) --- updated-dependencies: - dependency-name: golang.org/x/tools dependency-version: 0.48.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) from 1.20.3 to 1.21.0. - [Release notes](https://github.com/cert-manager/cert-manager/releases) - [Changelog](https://github.com/cert-manager/cert-manager/blob/master/RELEASE.md) - [Commits](cert-manager/cert-manager@v1.20.3...v1.21.0) --- updated-dependencies: - dependency-name: github.com/cert-manager/cert-manager dependency-version: 1.21.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- Replace broken test-experimental-e2e target (test/experimental-e2e no longer exists) with /bin/true so triggered jobs always succeed - Pass -timeout=60m to go test; the previous invocation relied on Go's 10m default which is too short for BoxcutterRuntime clusters - Set E2E_STEP_TIMEOUT=15m; BoxcutterRuntime applies resources through sequential phases (CRD must reach Established before the deploy phase starts), making installations slower than the upstream 5m default - Skip ~@CatalogdHA scenarios (require multiple catalogd replicas not present in standard topology) - Skip ~@ProgressDeadline scenarios (require progressDeadlineMinutes < 10 but the OpenShift CRD enforces a minimum of 10) - Skip ~@httpproxy scenarios (too disruptive to cluster networking) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Todd Short <tshort@redhat.com>
The e2e-test-registry image is no longer built by CI after openshift/release#78581 removed it from the CI config. The dynamic per-scenario catalog system replaced the pre-built registry image, making this Dockerfile dead code.
It's no longer bring used. Signed-off-by: Todd Short <tshort@redhat.com>
Adds a new test that verifies cluster-olm-operator correctly configures operator-controller and catalogd deployments based on the cluster's control plane topology: - HA topologies (HighlyAvailable, HighlyAvailableArbiter, DualReplica): replicas=2 with a PodDisruptionBudget present - Non-HA topologies (SingleReplica/SNO, External): replicas=1, no PDB Also registers policyv1 in the test scheme to support PDB list queries. Assisted-by: claude Signed-off-by: Todd Short <tshort@redhat.com>
… builders Signed-off-by: Todd Short <tshort@redhat.com>
…ge to be consistent with ART for 5.0 Reconciling with https://github.com/openshift-eng/ocp-build-data/tree/7691ed4dc0b6585b358f9e73fb736ace9a48a286/images/ose-olm-operator-controller.yml
Set catalog image tags to v5.0 for the 4.23/5.0 release. Dynamically discover an installable package from the serving catalogs instead of hardcoding quay-operator v3.13.10, preferring quay-operator, cluster-logging, serverless-operator, logic-operator in that order then alling back to the first available package. Signed-off-by: Todd Short <tshort@redhat.com>
…ntal manifests HelmChartSupport was removed upstream in dbc9b4a but the downstream experimental.yaml values file and its generated manifest still referenced it, causing operator-controller to crash on startup with: invalid argument "HelmChartSupport=false" for "--feature-gates" flag: unrecognized feature gate: HelmChartSupport This made the OLM cluster operator Degraded/Unavailable and caused cluster installation to time out (exit code 6). Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…cluster version Add a second ReleaseGate-eligible OTE test verifying that an operator whose olm.maxOpenShiftVersion exceeds the current cluster version does not block cluster upgrade (InstalledOLMOperatorsUpgradeable stays True). The existing test only covered the blocking path (maxOCPVersion == current version → False). This covers the complementary allow path (maxOCPVersion == next minor → True), directly exercising the normalization logic introduced for the 4.23/5.0 co-release boundary. A nextMinorVersion() helper mirrors the 4.23→5.1 special case so the bundle annotation is always set to the correct next upgrade target. Run 'make build-update' to register the new allow-case test in the extension metadata after adding it to olmv1-incompatible.go. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Todd Short <tshort@redhat.com>
Automate the ClusterExtension rollout failure coverage for OCP-88331 and OCP-88332 by building in-cluster bundle and catalog images for successful and failing bundle versions. The new QE specs verify ProgressDeadlineExceeded on an initial failed rollout and ProbeFailure while upgrading to a bad revision under the BoxCutter runtime. Signed-off-by: Daniel Franz <dfranz@redhat.com> Co-authored-by: Bruno Andrade <bruno.balint@gmail.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Todd Short <tshort@redhat.com>
…eAccount usage in ClusterExtension API, Synthetic Permissions, and PreFlight Admissions Signed-off-by: Daniel Franz <dfranz@redhat.com>
Signed-off-by: Todd Short <tshort@redhat.com>
|
@tmshort: This pull request references OPRUN-4666 which is a valid jira issue. This pull request references OPRUN-4671 which is a valid jira issue. This pull request references OPRUN-4672 which is a valid jira issue. This pull request references OPRUN-4673 which is a valid jira issue. This pull request references OPRUN-4674 which is a valid jira issue. This pull request references OPRUN-4659 which is a valid jira issue. DetailsIn response to this: 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. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: tmshort The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughThe change deprecates and ignores ChangesOLMv1 service-account model
Catalogd GraphQL and image handling
Demo and build workflow
Generated annotations
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
✨ Finishing Touches🧪 Generate unit tests (beta)
|
|
/test unit |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/catalogd/service/graphql_service.go (1)
47-80: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
ctxpassed intoGetSchemais never used — schema build has no timeout.
GetSchemaaccepts acontext.Contextbut never reads it; the underlyingbuildGroup.Do/buildSchema/provider.LoadCatalogSchema/NewObjectLoadercalls take no context either (verifiedgolang.org/x/sync/singleflight.Doitself has no context-aware overload).ExecuteQueryonly wrapsgraphql.Doin a 5s timeout (Line 96) — theGetSchema(ctx, catalog)call right before it (Line 91) can block indefinitely if catalog loading is slow, with no deadline enforcement despite the surrounding code clearly intending timeout-bounded execution.Wrap the schema-build phase with its own timeout (e.g., derive it from
ctxsimilarly to the query timeout) or thread the context through to the provider so cancellation/deadlines actually apply to catalog IO.As per path instructions for
**/*.go,**/*.go: "context.Context for cancellation and timeouts" — the unusedctxparameter here doesn't fulfill that guidance.Also applies to: 82-106
🤖 Prompt for 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. In `@internal/catalogd/service/graphql_service.go` around lines 47 - 80, Make GetSchema honor its ctx by applying a bounded timeout or cancellation to the schema-build operation, including the buildGroup.Do/buildSchema path, so slow catalog loads cannot block indefinitely. Prefer threading ctx through buildSchema and the provider.LoadCatalogSchema/NewObjectLoader calls; otherwise enforce timeout completion around buildGroup.Do. Preserve cache behavior and return context cancellation/deadline errors.Source: Path instructions
🧹 Nitpick comments (2)
test/e2e/features/revision.feature (1)
9-16: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDrop the unused
pvc-probe-sasetup
These scenarios no longer referencepvc-probe-sain theClusterObjectSetmanifest, so the sharedGiven ServiceAccount ...step now creates an unused ServiceAccount/RBAC pair. Switch to the namespace-only setup used by the migrated scenarios below.🤖 Prompt for 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. In `@test/e2e/features/revision.feature` around lines 9 - 16, Remove the unused “Given ServiceAccount "pvc-probe-sa" with needed permissions” step from the affected scenarios in revision.feature, and use the namespace-only setup established by the migrated scenarios below. Keep the ClusterObjectSet manifests and scenario behavior unchanged.test/e2e/steps/asciicast_recorder.go (1)
139-147: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winUnhandled error from
f.Close().
defer f.Close()discards the close error. For a file write path, a failed close can mean data wasn't flushed to disk, so this should ideally be captured with a named return / explicit check rather than silently dropped.As per path instructions for
**/*.go: "Never ignore error returns."♻️ Proposed fix
f, err := os.Create(r.castPath) if err != nil { return fmt.Errorf("failed to create cast file %s: %w", r.castPath, err) } - defer f.Close() + defer func() { + if cerr := f.Close(); cerr != nil && err == nil { + err = fmt.Errorf("failed to close cast file %s: %w", r.castPath, cerr) + } + }()🤖 Prompt for 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. In `@test/e2e/steps/asciicast_recorder.go` around lines 139 - 147, Update AsciiCastRecorder.Stop to handle the error returned by f.Close instead of discarding it via defer. Use a named return or explicit close handling so close failures are propagated while preserving existing errors from directory creation, file creation, and recording.Source: Path instructions
🤖 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 `@docs/howto/how-to-protect-olmv1-api-access.md`:
- Around line 39-44: Update the RBAC verb lists in the installer role
documentation to include patch for both resource entries, alongside the existing
create, update, delete, get, list, and watch verbs. Ensure both resources
support declarative kubectl apply workflows.
- Line 71: Update the Markdown link in the ValidatingAdmissionPolicy discussion
to replace the vague “here” anchor with descriptive text identifying the
Kubernetes ValidatingAdmissionPolicy documentation, while preserving the
existing destination URL.
In `@internal/catalogd/graphql/validation.go`:
- Around line 16-21: Update query complexity traversal around
queryComplexity.visited and the fragment-recursion logic in validateQuery to
treat visited as a per-path set: mark a fragment before traversing its
definition, remove it after recursion completes, and skip only fragments already
active on the current path. Preserve cycle protection while allowing each
non-overlapping fragment spread to contribute its fields and aliases to the
operation totals.
In `@internal/catalogd/storage/localdir_test.go`:
- Around line 711-712: Update the test setup around NewLocalDirV1 and the
corresponding setup at the other URL parsing occurrence to capture the error
returned by url.Parse and assert it with require.NoError before using rootURL.
Do not discard the parsing error, including for constant URLs.
In `@internal/catalogd/storage/localdir.go`:
- Around line 344-356: Validate offset and limit before slicing sections in the
surrounding schema-section retrieval method, returning a validation error when
either pagination value is negative. Preserve the existing nil returns for
missing or exhausted sections and the current slicing behavior for non-negative
values.
- Around line 97-106: Update storeAtomicSwap’s schema warm-up flow to avoid
deleting the previously healthy catalog before validation completes. Either
validate the temporary catalog before replacing the existing directory, or
retain the old directory and restore it when graphqlSvc.GetSchema fails; ensure
rollback removes the new directory and leaves the prior catalog available.
- Around line 124-128: Update the cleanup paths in the local catalog storage
flow, including the deferred RemoveAll around MkdirTemp and the f.Close path
referenced by the comment, so their returned errors are explicitly handled
rather than discarded. Propagate cleanup or close failures when the surrounding
function can return an error; otherwise log them using the existing logging
mechanism, while preserving the current successful cleanup behavior.
- Around line 332-340: Update NewObjectLoader so the closure no longer captures
an index loaded before locking; acquire the snapshot RLock first, then load the
index through the lock-held helper before reading the catalog file. Preserve the
existing error handling and ensure both index and JSONL data come from the same
snapshot.
In `@openshift/operator-controller/manifests.yaml`:
- Around line 736-740: Replace the cluster-admin role reference in the
operator-controller-cluster-admin-rolebinding with a least-privilege custom or
aggregated ClusterRole that grants only the manager’s required permissions in
openshift/operator-controller/manifests.yaml:736-740 and
openshift/operator-controller/manifests-experimental.yaml:887-891. Apply the
same scoped RBAC change in both standard and experimental manifests, preserving
the Controller ServiceAccount binding.
---
Outside diff comments:
In `@internal/catalogd/service/graphql_service.go`:
- Around line 47-80: Make GetSchema honor its ctx by applying a bounded timeout
or cancellation to the schema-build operation, including the
buildGroup.Do/buildSchema path, so slow catalog loads cannot block indefinitely.
Prefer threading ctx through buildSchema and the
provider.LoadCatalogSchema/NewObjectLoader calls; otherwise enforce timeout
completion around buildGroup.Do. Preserve cache behavior and return context
cancellation/deadline errors.
---
Nitpick comments:
In `@test/e2e/features/revision.feature`:
- Around line 9-16: Remove the unused “Given ServiceAccount "pvc-probe-sa" with
needed permissions” step from the affected scenarios in revision.feature, and
use the namespace-only setup established by the migrated scenarios below. Keep
the ClusterObjectSet manifests and scenario behavior unchanged.
In `@test/e2e/steps/asciicast_recorder.go`:
- Around line 139-147: Update AsciiCastRecorder.Stop to handle the error
returned by f.Close instead of discarding it via defer. Use a named return or
explicit close handling so close failures are propagated while preserving
existing errors from directory creation, file creation, and recording.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| - create | ||
| - update | ||
| - delete | ||
| - get | ||
| - list | ||
| - watch |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Grant patch to the installer role.
kubectl apply and other declarative clients use PATCH for existing resources, so this role cannot perform the documented modification workflow. Add patch for both resources.
🤖 Prompt for 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.
In `@docs/howto/how-to-protect-olmv1-api-access.md` around lines 39 - 44, Update
the RBAC verb lists in the installer role documentation to include patch for
both resource entries, alongside the existing create, update, delete, get, list,
and watch verbs. Ensure both resources support declarative kubectl apply
workflows.
|
|
||
| ## Validating Admission Policy | ||
|
|
||
| A `ValidatingAdmissionPolicy` provides much more flexibility than simple RBAC when it comes to managing access to `ClusterExtensions`. For more detailed instructions on the fundamentals of the `ValidatingAdmissionPolicy` API, take a look at the Kubernetes docs [here](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use descriptive link text.
Replace “here” with text such as “Kubernetes ValidatingAdmissionPolicy documentation.”
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)
[warning] 71-71: Link text should be descriptive
(MD059, descriptive-link-text)
🤖 Prompt for 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.
In `@docs/howto/how-to-protect-olmv1-api-access.md` at line 71, Update the
Markdown link in the ValidatingAdmissionPolicy discussion to replace the vague
“here” anchor with descriptive text identifying the Kubernetes
ValidatingAdmissionPolicy documentation, while preserving the existing
destination URL.
Source: Linters/SAST tools
| type queryComplexity struct { | ||
| aliases int | ||
| fields int | ||
| fragments map[string]*ast.FragmentDefinition | ||
| visited map[string]bool | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Fragment-spread dedup lets query cost bypass the complexity limits it's meant to enforce.
c.visited is a single map reused for the whole operation and a fragment name is never unmarked once counted (Lines 79-84). This only guards against fragments that self-reference (cycles), but it also silently skips re-counting a fragment the second, third, ... Nth time it's spread in different, non-overlapping branches of the same query — even though the GraphQL executor (graphql.Do) will actually resolve that fragment's fields at every one of those spread sites. An attacker can define one deep/wide fragment and reuse it across many sibling fields to keep the reported fields/aliases counts under maxQueryFields/maxQueryAliases while the real execution cost multiplies — defeating the DoS protection this validator exists to provide.
Use a per-path "currently visiting" set (added before recursing into a fragment, removed after) instead of a permanent per-operation set, so cycles are still blocked but each distinct spread occurrence is fully counted.
🔒 Proposed fix: track visiting fragments per traversal path
type queryComplexity struct {
aliases int
fields int
fragments map[string]*ast.FragmentDefinition
- visited map[string]bool
}
@@
for _, def := range doc.Definitions {
if op, ok := def.(*ast.OperationDefinition); ok {
- // Reset per operation so shared fragments are counted for each operation.
- c.visited = make(map[string]bool)
- if err := c.walkSelectionSet(op.SelectionSet, 1); err != nil {
+ if err := c.walkSelectionSet(op.SelectionSet, 1, make(map[string]bool)); err != nil {
return err
}
}
}
@@
-func (c *queryComplexity) walkSelectionSet(ss *ast.SelectionSet, depth int) error {
+func (c *queryComplexity) walkSelectionSet(ss *ast.SelectionSet, depth int, visiting map[string]bool) error {
...
- if err := c.walkSelectionSet(s.SelectionSet, depth+1); err != nil {
+ if err := c.walkSelectionSet(s.SelectionSet, depth+1, visiting); err != nil {
return err
}
case *ast.InlineFragment:
- if err := c.walkSelectionSet(s.SelectionSet, depth+1); err != nil {
+ if err := c.walkSelectionSet(s.SelectionSet, depth+1, visiting); err != nil {
return err
}
case *ast.FragmentSpread:
name := s.Name.Value
- if c.visited[name] {
+ if visiting[name] {
continue
}
- c.visited[name] = true
+ visiting[name] = true
if frag, ok := c.fragments[name]; ok {
- if err := c.walkSelectionSet(frag.SelectionSet, depth+1); err != nil {
+ if err := c.walkSelectionSet(frag.SelectionSet, depth+1, visiting); err != nil {
return err
}
}
+ delete(visiting, name)
}Also applies to: 41-42, 79-89
🤖 Prompt for 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.
In `@internal/catalogd/graphql/validation.go` around lines 16 - 21, Update query
complexity traversal around queryComplexity.visited and the fragment-recursion
logic in validateQuery to treat visited as a per-path set: mark a fragment
before traversing its definition, remove it after recursion completes, and skip
only fragments already active on the current path. Preserve cycle protection
while allowing each non-overlapping fragment spread to contribute its fields and
aliases to the operation totals.
| rootURL, _ := url.Parse("http://localhost/catalogs/") | ||
| s := NewLocalDirV1( |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Check the URL parsing errors.
Do not discard url.Parse errors, even for constants; assert them with require.NoError. As per path instructions, “Never ignore error returns.”
Also applies to: 764-765
🤖 Prompt for 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.
In `@internal/catalogd/storage/localdir_test.go` around lines 711 - 712, Update
the test setup around NewLocalDirV1 and the corresponding setup at the other URL
parsing occurrence to capture the error returned by url.Parse and assert it with
require.NoError before using rootURL. Do not discard the parsing error,
including for constant URLs.
Source: Path instructions
| if s.graphqlSvc != nil { | ||
| if _, err := s.graphqlSvc.GetSchema(ctx, catalog); err != nil { | ||
| s.graphqlSvc.InvalidateCache(catalog) | ||
| s.m.Lock() | ||
| removeErr := os.RemoveAll(catalogDir) | ||
| s.m.Unlock() | ||
| if removeErr != nil { | ||
| return fmt.Errorf("failed to pre-build GraphQL schema for catalog %q: %w (rollback also failed: %v)", catalog, err, removeErr) | ||
| } | ||
| return fmt.Errorf("failed to pre-build GraphQL schema for catalog %q: %w", catalog, err) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift
Preserve the previous catalog if schema warm-up fails.
storeAtomicSwap has already deleted the prior directory. This rollback only deletes the new directory, leaving a previously healthy catalog unavailable. Retain and restore the old directory, or validate the temporary catalog before replacing it.
🤖 Prompt for 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.
In `@internal/catalogd/storage/localdir.go` around lines 97 - 106, Update
storeAtomicSwap’s schema warm-up flow to avoid deleting the previously healthy
catalog before validation completes. Either validate the temporary catalog
before replacing the existing directory, or retain the old directory and restore
it when graphqlSvc.GetSchema fails; ensure rollback removes the new directory
and leaves the prior catalog available.
| tmpCatalogDir, err := os.MkdirTemp(s.RootDir, fmt.Sprintf(".%s-*", catalog)) | ||
| if err != nil { | ||
| return err | ||
| return "", err | ||
| } | ||
| defer os.RemoveAll(tmpCatalogDir) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Handle deferred cleanup and close errors.
os.RemoveAll and f.Close errors are discarded. Propagate or log them so failed cleanup does not silently accumulate stale catalog data. As per path instructions, “Never ignore error returns.”
Also applies to: 358-362
🤖 Prompt for 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.
In `@internal/catalogd/storage/localdir.go` around lines 124 - 128, Update the
cleanup paths in the local catalog storage flow, including the deferred
RemoveAll around MkdirTemp and the f.Close path referenced by the comment, so
their returned errors are explicitly handled rather than discarded. Propagate
cleanup or close failures when the surrounding function can return an error;
otherwise log them using the existing logging mechanism, while preserving the
current successful cleanup behavior.
Source: Path instructions
| func (s *LocalDirV1) NewObjectLoader(catalog string) (gql.ObjectLoader, error) { | ||
| idx, err := s.loadIndex(catalog) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("error loading index for catalog %q: %w", catalog, err) | ||
| } | ||
|
|
||
| catalogPath := catalogFilePath(s.catalogDir(catalog)) | ||
|
|
||
| return func(schemaName string, offset, limit int) ([]map[string]interface{}, error) { |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Load the index under the same snapshot lock as the catalog file.
The closure captures idx before it takes RLock. A loader retained from the previous cached schema can therefore apply old byte offsets to newly swapped JSONL data, returning incorrect objects or read errors. Load the index after acquiring the closure lock, using a lock-held helper.
🤖 Prompt for 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.
In `@internal/catalogd/storage/localdir.go` around lines 332 - 340, Update
NewObjectLoader so the closure no longer captures an index loaded before
locking; acquire the snapshot RLock first, then load the index through the
lock-held helper before reading the catalog file. Preserve the existing error
handling and ensure both index and JSONL data come from the same snapshot.
| sections := idx.GetSchemaSections(schemaName) | ||
| if sections == nil { | ||
| return nil, nil | ||
| } | ||
|
|
||
| if offset >= len(sections) { | ||
| return nil, nil | ||
| } | ||
| sections = sections[offset:] | ||
|
|
||
| if limit < len(sections) { | ||
| sections = sections[:limit] | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Reject negative pagination values before slicing.
offset = -1 reaches sections[offset:], and limit = -1 reaches sections[:limit]; both panic. Return a validation error when either value is negative.
🤖 Prompt for 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.
In `@internal/catalogd/storage/localdir.go` around lines 344 - 356, Validate
offset and limit before slicing sections in the surrounding schema-section
retrieval method, returning a validation error when either pagination value is
negative. Preserve the existing nil returns for missing or exhausted sections
and the current slicing behavior for non-negative values.
| name: operator-controller-cluster-admin-rolebinding | ||
| roleRef: | ||
| apiGroup: rbac.authorization.k8s.io | ||
| kind: ClusterRole | ||
| name: operator-controller-manager-role | ||
| name: cluster-admin |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
Controller ServiceAccount bound to cluster-admin in both standard and experimental manifests. The scoped operator-controller-manager-role binding was replaced by a cluster-admin ClusterRoleBinding. This is a deliberate consequence of removing SA-scoped installs (documented in the CRD deprecation text), but it broadens the workload's blast radius and conflicts with the least-privilege guideline. Confirm this is the accepted design and, if possible, scope to a custom/aggregated ClusterRole instead of cluster-admin.
openshift/operator-controller/manifests.yaml#L736-L740:operator-controller-cluster-admin-rolebindingbinds the manager SA tocluster-admin.openshift/operator-controller/manifests-experimental.yaml#L887-L891: identicalcluster-adminbinding for the experimental feature-set.
As per path instructions: "RBAC: least privilege; no cluster-admin for workloads".
📍 Affects 2 files
openshift/operator-controller/manifests.yaml#L736-L740(this comment)openshift/operator-controller/manifests-experimental.yaml#L887-L891
🤖 Prompt for 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.
In `@openshift/operator-controller/manifests.yaml` around lines 736 - 740, Replace
the cluster-admin role reference in the
operator-controller-cluster-admin-rolebinding with a least-privilege custom or
aggregated ClusterRole that grants only the manager’s required permissions in
openshift/operator-controller/manifests.yaml:736-740 and
openshift/operator-controller/manifests-experimental.yaml:887-891. Apply the
same scoped RBAC change in both standard and experimental manifests, preserving
the Controller ServiceAccount binding.
Source: Path instructions
|
Closing in favor of merged #767 |
Summary by CodeRabbit
New Features
Changes
serviceAccountconfiguration is now optional, deprecated, and ignored; setting it produces a warning.Documentation