Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
1 change: 1 addition & 0 deletions docs/api-reference/catalogd-api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ _Appears in:_
| --- | --- | --- | --- |
| `source` _[CatalogSource](#catalogsource)_ | source is a required field that allows the user to define the source of a Catalog that contains catalog metadata in the File-Based Catalog (FBC) format.<br /><br />Below is a minimal example of a ClusterCatalogSpec that sources a catalog from an image:<br /><br /> source:<br /> type: Image<br /> image:<br /> ref: quay.io/operatorhubio/catalog:latest<br /><br />For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs | | |
| `priority` _integer_ | priority is an optional field that allows the user to define a priority for a ClusterCatalog.<br />A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements.<br />For example, in the case where multiple ClusterCatalogs provide the same bundle.<br />A higher number means higher priority. Negative numbers are also accepted.<br />When omitted, the default priority is 0. | 0 | |
| `availability` _string_ | Availability is an optional field that allows users to define whether the ClusterCatalog is utilized by the operator-controller.<br /><br />Allowed values are : ["Enabled", "Disabled"].<br />If set to "Enabled", the catalog will be used for updates, serving contents, and package installations.<br /><br />If set to "Disabled", catalogd will stop serving the catalog and the cached data will be removed.<br /><br />If unspecified, the default value is "Enabled" | Enabled | Enum: [Disabled Enabled] <br /> |


#### ClusterCatalogStatus
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/onsi/gomega v1.34.2
github.com/opencontainers/go-digest v1.0.0
github.com/operator-framework/api v0.27.0
github.com/operator-framework/catalogd v0.32.0
github.com/operator-framework/catalogd v0.33.0
github.com/operator-framework/helm-operator-plugins v0.5.0
github.com/operator-framework/operator-registry v1.47.0
github.com/spf13/pflag v1.0.5
Expand Down Expand Up @@ -179,7 +179,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/proglottis/gpgme v0.1.3 // indirect
github.com/prometheus/client_golang v1.20.4 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ github.com/openshift/crd-schema-checker v0.0.0-20240404194209-35a9033b1d11 h1:eT
github.com/openshift/crd-schema-checker v0.0.0-20240404194209-35a9033b1d11/go.mod h1:EmVJt97N+pfWFsli/ipXTBZqSG5F5KGQhm3c3IsGq1o=
github.com/operator-framework/api v0.27.0 h1:OrVaGKZJvbZo58HTv2guz7aURkhVKYhFqZ/6VpifiXI=
github.com/operator-framework/api v0.27.0/go.mod h1:lg2Xx+S8NQWGYlEOvFwQvH46E5EK5IrAIL7HWfAhciM=
github.com/operator-framework/catalogd v0.32.0 h1:VKD+7wfEF6CnJgR4aUYyT85KP2Te7zjhaPvgvWy25Uw=
github.com/operator-framework/catalogd v0.32.0/go.mod h1:FrFSCwRXr4aPslcXIv48dan5AdM37k/B9tK/RpdvZCU=
github.com/operator-framework/catalogd v0.33.0 h1:hnLIFykO1FkjOAUFRPuYRIHQTE0oBF9jkGmWjKhxniQ=
github.com/operator-framework/catalogd v0.33.0/go.mod h1:anZurjcFMBvbkuyqlJ98v9z+yjniPKqmhlyitk9DuBQ=
github.com/operator-framework/helm-operator-plugins v0.5.0 h1:qph2OoECcI9mpuUBtOsWOMgvpx52mPTTSvzVxICsT04=
github.com/operator-framework/helm-operator-plugins v0.5.0/go.mod h1:yVncrZ/FJNqedMil+055fk6sw8aMKRrget/AqGM0ig0=
github.com/operator-framework/operator-lib v0.15.0 h1:0QeRM4PMtThqINpcFGCEBnIV3Z8u7/8fYLEx6mUtdcM=
Expand Down Expand Up @@ -569,8 +569,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI=
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
Expand Down
20 changes: 19 additions & 1 deletion internal/resolve/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resolve
import (
"context"
"fmt"
"sigs.k8s.io/controller-runtime/pkg/log"
"slices"
"sort"
"strings"
Expand Down Expand Up @@ -231,20 +232,37 @@ func isDeprecated(bundle declcfg.Bundle, deprecation *declcfg.Deprecation) bool

type CatalogWalkFunc func(context.Context, *catalogd.ClusterCatalog, *declcfg.DeclarativeConfig, error) error

func CatalogWalker(listCatalogs func(context.Context, ...client.ListOption) ([]catalogd.ClusterCatalog, error), getPackage func(context.Context, *catalogd.ClusterCatalog, string) (*declcfg.DeclarativeConfig, error)) func(ctx context.Context, packageName string, f CatalogWalkFunc, catalogListOpts ...client.ListOption) error {
func CatalogWalker(
listCatalogs func(context.Context, ...client.ListOption) ([]catalogd.ClusterCatalog, error),
getPackage func(context.Context, *catalogd.ClusterCatalog, string) (*declcfg.DeclarativeConfig, error),
) func(ctx context.Context, packageName string, f CatalogWalkFunc, catalogListOpts ...client.ListOption) error {
return func(ctx context.Context, packageName string, f CatalogWalkFunc, catalogListOpts ...client.ListOption) error {
l := log.FromContext(ctx)
catalogs, err := listCatalogs(ctx, catalogListOpts...)
if err != nil {
return fmt.Errorf("error listing catalogs: %w", err)
}

// Remove disabled catalogs from consideration
catalogs = slices.DeleteFunc(catalogs, func(c catalogd.ClusterCatalog) bool {
if c.Spec.Availability == "Disabled" {
l.Info("excluding ClusterCatalog from resolution process since it is disabled", "catalog", c.Name)
return true
}
return false
})

for i := range catalogs {
cat := &catalogs[i]

// process enabled catalogs
fbc, fbcErr := getPackage(ctx, cat, packageName)

if walkErr := f(ctx, cat, fbc, fbcErr); walkErr != nil {
return walkErr
}
}

return nil
}
}
72 changes: 72 additions & 0 deletions internal/resolve/catalog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -963,3 +963,75 @@ func TestMultipleChannels(t *testing.T) {
assert.Equal(t, bsemver.MustParse("2.0.0"), *gotVersion)
assert.Equal(t, ptr.To(packageDeprecation(pkgName)), gotDeprecation)
}

func TestAllCatalogsDisabled(t *testing.T) {
pkgName := randPkg()
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
return []catalogd.ClusterCatalog{
{
Spec: catalogd.ClusterCatalogSpec{
Availability: "Disabled",
},
},
{
Spec: catalogd.ClusterCatalogSpec{
Availability: "Disabled",
},
},
}, nil
}

getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
panic("getPackage should never be called when all catalogs are disabled")
}

r := CatalogResolver{
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
}

ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
_, _, _, err := r.Resolve(context.Background(), ce, nil)
require.Error(t, err)
assert.Contains(t, err.Error(), "no bundles found for package")
}

func TestSomeCatalogsDisabled(t *testing.T) {
pkgName := randPkg()
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
return []catalogd.ClusterCatalog{
{
ObjectMeta: metav1.ObjectMeta{
Name: "enabledCatalog",
},
Spec: catalogd.ClusterCatalogSpec{
Priority: 1, // Higher priority
Availability: "Enabled",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "disabledCatalog",
},
Spec: catalogd.ClusterCatalogSpec{
Priority: 0, // Lower priority (but disabled)
Availability: "Disabled",
},
},
}, nil
}

getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
// Only enabled catalog should be processed
return genPackage(pkgName), nil
}

r := CatalogResolver{
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
}

ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
gotBundle, gotVersion, _, err := r.Resolve(context.Background(), ce, nil)
require.NoError(t, err)
require.NotNil(t, gotBundle)
require.Equal(t, bsemver.MustParse("3.0.0"), *gotVersion)
}
Loading