Skip to content

Commit 4f366a6

Browse files
committed
grpc changes
Signed-off-by: Jordan Keister <[email protected]>
1 parent f2285a2 commit 4f366a6

File tree

14 files changed

+544
-281
lines changed

14 files changed

+544
-281
lines changed

alpha/declcfg/declcfg.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const (
1919
SchemaPackage = "olm.package"
2020
SchemaChannel = "olm.channel"
2121
SchemaBundle = "olm.bundle"
22-
SchemaDeprecation = "olm.catalog.deprecation"
22+
SchemaDeprecation = "olm.deprecations"
2323
)
2424

2525
type DeclarativeConfig struct {
@@ -93,16 +93,19 @@ type RelatedImage struct {
9393
}
9494

9595
type Deprecation struct {
96-
Schema string `json:"schema"`
97-
Package string `json:"package"`
98-
Name string `json:"name,omitempty"`
99-
Deprecations []DeprecationEntry `json:"deprecations"`
96+
Schema string `json:"schema"`
97+
Package string `json:"package"`
98+
Entries []DeprecationEntry `json:"entries"`
10099
}
101100

102101
type DeprecationEntry struct {
103-
Schema string `json:"schema"`
104-
Name string `json:"name,omitempty"`
105-
Message json.RawMessage `json:"message"`
102+
Reference PackageScopedReference `json:"reference"`
103+
Message string `json:"message"`
104+
}
105+
106+
type PackageScopedReference struct {
107+
Schema string `json:"schema"`
108+
Name string `json:"name,omitempty"`
106109
}
107110

108111
type Meta struct {

alpha/declcfg/declcfg_to_model.go

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
3737
mpkgs[p.Name] = mpkg
3838
}
3939

40-
channelDefinedEntries := map[string]sets.String{}
40+
channelDefinedEntries := map[string]sets.Set[string]{}
4141
for _, c := range cfg.Channels {
4242
mpkg, ok := mpkgs[c.Package]
4343
if !ok {
@@ -62,7 +62,7 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
6262
Properties: c.Properties,
6363
}
6464

65-
cde := sets.NewString()
65+
cde := sets.Set[string]{}
6666
for _, entry := range c.Entries {
6767
if _, ok := mch.Bundles[entry.Name]; ok {
6868
return nil, fmt.Errorf("invalid package %q, channel %q: duplicate entry %q", c.Package, c.Name, entry.Name)
@@ -89,7 +89,7 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
8989

9090
// packageBundles tracks the set of bundle names for each package
9191
// and is used to detect duplicate bundles.
92-
packageBundles := map[string]sets.String{}
92+
packageBundles := map[string]sets.Set[string]{}
9393

9494
for _, b := range cfg.Bundles {
9595
if b.Package == "" {
@@ -102,7 +102,7 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
102102

103103
bundles, ok := packageBundles[b.Package]
104104
if !ok {
105-
bundles = sets.NewString()
105+
bundles = sets.Set[string]{}
106106
}
107107
if bundles.Has(b.Name) {
108108
return nil, fmt.Errorf("package %q has duplicate bundle %q", b.Package, b.Name)
@@ -151,7 +151,7 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
151151

152152
for pkg, entries := range channelDefinedEntries {
153153
if entries.Len() > 0 {
154-
return nil, fmt.Errorf("no olm.bundle blobs found in package %q for olm.channel entries %s", pkg, entries.List())
154+
return nil, fmt.Errorf("no olm.bundle blobs found in package %q for olm.channel entries %s", pkg, sets.List[string](entries))
155155
}
156156
}
157157

@@ -168,6 +168,70 @@ func ConvertToModel(cfg DeclarativeConfig) (model.Model, error) {
168168
}
169169
}
170170

171+
// deprecationsByPackage tracks the set of package names
172+
// and is used to detect duplicate packages.
173+
deprecationsByPackage := sets.New[string]()
174+
175+
for i, deprecation := range cfg.Deprecations {
176+
177+
// no need to validate schema, since it could not be unmarshaled if missing/invalid
178+
179+
if deprecation.Package == "" {
180+
return nil, fmt.Errorf("package name must be set for deprecation item %v", i)
181+
}
182+
183+
// must refer to package in this catalog
184+
mpkg, ok := mpkgs[deprecation.Package]
185+
if !ok {
186+
return nil, fmt.Errorf("cannot apply deprecations to an unknown package %q", deprecation.Package)
187+
}
188+
189+
// must be unique per package
190+
if deprecationsByPackage.Has(deprecation.Package) {
191+
return nil, fmt.Errorf("expected a maximum of one deprecation per package: %q", deprecation.Package)
192+
}
193+
deprecationsByPackage.Insert(deprecation.Package)
194+
195+
references := sets.New[PackageScopedReference]()
196+
197+
for j, entry := range deprecation.Entries {
198+
if entry.Reference.Schema == "" {
199+
return nil, fmt.Errorf("schema must be set for deprecation entry [%v] for package %q", deprecation.Package, j)
200+
}
201+
202+
if references.Has(entry.Reference) {
203+
return nil, fmt.Errorf("duplicate deprecation entry %#v for package %q", entry.Reference, deprecation.Package)
204+
}
205+
206+
switch entry.Reference.Schema {
207+
case SchemaBundle:
208+
if !packageBundles[deprecation.Package].Has(entry.Reference.Name) {
209+
return nil, fmt.Errorf("cannot deprecate bundle %q for package %q: bundle not found", entry.Reference.Name, deprecation.Package)
210+
}
211+
for _, mch := range mpkg.Channels {
212+
if mb, ok := mch.Bundles[entry.Reference.Name]; ok {
213+
mb.Deprecation = &model.Deprecation{Message: entry.Message}
214+
}
215+
}
216+
case SchemaChannel:
217+
ch, ok := mpkg.Channels[entry.Reference.Name]
218+
if !ok {
219+
return nil, fmt.Errorf("cannot deprecate channel %q for package %q: channel not found", entry.Reference.Name, deprecation.Package)
220+
}
221+
ch.Deprecation = &model.Deprecation{Message: entry.Message}
222+
223+
case SchemaPackage:
224+
if entry.Reference.Name != "" {
225+
return nil, fmt.Errorf("package name must be empty for deprecated package %q (specified %q)", deprecation.Package, entry.Reference.Name)
226+
}
227+
mpkg.Deprecation = &model.Deprecation{Message: entry.Message}
228+
229+
default:
230+
return nil, fmt.Errorf("cannot deprecate object %#v referenced by entry %v for package %q: object schema unknown", entry.Reference, j, deprecation.Package)
231+
}
232+
}
233+
}
234+
171235
if err := mpkgs.Validate(); err != nil {
172236
return nil, err
173237
}

alpha/declcfg/load_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,12 @@ func TestLoadFS(t *testing.T) {
338338
},
339339
Deprecations: []Deprecation{
340340
{
341-
Schema: "olm.catalog.deprecation",
341+
Schema: SchemaDeprecation,
342342
Package: "kiali",
343-
Name: "bobs-discount-name",
344-
Deprecations: []DeprecationEntry{
345-
{Schema: "olm.bundle", Name: "kiali-operator.v1.68.0", Message: json.RawMessage(`"kiali-operator.v1.68.0 is deprecated. Uninstall and install kiali-operator.v1.72.0 for support.\n"`)},
346-
{Schema: "olm.package", Name: "kiali", Message: json.RawMessage(`"package kiali is end of life. Please use 'kiali-new' package for support.\n"`)},
347-
{Schema: "olm.channel", Name: "alpha", Message: json.RawMessage(`"channel alpha is no longer supported. Please switch to channel 'stable'.\n"`)},
343+
Entries: []DeprecationEntry{
344+
{Reference: PackageScopedReference{Schema: SchemaBundle, Name: "kiali-operator.v1.68.0"}, Message: "kiali-operator.v1.68.0 is deprecated. Uninstall and install kiali-operator.v1.72.0 for support.\n"},
345+
{Reference: PackageScopedReference{Schema: SchemaPackage}, Message: "package kiali is end of life. Please use 'kiali-new' package for support.\n"},
346+
{Reference: PackageScopedReference{Schema: SchemaChannel, Name: "alpha"}, Message: "channel alpha is no longer supported. Please switch to channel 'stable'.\n"},
348347
},
349348
},
350349
},
@@ -899,22 +898,23 @@ present in the .indexignore file.`),
899898
}
900899
deprecations = &fstest.MapFile{
901900
Data: []byte(`---
902-
schema: olm.catalog.deprecation
901+
schema: olm.deprecations
903902
package: kiali
904-
name: bobs-discount-name
905-
deprecations:
906-
- schema: olm.bundle
907-
name: kiali-operator.v1.68.0
903+
entries:
904+
- reference:
905+
schema: olm.bundle
906+
name: kiali-operator.v1.68.0
908907
message: |
909908
kiali-operator.v1.68.0 is deprecated. Uninstall and install kiali-operator.v1.72.0 for support.
910-
- schema: olm.package
911-
name: kiali
909+
- reference:
910+
schema: olm.package
912911
message: |
913912
package kiali is end of life. Please use 'kiali-new' package for support.
914-
- schema: olm.channel
915-
name: alpha
913+
- reference:
914+
schema: olm.channel
915+
name: alpha
916916
message: |
917-
channel alpha is no longer supported. Please switch to channel 'stable'.`),
917+
channel alpha is no longer supported. Please switch to channel 'stable'.`),
918918
}
919919

920920
validFS = fstest.MapFS{

alpha/declcfg/write.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,17 @@ func writeToEncoder(cfg DeclarativeConfig, enc encoder) error {
425425
}
426426
}
427427

428+
//
429+
// Normally we would order the deprecations, but it really doesn't make sense since
430+
// - there will be 0 or 1 of them for any given package
431+
// - they have no other useful field for ordering
432+
//
433+
// validation is typically via conversion to a model.Model and invoking model.Package.Validate()
434+
// It's possible that a user of the object could create a slice containing more then 1
435+
// Deprecation object for a package, and it would bypass validation if this
436+
// function gets called without conversion.
437+
//
428438
deprecations := deprecationsByPackage[pName]
429-
sort.SliceStable(deprecations, func(i, j int) bool {
430-
return deprecations[i].Name < deprecations[j].Name
431-
})
432439
for _, d := range deprecations {
433440
if err := enc.Encode(d); err != nil {
434441
return err

alpha/model/model.go

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import (
1616
"github.com/operator-framework/operator-registry/alpha/property"
1717
)
1818

19+
type Deprecation struct {
20+
Message string `json:"message"`
21+
}
22+
1923
func init() {
2024
t := types.NewType("svg", "image/svg+xml")
2125
filetype.AddMatcher(t, svg.Is)
@@ -44,6 +48,7 @@ type Package struct {
4448
Icon *Icon
4549
DefaultChannel *Channel
4650
Channels map[string]*Channel
51+
Deprecation *Deprecation
4752
}
4853

4954
func (m *Package) Validate() error {
@@ -84,12 +89,17 @@ func (m *Package) Validate() error {
8489
if m.DefaultChannel != nil && !foundDefault {
8590
result.subErrors = append(result.subErrors, fmt.Errorf("default channel %q not found in channels list", m.DefaultChannel.Name))
8691
}
92+
93+
if err := m.Deprecation.Validate(); err != nil {
94+
result.subErrors = append(result.subErrors, fmt.Errorf("invalid deprecation: %v", err))
95+
}
96+
8797
return result.orNil()
8898
}
8999

90100
type Icon struct {
91-
Data []byte
92-
MediaType string
101+
Data []byte `json:"base64data"`
102+
MediaType string `json:"mediatype"`
93103
}
94104

95105
func (i *Icon) Validate() error {
@@ -131,9 +141,10 @@ func (i *Icon) validateData() error {
131141
}
132142

133143
type Channel struct {
134-
Package *Package
135-
Name string
136-
Bundles map[string]*Bundle
144+
Package *Package
145+
Name string
146+
Bundles map[string]*Bundle
147+
Deprecation *Deprecation
137148
// NOTICE: The field Properties of the type Channel is for internal use only.
138149
// DO NOT use it for any public-facing functionalities.
139150
// This API is in alpha stage and it is subject to change.
@@ -206,6 +217,11 @@ func (c *Channel) Validate() error {
206217
result.subErrors = append(result.subErrors, fmt.Errorf("bundle %q not correctly linked to parent channel", b.Name))
207218
}
208219
}
220+
221+
if err := c.Deprecation.Validate(); err != nil {
222+
result.subErrors = append(result.subErrors, fmt.Errorf("invalid deprecation: %v", err))
223+
}
224+
209225
return result.orNil()
210226
}
211227

@@ -264,6 +280,7 @@ type Bundle struct {
264280
SkipRange string
265281
Properties []property.Property
266282
RelatedImages []RelatedImage
283+
Deprecation *Deprecation
267284

268285
// These fields are present so that we can continue serving
269286
// the GRPC API the way packageserver expects us to in a
@@ -318,6 +335,10 @@ func (b *Bundle) Validate() error {
318335
result.subErrors = append(result.subErrors, errors.New("bundle image must be set"))
319336
}
320337

338+
if err := b.Deprecation.Validate(); err != nil {
339+
result.subErrors = append(result.subErrors, fmt.Errorf("invalid deprecation: %v", err))
340+
}
341+
321342
return result.orNil()
322343
}
323344

@@ -374,3 +395,13 @@ func (m Model) AddBundle(b Bundle) {
374395
p.DefaultChannel = b.Channel
375396
}
376397
}
398+
399+
func (d *Deprecation) Validate() error {
400+
if d == nil {
401+
return nil
402+
}
403+
if d.Message == "" {
404+
return errors.New("message must be set")
405+
}
406+
return nil
407+
}

pkg/api/grpc_health_v1/health.pb.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/grpc_health_v1/health_grpc.pb.go

Lines changed: 8 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/model_to_api.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ func ConvertModelBundleToAPIBundle(b model.Bundle) (*Bundle, error) {
5252
}
5353
}
5454

55+
var deprecation *Deprecation
56+
if b.Deprecation != nil {
57+
deprecation = &Deprecation{
58+
Message: b.Deprecation.Message,
59+
}
60+
}
61+
5562
apiDeps, err := convertModelPropertiesToAPIDependencies(b.Properties)
5663
if err != nil {
5764
return nil, fmt.Errorf("convert model properties to api dependencies: %v", err)
@@ -71,6 +78,7 @@ func ConvertModelBundleToAPIBundle(b model.Bundle) (*Bundle, error) {
7178
Skips: b.Skips,
7279
CsvJson: csvJson,
7380
Object: b.Objects,
81+
Deprecation: deprecation,
7482
}, nil
7583
}
7684

0 commit comments

Comments
 (0)