diff --git a/alpha/action/diff.go b/alpha/action/diff.go index 9bd5d7501..cb9269626 100644 --- a/alpha/action/diff.go +++ b/alpha/action/diff.go @@ -90,7 +90,7 @@ func (p Diff) validate() error { } // DiffIncludeConfig configures Diff.Run() to include a set of packages, -// channels, and/or bundle versions in the output DeclarativeConfig. +// channels, and/or bundles/versions in the output DeclarativeConfig. // These override other diff mechanisms. For example, if running in // heads-only mode but package "foo" channel "stable" is specified, // the entire "stable" channel (all channel bundles) is added to the output. @@ -110,6 +110,10 @@ type DiffIncludePackage struct { // Versions to include. All channels containing these versions // are parsed for an upgrade graph. Versions []semver.Version `json:"versions,omitempty" yaml:"versions,omitempty"` + // Bundles are bundle names to include. All channels containing these bundles + // are parsed for an upgrade graph. + // Set this field only if the named bundle has no semantic version metadata. + Bundles []string `json:"bundles,omitempty" yaml:"bundles,omitempty"` } // DiffIncludeChannel contains a name (required) and versions (optional) @@ -119,6 +123,9 @@ type DiffIncludeChannel struct { Name string `json:"name" yaml:"name"` // Versions to include. Versions []semver.Version `json:"versions,omitempty" yaml:"versions,omitempty"` + // Bundles are bundle names to include. + // Set this field only if the named bundle has no semantic version metadata. + Bundles []string `json:"bundles,omitempty" yaml:"bundles,omitempty"` } // LoadDiffIncludeConfig loads a (YAML or JSON) DiffIncludeConfig from r. @@ -154,6 +161,7 @@ func convertIncludeConfigToIncluder(c DiffIncludeConfig) (includer declcfg.DiffI pkg := &includer.Packages[pkgI] pkg.Name = cpkg.Name pkg.AllChannels.Versions = cpkg.Versions + pkg.AllChannels.Bundles = cpkg.Bundles if len(cpkg.Channels) != 0 { pkg.Channels = make([]declcfg.DiffIncludeChannel, len(cpkg.Channels)) @@ -161,6 +169,7 @@ func convertIncludeConfigToIncluder(c DiffIncludeConfig) (includer declcfg.DiffI ch := &pkg.Channels[chI] ch.Name = cch.Name ch.Versions = cch.Versions + ch.Bundles = cch.Bundles } } } diff --git a/alpha/action/diff_test.go b/alpha/action/diff_test.go index fc7f9fb64..ae4082bfd 100644 --- a/alpha/action/diff_test.go +++ b/alpha/action/diff_test.go @@ -52,6 +52,87 @@ func TestDiff(t *testing.T) { expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-headsonly")), assertion: require.NoError, }, + { + name: "Success/IncludePackage", + diff: Diff{ + Registry: registry, + NewRefs: []string{filepath.Join("testdata", "index-declcfgs", "latest")}, + IncludeConfig: DiffIncludeConfig{ + Packages: []DiffIncludePackage{{Name: "baz"}}, + }, + }, + expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-include-pkg")), + assertion: require.NoError, + }, + { + name: "Success/IncludeChannel", + diff: Diff{ + Registry: registry, + NewRefs: []string{filepath.Join("testdata", "index-declcfgs", "latest")}, + IncludeConfig: DiffIncludeConfig{ + Packages: []DiffIncludePackage{ + { + Name: "baz", + Channels: []DiffIncludeChannel{{Name: "stable"}}, + }, + }, + }, + }, + expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-include-channel")), + assertion: require.NoError, + }, + { + name: "Success/IncludeVersion", + diff: Diff{ + Registry: registry, + NewRefs: []string{filepath.Join("testdata", "index-declcfgs", "latest")}, + IncludeConfig: DiffIncludeConfig{ + Packages: []DiffIncludePackage{ + { + Name: "baz", + Versions: []semver.Version{semver.MustParse("1.0.0")}, + }, + }, + }, + }, + expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-include-channel")), + assertion: require.NoError, + }, + { + name: "Success/IncludeBundle", + diff: Diff{ + Registry: registry, + NewRefs: []string{filepath.Join("testdata", "index-declcfgs", "latest")}, + IncludeConfig: DiffIncludeConfig{ + Packages: []DiffIncludePackage{ + { + Name: "baz", + Bundles: []string{"baz.v1.0.0"}, + }, + }, + }, + }, + expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-include-channel")), + assertion: require.NoError, + }, + { + name: "Success/IncludeSameVersionAndBundle", + diff: Diff{ + Registry: registry, + NewRefs: []string{filepath.Join("testdata", "index-declcfgs", "latest")}, + IncludeConfig: DiffIncludeConfig{ + Packages: []DiffIncludePackage{ + { + Name: "baz", + Versions: []semver.Version{semver.MustParse("1.0.0")}, + Bundles: []string{"baz.v1.0.0"}, + }, + }, + }, + }, + expectedCfg: loadDirFS(t, indicesDir, filepath.Join("testdata", "index-declcfgs", "exp-include-channel")), + assertion: require.NoError, + }, { name: "Fail/NewBundleImage", diff: Diff{ @@ -125,6 +206,8 @@ packages: - name: foo channels: - name: stable + bundles: + - foo.v0.3.0 versions: - 0.1.0 - 0.2.0 @@ -137,16 +220,19 @@ packages: - 0.1.0 versions: - 1.0.0 + bundles: + - bar.v1.2.0 `, expectedCfg: DiffIncludeConfig{ Packages: []DiffIncludePackage{ { Name: "foo", Channels: []DiffIncludeChannel{ - {Name: "stable", Versions: []semver.Version{ - semver.MustParse("0.1.0"), - semver.MustParse("0.2.0"), - }}, + { + Name: "stable", + Versions: []semver.Version{semver.MustParse("0.1.0"), semver.MustParse("0.2.0")}, + Bundles: []string{"foo.v0.3.0"}, + }, }, Versions: []semver.Version{semver.MustParse("1.0.0")}, }, @@ -158,6 +244,7 @@ packages: }}, }, Versions: []semver.Version{semver.MustParse("1.0.0")}, + Bundles: []string{"bar.v1.2.0"}, }, }, }, @@ -166,10 +253,11 @@ packages: { Name: "foo", Channels: []declcfg.DiffIncludeChannel{ - {Name: "stable", Versions: []semver.Version{ - semver.MustParse("0.1.0"), - semver.MustParse("0.2.0"), - }}, + { + Name: "stable", + Versions: []semver.Version{semver.MustParse("0.1.0"), semver.MustParse("0.2.0")}, + Bundles: []string{"foo.v0.3.0"}, + }, }, AllChannels: declcfg.DiffIncludeChannel{ Versions: []semver.Version{semver.MustParse("1.0.0")}, @@ -184,6 +272,7 @@ packages: }, AllChannels: declcfg.DiffIncludeChannel{ Versions: []semver.Version{semver.MustParse("1.0.0")}, + Bundles: []string{"bar.v1.2.0"}, }, }, }, diff --git a/alpha/action/testdata/index-declcfgs/exp-headsonly/index.yaml b/alpha/action/testdata/index-declcfgs/exp-headsonly/index.yaml index 6aef07f88..4b8fc1045 100644 --- a/alpha/action/testdata/index-declcfgs/exp-headsonly/index.yaml +++ b/alpha/action/testdata/index-declcfgs/exp-headsonly/index.yaml @@ -10,6 +10,7 @@ entries: - name: bar.v0.1.0 - name: bar.v0.2.0 replaces: bar.v0.1.0 + skipRange: <0.2.0 skips: - bar.v0.1.0 - name: bar.v1.0.0 diff --git a/alpha/action/testdata/index-declcfgs/exp-include-channel/index.yaml b/alpha/action/testdata/index-declcfgs/exp-include-channel/index.yaml new file mode 100644 index 000000000..f49e7ae20 --- /dev/null +++ b/alpha/action/testdata/index-declcfgs/exp-include-channel/index.yaml @@ -0,0 +1,248 @@ +--- +defaultChannel: stable +name: bar +schema: olm.package +--- +name: alpha +package: bar +schema: olm.channel +entries: + - name: bar.v0.1.0 + - name: bar.v0.2.0 + replaces: bar.v0.1.0 + skipRange: <0.2.0 + skips: + - bar.v0.1.0 + - name: bar.v1.0.0 + replaces: bar.v0.2.0 +--- +name: stable +package: bar +schema: olm.channel +entries: + - name: bar.v1.0.0 +--- +# Added because foo.v0.3.1 depends on bar <0.2.0 +image: test.registry/bar-operator/bar-bundle:v0.1.0 +name: bar.v0.1.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhci52MC4xLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxYWxwaGExIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhci1vcGVyYXRvci9iYXI6djAuMS4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJ2ZXJzaW9uIjoiMC4xLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 0.1.0 +relatedImages: +- image: test.registry/bar-operator/bar:v0.1.0 + name: operator +schema: olm.bundle +--- +# Added because foo.v0.3.1 depends on Bar, test.bar/v1alpha1. +# Note that dependency selection cannot decide between bar 0.1.0 +# and 0.2.0, as this is resolver territory. +image: test.registry/bar-operator/bar-bundle:v0.2.0 +name: bar.v0.2.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsib2xtLnNraXBSYW5nZSI6Ilx1MDAzYzAuMi4wIn0sIm5hbWUiOiJiYXIudjAuMi4wIn0sInNwZWMiOnsiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3siZ3JvdXAiOiJ0ZXN0LmJhciIsImtpbmQiOiJCYXIiLCJuYW1lIjoiYmFycy50ZXN0LmJhciIsInZlcnNpb24iOiJ2MWFscGhhMSJ9XX0sInJlbGF0ZWRJbWFnZXMiOlt7ImltYWdlIjoidGVzdC5yZWdpc3RyeS9iYXItb3BlcmF0b3IvYmFyOnYwLjIuMCIsIm5hbWUiOiJvcGVyYXRvciJ9XSwic2tpcHMiOlsiYmFyLnYwLjEuMCJdLCJ2ZXJzaW9uIjoiMC4yLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 0.2.0 +relatedImages: +- image: test.registry/bar-operator/bar:v0.2.0 + name: operator +schema: olm.bundle +--- +image: test.registry/bar-operator/bar-bundle:v1.0.0 +name: bar.v1.0.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSIsInNlcnZlZCI6dHJ1ZSwic3RvcmFnZSI6ZmFsc2V9LHsibmFtZSI6InYxIiwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfV19fQ== +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhci52MS4wLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxYWxwaGExIn0seyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhci1vcGVyYXRvci9iYXI6djEuMC4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImJhci52MC4yLjAiLCJ2ZXJzaW9uIjoiMS4wLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1 +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 1.0.0 +relatedImages: +- image: test.registry/bar-operator/bar:v1.0.0 + name: operator +schema: olm.bundle +--- +defaultChannel: stable +name: baz +schema: olm.package +--- +schema: olm.channel +package: baz +name: stable +entries: +- name: baz.v1.0.0 + skipRange: <1.0.0 +- name: baz.v1.0.1 + replaces: baz.v1.0.0 + skipRange: <1.0.0 + skips: + - baz.v1.0.0 +- name: baz.v1.1.0 + replaces: baz.v1.0.0 + skips: + - baz.v1.0.1 +--- +image: test.registry/baz-operator/baz-bundle:v1.0.0 +name: baz.v1.0.0 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhei52MS4wLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmF6Iiwia2luZCI6IkJheiIsIm5hbWUiOiJiYXpzLnRlc3QuYmF6IiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhei1vcGVyYXRvci9iYXo6djEuMC4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJ2ZXJzaW9uIjoiMS4wLjAifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.0.0 +relatedImages: +- image: test.registry/baz-operator/baz:v1.0.0 + name: operator +schema: olm.bundle +--- +image: test.registry/baz-operator/baz-bundle:v1.0.1 +name: baz.v1.0.1 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsib2xtLnNraXBSYW5nZSI6Ilx1MDAzYzEuMC4xIn0sIm5hbWUiOiJiYXoudjEuMC4xIn0sInNwZWMiOnsiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3siZ3JvdXAiOiJ0ZXN0LmJheiIsImtpbmQiOiJCYXoiLCJuYW1lIjoiYmF6cy50ZXN0LmJheiIsInZlcnNpb24iOiJ2MSJ9XX0sInJlbGF0ZWRJbWFnZXMiOlt7ImltYWdlIjoidGVzdC5yZWdpc3RyeS9iYXotb3BlcmF0b3IvYmF6OnYxLjAuMSIsIm5hbWUiOiJvcGVyYXRvciJ9XSwic2tpcHMiOlsiYmF6LnYxLjAuMCJdLCJ2ZXJzaW9uIjoiMS4wLjEifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.0.1 +relatedImages: +- image: test.registry/baz-operator/baz:v1.0.1 + name: operator +schema: olm.bundle +--- +image: test.registry/baz-operator/baz-bundle:v1.1.0 +name: baz.v1.1.0 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhei52MS4xLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmF6Iiwia2luZCI6IkJheiIsIm5hbWUiOiJiYXpzLnRlc3QuYmF6IiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhei1vcGVyYXRvci9iYXo6djEuMS4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImJhei52MS4wLjAiLCJ2ZXJzaW9uIjoiMS4xLjAifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.1.0 +relatedImages: +- image: test.registry/baz-operator/baz:v1.1.0 + name: operator +schema: olm.bundle +--- +defaultChannel: beta +name: foo +schema: olm.package +--- +name: beta +package: foo +schema: olm.channel +entries: + - name: foo.v0.3.1 + replaces: foo.v0.2.0 + skips: + - foo.v0.3.0 +--- +image: test.registry/foo-operator/foo-bundle:v0.3.1 +name: foo.v0.3.1 +package: foo +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImZvb3MudGVzdC5mb28ifSwic3BlYyI6eyJncm91cCI6InRlc3QuZm9vIiwibmFtZXMiOnsia2luZCI6IkZvbyIsInBsdXJhbCI6ImZvb3MifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSIsInNlcnZlZCI6dHJ1ZSwic3RvcmFnZSI6ZmFsc2V9LHsibmFtZSI6InYyIiwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfV19fQ== +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImZvby52MC4zLjEifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuZm9vIiwia2luZCI6IkZvbyIsIm5hbWUiOiJmb29zLnRlc3QuZm9vIiwidmVyc2lvbiI6InYxIn0seyJncm91cCI6InRlc3QuZm9vIiwia2luZCI6IkZvbyIsIm5hbWUiOiJmb29zLnRlc3QuZm9vIiwidmVyc2lvbiI6InYyIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Zvby1vcGVyYXRvci9mb286djAuMy4xIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImZvby52MC4yLjAiLCJza2lwcyI6WyJmb28udjAuMy4wIl0sInZlcnNpb24iOiIwLjMuMSJ9fQ== +- type: olm.gvk + value: + group: test.foo + kind: Foo + version: v1 +- type: olm.gvk + value: + group: test.foo + kind: Foo + version: v2 +- type: olm.gvk.required + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: foo + version: 0.3.1 +- type: olm.package.required + value: + packageName: bar + packageName: bar + versionRange: <0.2.0 +relatedImages: +- image: test.registry/foo-operator/foo:v0.3.1 + name: operator +schema: olm.bundle diff --git a/alpha/action/testdata/index-declcfgs/exp-include-pkg/index.yaml b/alpha/action/testdata/index-declcfgs/exp-include-pkg/index.yaml new file mode 100644 index 000000000..f49e7ae20 --- /dev/null +++ b/alpha/action/testdata/index-declcfgs/exp-include-pkg/index.yaml @@ -0,0 +1,248 @@ +--- +defaultChannel: stable +name: bar +schema: olm.package +--- +name: alpha +package: bar +schema: olm.channel +entries: + - name: bar.v0.1.0 + - name: bar.v0.2.0 + replaces: bar.v0.1.0 + skipRange: <0.2.0 + skips: + - bar.v0.1.0 + - name: bar.v1.0.0 + replaces: bar.v0.2.0 +--- +name: stable +package: bar +schema: olm.channel +entries: + - name: bar.v1.0.0 +--- +# Added because foo.v0.3.1 depends on bar <0.2.0 +image: test.registry/bar-operator/bar-bundle:v0.1.0 +name: bar.v0.1.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhci52MC4xLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxYWxwaGExIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhci1vcGVyYXRvci9iYXI6djAuMS4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJ2ZXJzaW9uIjoiMC4xLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 0.1.0 +relatedImages: +- image: test.registry/bar-operator/bar:v0.1.0 + name: operator +schema: olm.bundle +--- +# Added because foo.v0.3.1 depends on Bar, test.bar/v1alpha1. +# Note that dependency selection cannot decide between bar 0.1.0 +# and 0.2.0, as this is resolver territory. +image: test.registry/bar-operator/bar-bundle:v0.2.0 +name: bar.v0.2.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsib2xtLnNraXBSYW5nZSI6Ilx1MDAzYzAuMi4wIn0sIm5hbWUiOiJiYXIudjAuMi4wIn0sInNwZWMiOnsiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3siZ3JvdXAiOiJ0ZXN0LmJhciIsImtpbmQiOiJCYXIiLCJuYW1lIjoiYmFycy50ZXN0LmJhciIsInZlcnNpb24iOiJ2MWFscGhhMSJ9XX0sInJlbGF0ZWRJbWFnZXMiOlt7ImltYWdlIjoidGVzdC5yZWdpc3RyeS9iYXItb3BlcmF0b3IvYmFyOnYwLjIuMCIsIm5hbWUiOiJvcGVyYXRvciJ9XSwic2tpcHMiOlsiYmFyLnYwLjEuMCJdLCJ2ZXJzaW9uIjoiMC4yLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 0.2.0 +relatedImages: +- image: test.registry/bar-operator/bar:v0.2.0 + name: operator +schema: olm.bundle +--- +image: test.registry/bar-operator/bar-bundle:v1.0.0 +name: bar.v1.0.0 +package: bar +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhcnMudGVzdC5iYXIifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmFyIiwibmFtZXMiOnsia2luZCI6IkJhciIsInBsdXJhbCI6ImJhcnMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MWFscGhhMSIsInNlcnZlZCI6dHJ1ZSwic3RvcmFnZSI6ZmFsc2V9LHsibmFtZSI6InYxIiwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfV19fQ== +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhci52MS4wLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxYWxwaGExIn0seyJncm91cCI6InRlc3QuYmFyIiwia2luZCI6IkJhciIsIm5hbWUiOiJiYXJzLnRlc3QuYmFyIiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhci1vcGVyYXRvci9iYXI6djEuMC4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImJhci52MC4yLjAiLCJ2ZXJzaW9uIjoiMS4wLjAifX0= +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1 +- type: olm.gvk + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: bar + version: 1.0.0 +relatedImages: +- image: test.registry/bar-operator/bar:v1.0.0 + name: operator +schema: olm.bundle +--- +defaultChannel: stable +name: baz +schema: olm.package +--- +schema: olm.channel +package: baz +name: stable +entries: +- name: baz.v1.0.0 + skipRange: <1.0.0 +- name: baz.v1.0.1 + replaces: baz.v1.0.0 + skipRange: <1.0.0 + skips: + - baz.v1.0.0 +- name: baz.v1.1.0 + replaces: baz.v1.0.0 + skips: + - baz.v1.0.1 +--- +image: test.registry/baz-operator/baz-bundle:v1.0.0 +name: baz.v1.0.0 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhei52MS4wLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmF6Iiwia2luZCI6IkJheiIsIm5hbWUiOiJiYXpzLnRlc3QuYmF6IiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhei1vcGVyYXRvci9iYXo6djEuMC4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJ2ZXJzaW9uIjoiMS4wLjAifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.0.0 +relatedImages: +- image: test.registry/baz-operator/baz:v1.0.0 + name: operator +schema: olm.bundle +--- +image: test.registry/baz-operator/baz-bundle:v1.0.1 +name: baz.v1.0.1 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsiYW5ub3RhdGlvbnMiOnsib2xtLnNraXBSYW5nZSI6Ilx1MDAzYzEuMC4xIn0sIm5hbWUiOiJiYXoudjEuMC4xIn0sInNwZWMiOnsiY3VzdG9tcmVzb3VyY2VkZWZpbml0aW9ucyI6eyJvd25lZCI6W3siZ3JvdXAiOiJ0ZXN0LmJheiIsImtpbmQiOiJCYXoiLCJuYW1lIjoiYmF6cy50ZXN0LmJheiIsInZlcnNpb24iOiJ2MSJ9XX0sInJlbGF0ZWRJbWFnZXMiOlt7ImltYWdlIjoidGVzdC5yZWdpc3RyeS9iYXotb3BlcmF0b3IvYmF6OnYxLjAuMSIsIm5hbWUiOiJvcGVyYXRvciJ9XSwic2tpcHMiOlsiYmF6LnYxLjAuMCJdLCJ2ZXJzaW9uIjoiMS4wLjEifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.0.1 +relatedImages: +- image: test.registry/baz-operator/baz:v1.0.1 + name: operator +schema: olm.bundle +--- +image: test.registry/baz-operator/baz-bundle:v1.1.0 +name: baz.v1.1.0 +package: baz +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhenMudGVzdC5iYXoifSwic3BlYyI6eyJncm91cCI6InRlc3QuYmF6IiwibmFtZXMiOnsia2luZCI6IkJheiIsInBsdXJhbCI6ImJhenMifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSJ9XX19 +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImJhei52MS4xLjAifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuYmF6Iiwia2luZCI6IkJheiIsIm5hbWUiOiJiYXpzLnRlc3QuYmF6IiwidmVyc2lvbiI6InYxIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Jhei1vcGVyYXRvci9iYXo6djEuMS4wIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImJhei52MS4wLjAiLCJ2ZXJzaW9uIjoiMS4xLjAifX0= +- type: olm.gvk + value: + group: test.baz + kind: Baz + version: v1 +- type: olm.package + value: + packageName: baz + version: 1.1.0 +relatedImages: +- image: test.registry/baz-operator/baz:v1.1.0 + name: operator +schema: olm.bundle +--- +defaultChannel: beta +name: foo +schema: olm.package +--- +name: beta +package: foo +schema: olm.channel +entries: + - name: foo.v0.3.1 + replaces: foo.v0.2.0 + skips: + - foo.v0.3.0 +--- +image: test.registry/foo-operator/foo-bundle:v0.3.1 +name: foo.v0.3.1 +package: foo +properties: +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoiYXBpZXh0ZW5zaW9ucy5rOHMuaW8vdjEiLCJraW5kIjoiQ3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImZvb3MudGVzdC5mb28ifSwic3BlYyI6eyJncm91cCI6InRlc3QuZm9vIiwibmFtZXMiOnsia2luZCI6IkZvbyIsInBsdXJhbCI6ImZvb3MifSwidmVyc2lvbnMiOlt7Im5hbWUiOiJ2MSIsInNlcnZlZCI6dHJ1ZSwic3RvcmFnZSI6ZmFsc2V9LHsibmFtZSI6InYyIiwic2VydmVkIjp0cnVlLCJzdG9yYWdlIjp0cnVlfV19fQ== +- type: olm.bundle.object + value: + data: eyJhcGlWZXJzaW9uIjoib3BlcmF0b3JzLmNvcmVvcy5jb20vdjFhbHBoYTEiLCJraW5kIjoiQ2x1c3RlclNlcnZpY2VWZXJzaW9uIiwibWV0YWRhdGEiOnsibmFtZSI6ImZvby52MC4zLjEifSwic3BlYyI6eyJjdXN0b21yZXNvdXJjZWRlZmluaXRpb25zIjp7Im93bmVkIjpbeyJncm91cCI6InRlc3QuZm9vIiwia2luZCI6IkZvbyIsIm5hbWUiOiJmb29zLnRlc3QuZm9vIiwidmVyc2lvbiI6InYxIn0seyJncm91cCI6InRlc3QuZm9vIiwia2luZCI6IkZvbyIsIm5hbWUiOiJmb29zLnRlc3QuZm9vIiwidmVyc2lvbiI6InYyIn1dfSwicmVsYXRlZEltYWdlcyI6W3siaW1hZ2UiOiJ0ZXN0LnJlZ2lzdHJ5L2Zvby1vcGVyYXRvci9mb286djAuMy4xIiwibmFtZSI6Im9wZXJhdG9yIn1dLCJyZXBsYWNlcyI6ImZvby52MC4yLjAiLCJza2lwcyI6WyJmb28udjAuMy4wIl0sInZlcnNpb24iOiIwLjMuMSJ9fQ== +- type: olm.gvk + value: + group: test.foo + kind: Foo + version: v1 +- type: olm.gvk + value: + group: test.foo + kind: Foo + version: v2 +- type: olm.gvk.required + value: + group: test.bar + kind: Bar + version: v1alpha1 +- type: olm.package + value: + packageName: foo + version: 0.3.1 +- type: olm.package.required + value: + packageName: bar + packageName: bar + versionRange: <0.2.0 +relatedImages: +- image: test.registry/foo-operator/foo:v0.3.1 + name: operator +schema: olm.bundle diff --git a/alpha/declcfg/diff.go b/alpha/declcfg/diff.go index 35b06aed3..fbc550dbc 100644 --- a/alpha/declcfg/diff.go +++ b/alpha/declcfg/diff.go @@ -459,15 +459,19 @@ func copyChannel(in *model.Channel, pkg *model.Package) *model.Channel { func copyBundle(in *model.Bundle, ch *model.Channel, pkg *model.Package) *model.Bundle { cp := &model.Bundle{ - Name: in.Name, - Channel: ch, - Package: pkg, - Image: in.Image, - Replaces: in.Replaces, - Version: semver.MustParse(in.Version.String()), - CsvJSON: in.CsvJSON, + Name: in.Name, + Channel: ch, + Package: pkg, + Image: in.Image, + Replaces: in.Replaces, + Version: semver.MustParse(in.Version.String()), + CsvJSON: in.CsvJSON, + SkipRange: in.SkipRange, + } + if in.PropertiesP != nil { + cp.PropertiesP = new(property.Properties) + *cp.PropertiesP = *in.PropertiesP } - cp.PropertiesP, _ = property.Parse(in.Properties) if len(in.Skips) != 0 { cp.Skips = make([]string, len(in.Skips)) copy(cp.Skips, in.Skips) diff --git a/alpha/declcfg/diff_include.go b/alpha/declcfg/diff_include.go index 457fe0e94..24246de19 100644 --- a/alpha/declcfg/diff_include.go +++ b/alpha/declcfg/diff_include.go @@ -2,6 +2,7 @@ package declcfg import ( "fmt" + "strings" "github.com/blang/semver" "github.com/sirupsen/logrus" @@ -32,12 +33,15 @@ type DiffIncludePackage struct { AllChannels DiffIncludeChannel } -// DiffIncludeChannel specifies a channel, and optionally bundle versions to include. +// DiffIncludeChannel specifies a channel, and optionally bundles and bundle versions to include. type DiffIncludeChannel struct { // Name of channel. Name string // Versions of bundles. Versions []semver.Version + // Bundles are bundle names to include. + // Set this field only if the named bundle has no semantic version metadata. + Bundles []string } // Run adds all packages and channels in DiffIncluder with matching names @@ -68,7 +72,7 @@ func (ipkg DiffIncludePackage) includeNewInOutputModel(newModel, outputModel mod pkgLog := logger.WithField("package", newPkg.Name) // No channels or versions were specified, meaning "include the full package". - if len(ipkg.Channels) == 0 && len(ipkg.AllChannels.Versions) == 0 { + if len(ipkg.Channels) == 0 && len(ipkg.AllChannels.Versions) == 0 && len(ipkg.AllChannels.Bundles) == 0 { outputModel[ipkg.Name] = newPkg return nil } @@ -76,17 +80,18 @@ func (ipkg DiffIncludePackage) includeNewInOutputModel(newModel, outputModel mod outputPkg := copyPackageNoChannels(newPkg) outputModel[outputPkg.Name] = outputPkg - // Add all channels to ipkg.Channels if versions were specified to include across all channels. - // skipMissingVerForChannels's value for a channel will be true IFF at least one version is specified, + // Add all channels to ipkg.Channels if bundles or versions were specified to include across all channels. + // skipMissingBundleForChannels's value for a channel will be true IFF at least one version is specified, // since some other channel may contain that version. - skipMissingVerForChannels := map[string]bool{} - if len(ipkg.AllChannels.Versions) != 0 { + skipMissingBundleForChannels := map[string]bool{} + if len(ipkg.AllChannels.Versions) != 0 || len(ipkg.AllChannels.Bundles) != 0 { for newChName := range newPkg.Channels { ipkg.Channels = append(ipkg.Channels, DiffIncludeChannel{ Name: newChName, Versions: ipkg.AllChannels.Versions, + Bundles: ipkg.AllChannels.Bundles, }) - skipMissingVerForChannels[newChName] = true + skipMissingBundleForChannels[newChName] = true } } @@ -98,7 +103,7 @@ func (ipkg DiffIncludePackage) includeNewInOutputModel(newModel, outputModel mod } chLog := pkgLog.WithField("channel", newCh.Name) - bundles, err := getBundlesForVersions(newCh, ich.Versions, chLog, skipMissingVerForChannels[newCh.Name]) + bundles, err := getBundlesForVersions(newCh, ich.Versions, ich.Bundles, chLog, skipMissingBundleForChannels[newCh.Name]) if err != nil { ierrs = append(ierrs, fmt.Errorf("[package=%q channel=%q] %v", newPkg.Name, newCh.Name, err)) continue @@ -116,9 +121,9 @@ func (ipkg DiffIncludePackage) includeNewInOutputModel(newModel, outputModel mod // getBundlesForVersions returns all bundles matching a version in vers // and their upgrade graph(s) to ch.Head(). -// If skipMissingVersions is true, versions not satisfied by bundles in ch +// If skipMissingBundles is true, bundle names and versions not satisfied by bundles in ch // will not result in errors. -func getBundlesForVersions(ch *model.Channel, vers []semver.Version, logger *logrus.Entry, skipMissingVersions bool) (bundles []*model.Bundle, err error) { +func getBundlesForVersions(ch *model.Channel, vers []semver.Version, names []string, logger *logrus.Entry, skipMissingBundles bool) (bundles []*model.Bundle, err error) { // Short circuit when no versions were specified, meaning "include the whole channel". if len(vers) == 0 { @@ -128,27 +133,44 @@ func getBundlesForVersions(ch *model.Channel, vers []semver.Version, logger *log return bundles, nil } - // Add every bundle directly satisfying a version to bundles. + // Add every bundle with a specified bundle name or directly satisfying a bundle version to bundles. versionsToInclude := make(map[string]struct{}, len(vers)) for _, ver := range vers { versionsToInclude[ver.String()] = struct{}{} } + namesToInclude := make(map[string]struct{}, len(vers)) + for _, name := range names { + namesToInclude[name] = struct{}{} + } for _, b := range ch.Bundles { - if _, includeBundle := versionsToInclude[b.Version.String()]; includeBundle { + _, includeVersionedBundle := versionsToInclude[b.Version.String()] + _, includeNamedBundle := namesToInclude[b.Name] + if includeVersionedBundle || includeNamedBundle { bundles = append(bundles, b) } } // Some version was not satisfied by this channel. - if len(bundles) != len(versionsToInclude) && !skipMissingVersions { + if len(bundles) != len(versionsToInclude)+len(namesToInclude) && !skipMissingBundles { for _, b := range bundles { delete(versionsToInclude, b.Version.String()) + delete(namesToInclude, b.Name) } - verStrs := []string{} + var verStrs, nameStrs []string for verStr := range versionsToInclude { verStrs = append(verStrs, verStr) } - return nil, fmt.Errorf("versions do not exist in channel: %+q", verStrs) + for nameStr := range namesToInclude { + nameStrs = append(nameStrs, nameStr) + } + sb := strings.Builder{} + if len(verStrs) != 0 { + sb.WriteString(fmt.Sprintf("versions=%+q ", verStrs)) + } + if len(nameStrs) != 0 { + sb.WriteString(fmt.Sprintf("names=%+q", nameStrs)) + } + return nil, fmt.Errorf("bundles do not exist in channel: %s", strings.TrimSpace(sb.String())) } // Fill in the upgrade graph between each bundle and head. diff --git a/cmd/opm/alpha/diff/cmd.go b/cmd/opm/alpha/diff/cmd.go index 4d8e0cc39..6d476842d 100644 --- a/cmd/opm/alpha/diff/cmd.go +++ b/cmd/opm/alpha/diff/cmd.go @@ -117,8 +117,8 @@ docker push registry.org/my-catalog:diff-latest cmd.Flags().StringVarP(&a.output, "output", "o", "yaml", "Output format (json|yaml)") cmd.Flags().StringVar(&a.caFile, "ca-file", "", "the root Certificates to use with this command") cmd.Flags().StringVarP(&a.includeFile, "include-file", "i", "", "YAML defining packages, "+ - "channels, and/or versions to include in the diff from the new refs. Upgrade graphs "+ - "from individual versions to their channel's head are added to the diff") + "channels, and/or bundles/versions to include in the diff from the new refs. Upgrade graphs "+ + "from individual bundles/versions to their channel's head are added to the diff") cmd.Flags().BoolVar(&a.debug, "debug", false, "enable debug logging") return cmd