Skip to content

Commit e8fc71b

Browse files
committed
wip: olm.package.v2, olm.bundle.v2, olm.package.icon
Signed-off-by: Joe Lanford <[email protected]>
1 parent c8307ca commit e8fc71b

File tree

6 files changed

+412
-83
lines changed

6 files changed

+412
-83
lines changed

alpha/action/migrations/001_v2.go

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package migrations
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"github.com/operator-framework/operator-registry/alpha/declcfg"
8+
"github.com/operator-framework/operator-registry/alpha/model"
9+
"github.com/operator-framework/operator-registry/alpha/property"
10+
)
11+
12+
func v2(cfg *declcfg.DeclarativeConfig) error {
13+
uniqueBundles := map[string]*model.Bundle{}
14+
m, err := declcfg.ConvertToModel(*cfg)
15+
if err != nil {
16+
return err
17+
}
18+
cfg.Packages = nil
19+
cfg.Bundles = nil
20+
21+
for _, pkg := range m {
22+
head, err := pkg.DefaultChannel.Head()
23+
if err != nil {
24+
return err
25+
}
26+
27+
if head.PropertiesP == nil || len(head.PropertiesP.CSVMetadatas) == 0 {
28+
return fmt.Errorf("no CSV metadata defined for package %s", pkg.Name)
29+
}
30+
csvMetadata := head.PropertiesP.CSVMetadatas[0]
31+
32+
packageAnnotations := map[string]string{
33+
"operators.openshift.io/capabilities": csvMetadata.Annotations["capabilities"],
34+
"operators.openshift.io/categories": csvMetadata.Annotations["categories"],
35+
"operators.openshift.io/infrastructure-features": csvMetadata.Annotations["operators.openshift.io/infrastructure-features"],
36+
"operators.openshift.io/valid-subscription": csvMetadata.Annotations["operators.openshift.io/valid-subscription"],
37+
"olm.operatorframework.io/olmv0-compatibility-default-channel": pkg.DefaultChannel.Name,
38+
}
39+
40+
v2p := declcfg.PackageV2{
41+
Schema: "olm.package.v2",
42+
Package: pkg.Name,
43+
DisplayName: csvMetadata.DisplayName,
44+
ShortDescription: csvMetadata.Annotations["description"],
45+
LongDescription: csvMetadata.Description,
46+
Keywords: csvMetadata.Keywords,
47+
Links: csvMetadata.Links,
48+
Provider: csvMetadata.Provider,
49+
Maintainers: csvMetadata.Maintainers,
50+
Annotations: packageAnnotations,
51+
}
52+
cfg.PackageV2s = append(cfg.PackageV2s, v2p)
53+
54+
if pkg.Icon != nil {
55+
v2i := declcfg.PackageIcon{
56+
Schema: "olm.package.icon",
57+
Package: pkg.Name,
58+
Data: pkg.Icon.Data,
59+
MediaType: pkg.Icon.MediaType,
60+
}
61+
cfg.PackageIcons = append(cfg.PackageIcons, v2i)
62+
}
63+
64+
for _, ch := range pkg.Channels {
65+
for _, b := range ch.Bundles {
66+
uniqueBundles[b.Name] = b
67+
}
68+
}
69+
}
70+
71+
bundleRenames := make(map[string]string, len(uniqueBundles))
72+
for _, b := range uniqueBundles {
73+
newName := fmt.Sprintf("%s.v%s", b.Package.Name, b.Version)
74+
v2b := declcfg.BundleV2{
75+
Schema: "olm.bundle.v2",
76+
Package: b.Package.Name,
77+
Name: newName,
78+
79+
Version: b.Version.String(),
80+
Release: 0,
81+
Reference: fmt.Sprintf("docker://%s", b.Image),
82+
RelatedReferences: make([]string, 0, len(b.RelatedImages)),
83+
84+
Constraints: map[string][]json.RawMessage{},
85+
Properties: map[string][]json.RawMessage{},
86+
}
87+
bundleRenames[b.Name] = newName
88+
89+
for _, ri := range b.RelatedImages {
90+
v2b.RelatedReferences = append(v2b.RelatedReferences, fmt.Sprintf("docker://%s", ri.Image))
91+
}
92+
93+
for _, p := range b.Properties {
94+
if p.Type == property.TypePackage || p.Type == property.TypeBundleObject {
95+
continue
96+
}
97+
if isContraint(p) {
98+
v2b.Constraints[p.Type] = append(v2b.Constraints[p.Type], p.Value)
99+
} else {
100+
v2b.Properties[p.Type] = append(v2b.Properties[p.Type], p.Value)
101+
}
102+
}
103+
104+
if b.PropertiesP != nil && len(b.PropertiesP.CSVMetadatas) > 0 {
105+
csvMetadata := b.PropertiesP.CSVMetadatas[0]
106+
107+
desiredAnnotations := map[string]string{
108+
"createdAt": "operators.openshift.io/creationTimestamp",
109+
"repository": "operators.openshift.io/repository",
110+
"support": "operators.openshift.io/support",
111+
"containerImage": "operators.openshift.io/image",
112+
}
113+
114+
bundleAnnotations := map[string]string{}
115+
for fromKey, toKey := range desiredAnnotations {
116+
if value, ok := csvMetadata.Annotations[fromKey]; ok {
117+
bundleAnnotations[toKey] = value
118+
}
119+
}
120+
v2b.Annotations = bundleAnnotations
121+
}
122+
cfg.BundleV2s = append(cfg.BundleV2s, v2b)
123+
}
124+
125+
for i, ch := range cfg.Channels {
126+
for j, entry := range ch.Entries {
127+
if newName, ok := bundleRenames[entry.Name]; ok {
128+
cfg.Channels[i].Entries[j].Name = newName
129+
}
130+
if newName, ok := bundleRenames[entry.Replaces]; ok {
131+
cfg.Channels[i].Entries[j].Replaces = newName
132+
}
133+
for k, skip := range entry.Skips {
134+
if newName, ok := bundleRenames[skip]; ok {
135+
cfg.Channels[i].Entries[j].Skips[k] = newName
136+
}
137+
}
138+
}
139+
}
140+
141+
for depIdx := range cfg.Deprecations {
142+
for entryIdx := range cfg.Deprecations[depIdx].Entries {
143+
e := &cfg.Deprecations[depIdx].Entries[entryIdx]
144+
switch e.Reference.Schema {
145+
case declcfg.SchemaPackage:
146+
e.Reference.Schema = declcfg.SchemaPackageV2
147+
case declcfg.SchemaBundle:
148+
e.Reference.Schema = declcfg.SchemaBundleV2
149+
}
150+
}
151+
}
152+
return nil
153+
}
154+
155+
func isContraint(p property.Property) bool {
156+
switch p.Type {
157+
case property.TypeConstraint, property.TypeGVKRequired, property.TypePackageRequired:
158+
return true
159+
}
160+
return false
161+
}

alpha/action/migrations/migrations.go

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Migrations struct {
5454
var allMigrations = []Migration{
5555
newMigration(NoMigrations, "do nothing", func(_ *declcfg.DeclarativeConfig) error { return nil }),
5656
newMigration("bundle-object-to-csv-metadata", `migrates bundles' "olm.bundle.object" to "olm.csv.metadata"`, bundleObjectToCSVMetadata),
57+
newMigration("v2", `migrate catalog to olm.package.v2, olm.bundle.v2, and olm.package.icon`, v2),
5758
}
5859

5960
func NewMigrations(name string) (*Migrations, error) {

alpha/declcfg/declcfg.go

+53-4
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,35 @@ import (
66
"errors"
77
"fmt"
88

9-
prettyunmarshaler "github.com/operator-framework/operator-registry/pkg/prettyunmarshaler"
10-
119
"golang.org/x/text/cases"
1210
utilerrors "k8s.io/apimachinery/pkg/util/errors"
1311
"k8s.io/apimachinery/pkg/util/sets"
1412

13+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
14+
1515
"github.com/operator-framework/operator-registry/alpha/property"
16+
prettyunmarshaler "github.com/operator-framework/operator-registry/pkg/prettyunmarshaler"
1617
)
1718

1819
const (
1920
SchemaPackage = "olm.package"
2021
SchemaChannel = "olm.channel"
2122
SchemaBundle = "olm.bundle"
2223
SchemaDeprecation = "olm.deprecations"
24+
SchemaPackageV2 = "olm.package.v2"
25+
SchemaBundleV2 = "olm.bundle.v2"
26+
SchemaPackageIcon = "olm.package.icon"
2327
)
2428

2529
type DeclarativeConfig struct {
2630
Packages []Package
27-
Channels []Channel
28-
Bundles []Bundle
31+
PackageV2s []PackageV2
32+
PackageIcons []PackageIcon
33+
34+
Channels []Channel
35+
Bundles []Bundle
36+
BundleV2s []BundleV2
37+
2938
Deprecations []Deprecation
3039
Others []Meta
3140
}
@@ -92,6 +101,43 @@ type RelatedImage struct {
92101
Image string `json:"image"`
93102
}
94103

104+
type PackageV2 struct {
105+
Schema string `json:"schema"`
106+
Package string `json:"package"`
107+
Annotations map[string]string `json:"annotations,omitempty"`
108+
109+
DisplayName string `json:"displayName,omitempty"`
110+
ShortDescription string `json:"shortDescription,omitempty"`
111+
LongDescription string `json:"longDescription,omitempty"`
112+
Keywords []string `json:"keywords,omitempty"`
113+
Links []v1alpha1.AppLink `json:"links,omitempty"`
114+
Provider v1alpha1.AppLink `json:"provider,omitempty"`
115+
Maintainers []v1alpha1.Maintainer `json:"maintainers,omitempty"`
116+
}
117+
118+
type PackageIcon struct {
119+
Schema string `json:"schema"`
120+
Package string `json:"package"`
121+
Data []byte `json:"data"`
122+
MediaType string `json:"mediaType"`
123+
}
124+
125+
type BundleV2 struct {
126+
Schema string `json:"schema"`
127+
Package string `json:"package"`
128+
Name string `json:"name"`
129+
Annotations map[string]string `json:"annotations,omitempty"`
130+
131+
Version string `json:"version"`
132+
Release uint32 `json:"release"`
133+
134+
Reference string `json:"ref"`
135+
RelatedReferences []string `json:"relatedReferences,omitempty"`
136+
137+
Properties map[string][]json.RawMessage `json:"properties,omitempty"`
138+
Constraints map[string][]json.RawMessage `json:"constraints,omitempty"`
139+
}
140+
95141
type Deprecation struct {
96142
Schema string `json:"schema"`
97143
Package string `json:"package"`
@@ -202,8 +248,11 @@ func extractUniqueMetaKeys(blobMap map[string]any, m *Meta) error {
202248

203249
func (destination *DeclarativeConfig) Merge(src *DeclarativeConfig) {
204250
destination.Packages = append(destination.Packages, src.Packages...)
251+
destination.PackageV2s = append(destination.PackageV2s, src.PackageV2s...)
252+
destination.PackageIcons = append(destination.PackageIcons, src.PackageIcons...)
205253
destination.Channels = append(destination.Channels, src.Channels...)
206254
destination.Bundles = append(destination.Bundles, src.Bundles...)
255+
destination.BundleV2s = append(destination.BundleV2s, src.BundleV2s...)
207256
destination.Others = append(destination.Others, src.Others...)
208257
destination.Deprecations = append(destination.Deprecations, src.Deprecations...)
209258
}

0 commit comments

Comments
 (0)