Skip to content

Commit 775fc0e

Browse files
committed
Add support for catalogs with Spec.Availability
Signed-off-by: Brett Tofel <[email protected]>
1 parent 79f42d5 commit 775fc0e

File tree

3 files changed

+184
-0
lines changed

3 files changed

+184
-0
lines changed

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ require (
3737
sigs.k8s.io/yaml v1.4.0
3838
)
3939

40+
replace (
41+
github.com/operator-framework/catalogd => ../catalogd
42+
)
43+
4044
require (
4145
carvel.dev/vendir v0.40.0 // indirect
4246
dario.cat/mergo v1.0.1 // indirect

internal/resolve/catalog.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package resolve
33
import (
44
"context"
55
"fmt"
6+
"sigs.k8s.io/controller-runtime/pkg/log"
67
"slices"
78
"sort"
89
"strings"
@@ -233,18 +234,50 @@ type CatalogWalkFunc func(context.Context, *catalogd.ClusterCatalog, *declcfg.De
233234

234235
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 {
235236
return func(ctx context.Context, packageName string, f CatalogWalkFunc, catalogListOpts ...client.ListOption) error {
237+
l := log.FromContext(ctx)
236238
catalogs, err := listCatalogs(ctx, catalogListOpts...)
237239
if err != nil {
238240
return fmt.Errorf("error listing catalogs: %w", err)
239241
}
240242

243+
// Track if at least one catalog was processed (not disabled)
244+
processedCatalogs := false
245+
bundleFound := false
246+
241247
for i := range catalogs {
242248
cat := &catalogs[i]
249+
250+
// skip catalogs with Availability set to "Disabled"
251+
if cat.Spec.Availability == "" || cat.Spec.Availability == "Enabled" {
252+
// Continue processing the catalog as it is enabled
253+
} else if cat.Spec.Availability == "Disabled" {
254+
l.Info("excluding ClusterCatalog from resolution process since it is disabled", "catalog", cat.Name)
255+
continue
256+
}
257+
258+
// Mark that we processed at least one catalog
259+
processedCatalogs = true
260+
243261
fbc, fbcErr := getPackage(ctx, cat, packageName)
262+
if fbcErr == nil && fbc != nil {
263+
bundleFound = true
264+
}
265+
244266
if walkErr := f(ctx, cat, fbc, fbcErr); walkErr != nil {
245267
return walkErr
246268
}
247269
}
270+
271+
// If no catalogs were processed at all, return a 'no catalogs' error
272+
if !processedCatalogs {
273+
return fmt.Errorf("no enabled catalogs found for package: %s", packageName)
274+
}
275+
276+
// Return an error if no valid bundle was found in any processed catalog
277+
if !bundleFound {
278+
return fmt.Errorf("no bundles found for package: %s", packageName)
279+
}
280+
248281
return nil
249282
}
250283
}

internal/resolve/catalog_test.go

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,3 +963,150 @@ func TestMultipleChannels(t *testing.T) {
963963
assert.Equal(t, bsemver.MustParse("2.0.0"), *gotVersion)
964964
assert.Equal(t, ptr.To(packageDeprecation(pkgName)), gotDeprecation)
965965
}
966+
967+
func TestAllCatalogsDisabled(t *testing.T) {
968+
pkgName := randPkg()
969+
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
970+
return []catalogd.ClusterCatalog{
971+
{
972+
Spec: catalogd.ClusterCatalogSpec{
973+
Availability: "Disabled",
974+
},
975+
},
976+
{
977+
Spec: catalogd.ClusterCatalogSpec{
978+
Availability: "Disabled",
979+
},
980+
},
981+
}, nil
982+
}
983+
984+
getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
985+
return genPackage(pkgName), nil
986+
}
987+
988+
r := CatalogResolver{
989+
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
990+
}
991+
992+
ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
993+
_, _, _, err := r.Resolve(context.Background(), ce, nil)
994+
require.Error(t, err)
995+
assert.Contains(t, err.Error(), "no enabled catalogs found for package")
996+
}
997+
998+
func TestSomeCatalogsDisabled(t *testing.T) {
999+
pkgName := randPkg()
1000+
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
1001+
return []catalogd.ClusterCatalog{
1002+
{
1003+
Spec: catalogd.ClusterCatalogSpec{
1004+
Availability: "Enabled",
1005+
},
1006+
},
1007+
{
1008+
Spec: catalogd.ClusterCatalogSpec{
1009+
Availability: "Disabled",
1010+
},
1011+
},
1012+
}, nil
1013+
}
1014+
1015+
getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
1016+
return genPackage(pkgName), nil
1017+
}
1018+
1019+
r := CatalogResolver{
1020+
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
1021+
}
1022+
1023+
ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
1024+
gotBundle, gotVersion, _, err := r.Resolve(context.Background(), ce, nil)
1025+
require.NoError(t, err)
1026+
require.NotNil(t, gotBundle)
1027+
require.Equal(t, bsemver.MustParse("3.0.0"), *gotVersion)
1028+
}
1029+
1030+
func TestPriorityRespectedWithDisabledCatalogs(t *testing.T) {
1031+
pkgName := randPkg()
1032+
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
1033+
return []catalogd.ClusterCatalog{
1034+
{
1035+
Spec: catalogd.ClusterCatalogSpec{
1036+
Priority: 1,
1037+
Availability: "Enabled",
1038+
},
1039+
},
1040+
{
1041+
Spec: catalogd.ClusterCatalogSpec{
1042+
Priority: 0,
1043+
Availability: "Disabled",
1044+
},
1045+
},
1046+
}, nil
1047+
}
1048+
1049+
getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
1050+
return genPackage(pkgName), nil
1051+
}
1052+
1053+
r := CatalogResolver{
1054+
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
1055+
}
1056+
1057+
ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
1058+
gotBundle, gotVersion, _, err := r.Resolve(context.Background(), ce, nil)
1059+
require.NoError(t, err)
1060+
require.NotNil(t, gotBundle)
1061+
require.Equal(t, bsemver.MustParse("3.0.0"), *gotVersion)
1062+
}
1063+
1064+
func TestCatalogWithoutAvailabilityIsEnabled(t *testing.T) {
1065+
pkgName := randPkg()
1066+
listCatalogs := func(ctx context.Context, options ...client.ListOption) ([]catalogd.ClusterCatalog, error) {
1067+
return []catalogd.ClusterCatalog{
1068+
{
1069+
Spec: catalogd.ClusterCatalogSpec{
1070+
Priority: 1, // No Availability field set
1071+
},
1072+
},
1073+
{
1074+
Spec: catalogd.ClusterCatalogSpec{
1075+
Availability: "Disabled", // This should be skipped
1076+
Priority: 2,
1077+
},
1078+
},
1079+
}, nil
1080+
}
1081+
1082+
getPackage := func(ctx context.Context, cat *catalogd.ClusterCatalog, packageName string) (*declcfg.DeclarativeConfig, error) {
1083+
if cat.Spec.Availability == "" || cat.Spec.Availability == "Enabled" {
1084+
return genPackage(pkgName), nil
1085+
}
1086+
return &declcfg.DeclarativeConfig{
1087+
Packages: []declcfg.Package{{Name: pkgName}},
1088+
Channels: []declcfg.Channel{
1089+
{
1090+
Package: pkgName,
1091+
Name: "alpha",
1092+
Entries: []declcfg.ChannelEntry{
1093+
{Name: bundleName(pkgName, "3.0.0")},
1094+
},
1095+
},
1096+
},
1097+
Bundles: []declcfg.Bundle{
1098+
genBundle(pkgName, "3.0.0"),
1099+
},
1100+
}, nil
1101+
}
1102+
1103+
r := CatalogResolver{
1104+
WalkCatalogsFunc: CatalogWalker(listCatalogs, getPackage),
1105+
}
1106+
1107+
ce := buildFooClusterExtension(pkgName, []string{}, ">=1.0.0", ocv1alpha1.UpgradeConstraintPolicyCatalogProvided)
1108+
gotBundle, gotVersion, _, err := r.Resolve(context.Background(), ce, nil)
1109+
require.NoError(t, err)
1110+
require.NotNil(t, gotBundle)
1111+
require.Equal(t, bsemver.MustParse("3.0.0"), *gotVersion, "expected version to be 3.0.0, but got %s", gotVersion)
1112+
}

0 commit comments

Comments
 (0)