Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
09d32fb
🌱 Return *DeploymentConfig directly from GetDeploymentConfig() (#2598)
joelanford Mar 27, 2026
de9700b
fix(boxcutter): detect collision when duplicate package is installed …
camilamacedo86 Mar 27, 2026
e709e65
:seedling: Bump marocchino/sticky-pull-request-comment from 2 to 3 (#…
dependabot[bot] Mar 27, 2026
8c7a40b
Merge branch 'main' into synchronize
Mar 30, 2026
1c4b880
UPSTREAM: <carry>: Add OpenShift specific files
dtfranz Oct 26, 2023
8b24cbd
UPSTREAM: <carry>: Add new tests for single/own namespaces install modes
camilamacedo86 Oct 6, 2025
caf0ff2
UPSTREAM: <carry>: Upgrade OCP image from 4.20 to 4.21
camilamacedo86 Oct 13, 2025
a18cb21
UPSTREAM: <carry>: [Default Catalog Tests] - Change logic to get ocp …
camilamacedo86 Oct 13, 2025
979843e
UPSTREAM: <carry>: Update OCP catalogs to v4.21
tmshort Oct 13, 2025
cfa40e5
UPSTREAM: <carry>: support singleown cases in disconnected
kuiwang02 Oct 16, 2025
56ed5ef
UPSTREAM: <carry>: fix cases 81696 and 74618 for product code changes
kuiwang02 Oct 17, 2025
cd1caf6
UPSTREAM: <carry>: Define Default timeouts and apply their usage accr…
camilamacedo86 Oct 22, 2025
c62a9a6
UPSTREAM: <carry>: Update to new feature-gate options in helm
tmshort Oct 22, 2025
fdb6510
UPSTREAM: <carry>: Fix flake for single/own ns tests by ensuring uniq…
camilamacedo86 Oct 22, 2025
48ea79a
UPSTREAM: <carry>: [OTE]: Enhance single/own ns based on review comme…
camilamacedo86 Oct 24, 2025
04f920b
UPSTREAM: <carry>: Update OwnSingle template to use spec.config.inlin…
kuiwang02 Nov 3, 2025
5da419b
UPSTREAM: <carry>: [OTE]: Add webhook cleanup validation on extension…
camilamacedo86 Nov 4, 2025
46215a1
UPSTREAM: <carry>: Add [OTP] to migrated cases
kuiwang02 Nov 7, 2025
c6ca276
UPSTREAM: <carry>: [OTE]: Upgrade dependencies used
camilamacedo86 Nov 5, 2025
ac64409
UPSTREAM: <carry>: fix(OTE): fix OpenShift Kubernetes replace version…
camilamacedo86 Nov 10, 2025
a276009
UPSTREAM: <carry>: [Default Catalog Tests] Upgrade go 1.24.6 and depe…
camilamacedo86 Nov 11, 2025
74843fa
UPSTREAM: <carry>: add disconnected environment support with custom p…
kuiwang02 Nov 12, 2025
4bb1e8d
UPSTREAM: <carry>: migrate jiazha test cases to OTE
jianzhangbjz Nov 14, 2025
c34f9ae
UPSTREAM: <carry>: migrate clustercatalog case to ote
Xia-Zhao-rh Oct 17, 2025
2549f4e
UPSTREAM: <carry>: migrate olmv1 QE stress cases
kuiwang02 Nov 20, 2025
17af3cc
UPSTREAM: <carry>: Use busybox/httpd to simulate probes
tmshort Nov 25, 2025
5e9c028
UPSTREAM: <carry>: migrate olmv1 QE cases
Xia-Zhao-rh Nov 25, 2025
adb6ec6
UPSTREAM: <carry>: add agent for olmv1 qe cases
kuiwang02 Oct 21, 2025
d843590
UPSTREAM: <carry>: Disable upstream PodDisruptionBudget
tmshort Dec 3, 2025
e24647a
UPSTREAM: <carry>: Add AGENTS.md for AI code contributions
rashmigottipati Dec 11, 2025
c047d96
UPSTREAM: <carry>: address review comments through addl prompts
rashmigottipati Dec 11, 2025
c3af2ba
UPSTREAM: <carry>: addressing some more review comments
rashmigottipati Dec 11, 2025
5a09a72
UPSTREAM: <carry>: remove DCO line
rashmigottipati Dec 11, 2025
c895fde
UPSTREAM: <carry>: migrate bandrade test cases to OTE
bandrade Nov 18, 2025
4ac832f
UPSTREAM: <carry>: update metadata
bandrade Dec 3, 2025
7619323
UPSTREAM: <carry>: remove originalName
bandrade Dec 3, 2025
e4ac70d
UPSTREAM: <carry>: update 80458's timeout to 180s
jianzhangbjz Dec 8, 2025
9570ada
UPSTREAM: <carry>: update 83026 to specify the clustercatalog
jianzhangbjz Dec 15, 2025
602c27d
UPSTREAM: <carry>: Update to golang 1.25 and ocp 4.22
oceanc80 Dec 18, 2025
989a8f6
UPSTREAM: <carry>: Use oc client for running e2e tests
pedjak Jan 13, 2026
69222cd
UPSTREAM: <carry>: Run upstream e2e tests tagged with `@catalogd-update`
pedjak Jan 14, 2026
112be4a
UPSTREAM: <carry>: enhance case to make it more stable
kuiwang02 Jan 6, 2026
aab862d
UPSTREAM: <carry>: add service account to curl job
ehearne-redhat Jan 7, 2026
cb49fc4
UPSTREAM: <carry>: move sa creation out of buildCurlJob()
ehearne-redhat Jan 8, 2026
af6d0d0
UPSTREAM: <carry>: comment out delete service account
ehearne-redhat Jan 9, 2026
2005cfd
UPSTREAM: <carry>: move defercleanup for sa for LIFO
ehearne-redhat Jan 9, 2026
9700234
UPSTREAM: <carry>: add polling so job fully deleted before proceed
ehearne-redhat Jan 12, 2026
702cc7c
UPSTREAM: <carry>: Revert "Merge pull request #594 from ehearne-redha…
sosiouxme Jan 20, 2026
ca0256f
UPSTREAM: <carry>: Remove openshift-redhat-marketplace catalog tests
camilamacedo86 Jan 8, 2026
c094f32
UPSTREAM: <carry>: config watchnamespace cases
kuiwang02 Jan 6, 2026
5c103f1
UPSTREAM: <carry>: enhance ocp-79770
Xia-Zhao-rh Jan 26, 2026
13a1bd0
UPSTREAM: <carry>: upgrade version support case
kuiwang02 Jan 28, 2026
54503cf
UPSTREAM: <carry>: Remove installed condition check from auth preflig…
Jan 30, 2026
ddf6bd2
UPSTREAM: <carry>: Add openshift/api dependency
Jan 30, 2026
ad6af4e
UPSTREAM: <carry>: Add boxcutter specific preflight auth test
Jan 30, 2026
df0000e
UPSTREAM: <carry>: adjust watchnamespace case based on change
kuiwang02 Feb 2, 2026
3088334
UPSTREAM: <carry>: fix(ote): Use as operator-controller dep from root…
camilamacedo86 Feb 3, 2026
9307333
UPSTREAM: <carry>: add 83979 automation
bandrade Feb 2, 2026
9e518ca
UPSTREAM: <carry>: add 85889 automation
bandrade Feb 2, 2026
dfa3dac
UPSTREAM: <carry>: Update test-operator startup script to fix pod pro…
Feb 4, 2026
a951737
UPSTREAM: <carry>: Fix up own-namespace invalid configuration test
Feb 7, 2026
b141f37
UPSTREAM: <carry>: Preflight tests use in-cluster catalog and bundles…
camilamacedo86 Feb 24, 2026
49cedae
UPSTREAM: <carry>: adjust sa and permission test cases per new change…
kuiwang02 Feb 2, 2026
c3c0626
UPSTREAM: <carry>: Update OCP catalogs to v4.22
camilamacedo86 Feb 3, 2026
31da244
UPSTREAM: <carry>: chore(OTE and Default Catalog Tests) Update go and…
camilamacedo86 Feb 26, 2026
836b198
UPSTREAM: <carry>: fix 83026 for TP cluster
jianzhangbjz Feb 28, 2026
651db6e
UPSTREAM: <carry>: serviceAccount validation unified across all runtimes
kuiwang02 Mar 6, 2026
bc9cbc8
UPSTREAM: <carry>: Fix OLMv1 test operator to listen on IPv6
stbenjam Mar 6, 2026
347f617
UPSTREAM: <carry>: Increase install timeout and add diagnostic loggin…
camilamacedo86 Mar 11, 2026
cb2108f
UPSTREAM: <carry>: add service account to curl job
ehearne-redhat Mar 2, 2026
1886e8f
UPSTREAM: <carry>: update OCP-75441 to support multi-arch
jianzhangbjz Mar 19, 2026
029bd39
UPSTREAM: <carry>: deployment config cases
kuiwang02 Feb 6, 2026
c99f92c
UPSTREAM: <carry>: Add OTE tests for OLMv1 DeploymentConfig support
tmshort Mar 11, 2026
4393160
UPSTREAM: <carry>: Update openshift/api and client-go
tmshort Mar 19, 2026
9b58ed2
UPSTREAM: <carry>: Add boxcutter tests
camilamacedo86 Mar 23, 2026
e239302
UPSTREAM: <carry>: enhance QE cases
Xia-Zhao-rh Mar 17, 2026
32fddc2
UPSTREAM: <carry>: Update quay-operator version to one containing arm…
dtfranz Mar 24, 2026
0564cdc
UPSTREAM: <carry>: verify volume/volumeMount override
kuiwang02 Mar 25, 2026
7532648
UPSTREAM: <carry>: Update grpc in default-catalog-consistency tests
tmshort Mar 27, 2026
4b9a304
UPSTREAM: <drop>: go mod vendor
Mar 30, 2026
af6b7b2
UPSTREAM: <drop>: remove upstream GitHub configuration
Mar 30, 2026
7b86fdb
UPSTREAM: <drop>: configure the commit-checker
Mar 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion commitchecker.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
expectedMergeBase: 253feaef5babbdabfb4b63d1cb3a60455947be3a
expectedMergeBase: e709e65344e8e7bc23fc421b96587ee702f1e8e3
upstreamBranch: main
upstreamOrg: operator-framework
upstreamRepo: operator-controller
35 changes: 6 additions & 29 deletions internal/operator-controller/applier/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ func (r *RegistryV1ManifestProvider) extractBundleConfigOptions(rv1 *bundle.Regi
opts = append(opts, render.WithTargetNamespaces(*watchNS))
}

// Extract and convert deploymentConfig if present and the feature gate is enabled.
// Extract deploymentConfig if present and the feature gate is enabled.
if r.IsDeploymentConfigEnabled {
if deploymentConfigMap := bundleConfig.GetDeploymentConfig(); deploymentConfigMap != nil {
deploymentConfig, err := convertToDeploymentConfig(deploymentConfigMap)
if err != nil {
return nil, errorutil.NewTerminalError(ocv1.ReasonInvalidConfiguration, fmt.Errorf("invalid deploymentConfig: %w", err))
}
deploymentConfig, err := bundleConfig.GetDeploymentConfig()
if err != nil {
return nil, errorutil.NewTerminalError(ocv1.ReasonInvalidConfiguration, fmt.Errorf("invalid deploymentConfig: %w", err))
}
if deploymentConfig != nil {
opts = append(opts, render.WithDeploymentConfig(deploymentConfig))
}
}
Expand Down Expand Up @@ -187,29 +187,6 @@ func extensionConfigBytes(ext *ocv1.ClusterExtension) []byte {
return nil
}

// convertToDeploymentConfig converts a map[string]any (from validated bundle config)
// to a *config.DeploymentConfig struct that can be passed to the renderer.
// Returns nil if the map is empty.
func convertToDeploymentConfig(deploymentConfigMap map[string]any) (*config.DeploymentConfig, error) {
if len(deploymentConfigMap) == 0 {
return nil, nil
}

// Marshal the map to JSON
data, err := json.Marshal(deploymentConfigMap)
if err != nil {
return nil, fmt.Errorf("failed to marshal deploymentConfig: %w", err)
}

// Unmarshal into the DeploymentConfig struct
var deploymentConfig config.DeploymentConfig
if err := json.Unmarshal(data, &deploymentConfig); err != nil {
return nil, fmt.Errorf("failed to unmarshal deploymentConfig: %w", err)
}

return &deploymentConfig, nil
}

func getBundleAnnotations(bundleFS fs.FS) (map[string]string, error) {
// The need to get the underlying bundle in order to extract its annotations
// will go away once we have a bundle interface that can surface the annotations independently of the
Expand Down
5 changes: 3 additions & 2 deletions internal/operator-controller/applier/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

ocv1 "github.com/operator-framework/operator-controller/api/v1"
"github.com/operator-framework/operator-controller/internal/operator-controller/applier"
"github.com/operator-framework/operator-controller/internal/operator-controller/config"
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render"
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render/registryv1"
Expand Down Expand Up @@ -599,8 +600,8 @@ func Test_RegistryV1ManifestProvider_DeploymentConfig(t *testing.T) {
BundleRenderer: render.BundleRenderer{
ResourceGenerators: []render.ResourceGenerator{
func(rv1 *bundle.RegistryV1, opts render.Options) ([]client.Object, error) {
t.Log("ensure deploymentConfig is nil for empty config object")
require.Nil(t, opts.DeploymentConfig)
t.Log("ensure deploymentConfig is empty for empty config object")
require.Equal(t, &config.DeploymentConfig{}, opts.DeploymentConfig)
return nil, nil
},
},
Expand Down
39 changes: 12 additions & 27 deletions internal/operator-controller/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,44 +106,29 @@ func (c *Config) GetWatchNamespace() *string {
}

// GetDeploymentConfig returns the deploymentConfig value if present in the configuration.
// Returns nil if deploymentConfig is not set or is explicitly set to null.
// The returned value is a generic map[string]any that can be marshaled to JSON
// for validation or conversion to specific types (like v1alpha1.SubscriptionConfig).
//
// Returns a defensive deep copy so callers can't mutate the internal Config state.
func (c *Config) GetDeploymentConfig() map[string]any {
// Returns (nil, nil) if deploymentConfig is not set or is explicitly set to null.
// Returns a non-nil error if the value cannot be marshaled or unmarshaled into a DeploymentConfig.
func (c *Config) GetDeploymentConfig() (*DeploymentConfig, error) {
if c == nil || *c == nil {
return nil
return nil, nil
}
val, exists := (*c)["deploymentConfig"]
if !exists {
return nil
return nil, nil
}
// User set deploymentConfig: null - treat as "not configured"
if val == nil {
return nil
}
// Schema validation ensures this is an object (map)
dcMap, ok := val.(map[string]any)
if !ok {
return nil
return nil, nil
}

// Return a defensive deep copy so callers can't mutate the internal Config state.
// We use JSON marshal/unmarshal because the data is already JSON-compatible and
// this handles nested structures correctly.
data, err := json.Marshal(dcMap)
data, err := json.Marshal(val)
if err != nil {
// This should never happen since the map came from validated JSON/YAML,
// but return nil as a safe fallback
return nil
return nil, fmt.Errorf("failed to marshal deploymentConfig: %w", err)
}
var copied map[string]any
if err := json.Unmarshal(data, &copied); err != nil {
// This should never happen for valid JSON
return nil
var dc DeploymentConfig
if err := json.Unmarshal(data, &dc); err != nil {
return nil, fmt.Errorf("failed to unmarshal deploymentConfig: %w", err)
}
return copied
return &dc, nil
}

// UnmarshalConfig takes user configuration, validates it, and creates a Config object.
Expand Down
58 changes: 30 additions & 28 deletions internal/operator-controller/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/ptr"

"github.com/operator-framework/api/pkg/operators/v1alpha1"
Expand Down Expand Up @@ -596,7 +598,7 @@ func Test_GetDeploymentConfig(t *testing.T) {
tests := []struct {
name string
rawConfig []byte
expectedDeploymentConfig map[string]any
expectedDeploymentConfig *config.DeploymentConfig
expectedDeploymentConfigNil bool
}{
{
Expand Down Expand Up @@ -628,13 +630,13 @@ func Test_GetDeploymentConfig(t *testing.T) {
}
}
}`),
expectedDeploymentConfig: map[string]any{
"nodeSelector": map[string]any{
expectedDeploymentConfig: &config.DeploymentConfig{
NodeSelector: map[string]string{
"kubernetes.io/os": "linux",
},
"resources": map[string]any{
"requests": map[string]any{
"memory": "128Mi",
Resources: &corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse("128Mi"),
},
},
},
Expand All @@ -650,7 +652,8 @@ func Test_GetDeploymentConfig(t *testing.T) {
cfg, err := config.UnmarshalConfig(tt.rawConfig, schema, "")
require.NoError(t, err)

result := cfg.GetDeploymentConfig()
result, err := cfg.GetDeploymentConfig()
require.NoError(t, err)
if tt.expectedDeploymentConfigNil {
require.Nil(t, result)
} else {
Expand All @@ -663,12 +666,13 @@ func Test_GetDeploymentConfig(t *testing.T) {
// Test nil config separately
t.Run("nil config returns nil", func(t *testing.T) {
var cfg *config.Config
result := cfg.GetDeploymentConfig()
result, err := cfg.GetDeploymentConfig()
require.NoError(t, err)
require.Nil(t, result)
})

// Test that returned map is a defensive copy (mutations don't affect original)
t.Run("returned map is defensive copy - mutations don't affect original", func(t *testing.T) {
// Test that returned struct is a separate instance (mutations don't affect original)
t.Run("returned struct is independent copy - mutations don't affect original", func(t *testing.T) {
rawConfig := []byte(`{
"deploymentConfig": {
"nodeSelector": {
Expand All @@ -684,31 +688,29 @@ func Test_GetDeploymentConfig(t *testing.T) {
require.NoError(t, err)

// Get the deploymentConfig
result1 := cfg.GetDeploymentConfig()
result1, err := cfg.GetDeploymentConfig()
require.NoError(t, err)
require.NotNil(t, result1)

// Mutate the returned map
result1["nodeSelector"] = map[string]any{
"mutated": "value",
}
result1["newField"] = "added"
// Mutate the returned struct
result1.NodeSelector["mutated"] = "value"

// Get deploymentConfig again - should be unaffected by mutations
result2 := cfg.GetDeploymentConfig()
result2, err := cfg.GetDeploymentConfig()
require.NoError(t, err)
require.NotNil(t, result2)

// Original values should be intact
require.Equal(t, map[string]any{
"nodeSelector": map[string]any{
"kubernetes.io/os": "linux",
},
}, result2)

// New field should not exist
_, exists := result2["newField"]
require.False(t, exists)
require.Equal(t, map[string]string{
"kubernetes.io/os": "linux",
}, result2.NodeSelector)
})

// result1 should have the mutations
require.Equal(t, "added", result1["newField"])
// Test that invalid deploymentConfig type returns an error
t.Run("invalid deploymentConfig type returns error", func(t *testing.T) {
cfg := config.Config{"deploymentConfig": "not-an-object"}
result, err := cfg.GetDeploymentConfig()
require.Error(t, err)
require.Nil(t, result)
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ func (c *ClusterExtensionRevisionReconciler) reconcile(ctx context.Context, cer
return ctrl.Result{}, fmt.Errorf("converting to boxcutter revision: %v", err)
}

siblings, err := c.siblingRevisionNames(ctx, cer)
if err != nil {
setRetryingConditions(cer, err.Error())
return ctrl.Result{}, fmt.Errorf("listing sibling revisions: %v", err)
}
Comment on lines +148 to +152
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep foreign-owner collision checks enabled for unlabeled CERs.

Test_ClusterExtensionRevisionReconciler_getScopedClient_Errors already treats a missing labels.OwnerNameKey as supported, but siblingRevisionNames() returns nil there and Line 216 skips foreignRevisionController() entirely. That lets an unlabeled revision progress against objects still controlled by another ClusterExtensionRevision without surfacing the collision.

Suggested fix
-			if ores.Action() == machinery.ActionProgressed && siblings != nil {
+			if ores.Action() == machinery.ActionProgressed {
 				if ref := foreignRevisionController(ores.Object(), siblings); ref != nil {
 					collidingObjs = append(collidingObjs, ores.String()+fmt.Sprintf("\nConflicting Owner: %s", ref.String()))
 				}
 			}
 func (c *ClusterExtensionRevisionReconciler) siblingRevisionNames(ctx context.Context, cer *ocv1.ClusterExtensionRevision) (sets.Set[string], error) {
+	names := sets.New[string](cer.Name)
 	ownerLabel, ok := cer.Labels[labels.OwnerNameKey]
 	if !ok {
-		return nil, nil
+		return names, nil
 	}
 	revList := &ocv1.ClusterExtensionRevisionList{}
 	if err := c.TrackingCache.List(ctx, revList, client.MatchingLabels{
 		labels.OwnerNameKey: ownerLabel,
 	}); err != nil {
 		return nil, fmt.Errorf("listing sibling revisions: %w", err)
 	}
-	names := sets.New[string]()
 	for i := range revList.Items {
 		names.Insert(revList.Items[i].Name)
 	}
 	return names, nil
 }

Also applies to: 216-220, 531-565

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@internal/operator-controller/controllers/clusterextensionrevision_controller.go`
around lines 148 - 152, siblingRevisionNames currently returns nil for unlabeled
ClusterExtensionRevisions which causes the controller to skip foreign-owner
collision checks; update siblingRevisionNames to return an empty slice (not nil)
for unlabeled CERs and/or treat a missing labels.OwnerNameKey as a supported
case so that callers like the reconciler still call
foreignRevisionController(cer, siblings) and perform collision checks; ensure
the reconciler code paths that check siblings (the logic around
siblingRevisionNames and the call to foreignRevisionController in
clusterextensionrevision_controller.go) are changed to invoke
foreignRevisionController even when the owner label is absent, and preserve use
of setRetryingConditions and error handling (do not short-circuit by returning
early with nil siblings).


revisionEngine, err := c.RevisionEngineFactory.CreateRevisionEngine(ctx, cer)
if err != nil {
setRetryingConditions(cer, err.Error())
Expand Down Expand Up @@ -207,6 +213,11 @@ func (c *ClusterExtensionRevisionReconciler) reconcile(ctx context.Context, cer
if ores.Action() == machinery.ActionCollision {
collidingObjs = append(collidingObjs, ores.String())
}
if ores.Action() == machinery.ActionProgressed && siblings != nil {
if ref := foreignRevisionController(ores.Object(), siblings); ref != nil {
collidingObjs = append(collidingObjs, ores.String()+fmt.Sprintf("\nConflicting Owner: %s", ref.String()))
}
}
}

if len(collidingObjs) > 0 {
Expand Down Expand Up @@ -517,6 +528,42 @@ func EffectiveCollisionProtection(cp ...ocv1.CollisionProtection) ocv1.Collision
return ecp
}

// siblingRevisionNames returns the names of all ClusterExtensionRevisions that belong to
// the same ClusterExtension as cer. Returns nil when cer has no owner label.
func (c *ClusterExtensionRevisionReconciler) siblingRevisionNames(ctx context.Context, cer *ocv1.ClusterExtensionRevision) (sets.Set[string], error) {
ownerLabel, ok := cer.Labels[labels.OwnerNameKey]
if !ok {
return nil, nil
}
revList := &ocv1.ClusterExtensionRevisionList{}
if err := c.TrackingCache.List(ctx, revList, client.MatchingLabels{
labels.OwnerNameKey: ownerLabel,
}); err != nil {
return nil, fmt.Errorf("listing sibling revisions: %w", err)
}
names := sets.New[string]()
for i := range revList.Items {
names.Insert(revList.Items[i].Name)
}
return names, nil
}

// foreignRevisionController returns the controller OwnerReference when obj is owned by a
// ClusterExtensionRevision that is not in siblings (i.e. belongs to a different ClusterExtension).
// Returns nil when the controller is a sibling or is not a ClusterExtensionRevision.
func foreignRevisionController(obj metav1.Object, siblings sets.Set[string]) *metav1.OwnerReference {
refs := obj.GetOwnerReferences()
for i := range refs {
if refs[i].Controller != nil && *refs[i].Controller &&
refs[i].Kind == ocv1.ClusterExtensionRevisionKind &&
refs[i].APIVersion == ocv1.GroupVersion.String() &&
!siblings.Has(refs[i].Name) {
return &refs[i]
}
}
return nil
}

// buildProgressionProbes creates a set of boxcutter probes from the fields provided in the CER's spec.progressionProbes.
// Returns nil and an error if encountered while attempting to build the probes.
func buildProgressionProbes(progressionProbes []ocv1.ProgressionProbe) (probing.And, error) {
Expand Down
Loading