44 "context"
55 "crypto/sha256"
66 "encoding/json"
7+ "errors"
78 "fmt"
89 "io/fs"
910 "path/filepath"
@@ -23,6 +24,7 @@ import (
2324 "sigs.k8s.io/yaml"
2425
2526 "github.com/operator-framework/api/pkg/operators/v1alpha1"
27+ "github.com/operator-framework/operator-registry/alpha/property"
2628 registrybundle "github.com/operator-framework/operator-registry/pkg/lib/bundle"
2729
2830 registry "github.com/operator-framework/operator-controller/internal/rukpak/operator-registry"
@@ -43,12 +45,12 @@ func RegistryV1ToHelmChart(ctx context.Context, rv1 fs.FS, installNamespace stri
4345 l := log .FromContext (ctx )
4446
4547 reg := RegistryV1 {}
46- fileData , err := fs .ReadFile (rv1 , filepath .Join ("metadata" , "annotations.yaml" ))
48+ annotationsFileData , err := fs .ReadFile (rv1 , filepath .Join ("metadata" , "annotations.yaml" ))
4749 if err != nil {
4850 return nil , err
4951 }
5052 annotationsFile := registry.AnnotationsFile {}
51- if err := yaml .Unmarshal (fileData , & annotationsFile ); err != nil {
53+ if err := yaml .Unmarshal (annotationsFileData , & annotationsFile ); err != nil {
5254 return nil , err
5355 }
5456 reg .PackageName = annotationsFile .Annotations .PackageName
@@ -101,9 +103,61 @@ func RegistryV1ToHelmChart(ctx context.Context, rv1 fs.FS, installNamespace stri
101103 return nil , err
102104 }
103105
106+ if err := copyMetadataPropertiesToCSV (& reg .CSV , rv1 ); err != nil {
107+ return nil , err
108+ }
109+
104110 return toChart (reg , installNamespace , watchNamespaces )
105111}
106112
113+ // copyMetadataPropertiesToCSV copies properties from `metadata/propeties.yaml` (in the filesystem fsys) into
114+ // the CSV's `.metadata.annotations['olm.properties']` value, preserving any properties that are already
115+ // present in the annotations.
116+ func copyMetadataPropertiesToCSV (csv * v1alpha1.ClusterServiceVersion , fsys fs.FS ) error {
117+ var allProperties []property.Property
118+
119+ // First load existing properties from the CSV. We want to preserve these.
120+ if csvPropertiesJSON , ok := csv .Annotations ["olm.properties" ]; ok {
121+ var csvProperties []property.Property
122+ if err := json .Unmarshal ([]byte (csvPropertiesJSON ), & csvProperties ); err != nil {
123+ return fmt .Errorf ("failed to unmarshal csv.metadata.annotations['olm.properties']: %w" , err )
124+ }
125+ allProperties = append (allProperties , csvProperties ... )
126+ }
127+
128+ // Next, load properties from the metadata/properties.yaml file, if it exists.
129+ metadataPropertiesJSON , err := fs .ReadFile (fsys , filepath .Join ("metadata" , "properties.yaml" ))
130+ if err != nil && ! errors .Is (err , fs .ErrNotExist ) {
131+ return fmt .Errorf ("failed to read properties.yaml file: %w" , err )
132+ }
133+
134+ // If there are no properties, we can stick with whatever
135+ // was already present in the CSV annotations.
136+ if len (metadataPropertiesJSON ) == 0 {
137+ return nil
138+ }
139+
140+ // Otherwise, we need to parse the properties.yaml file and
141+ // append its properties into the CSV annotation.
142+ type registryV1Properties struct {
143+ Properties []property.Property `json:"properties"`
144+ }
145+
146+ var metadataProperties registryV1Properties
147+ if err := yaml .Unmarshal (metadataPropertiesJSON , & metadataProperties ); err != nil {
148+ return fmt .Errorf ("failed to unmarshal metadata/properties.yaml: %w" , err )
149+ }
150+ allProperties = append (allProperties , metadataProperties .Properties ... )
151+
152+ // Lastly re-marshal all the properties back into a JSON array and update the CSV annotation
153+ allPropertiesJSON , err := json .Marshal (allProperties )
154+ if err != nil {
155+ return fmt .Errorf ("failed to marshal registry+v1 properties to json: %w" , err )
156+ }
157+ csv .Annotations ["olm.properties" ] = string (allPropertiesJSON )
158+ return nil
159+ }
160+
107161func toChart (in RegistryV1 , installNamespace string , watchNamespaces []string ) (* chart.Chart , error ) {
108162 plain , err := Convert (in , installNamespace , watchNamespaces )
109163 if err != nil {
0 commit comments