@@ -2,25 +2,58 @@ package basic
22
33import (
44 "context"
5+ "encoding/json"
56 "fmt"
67 "io"
78
89 "github.com/operator-framework/operator-registry/alpha/action"
910 "github.com/operator-framework/operator-registry/alpha/declcfg"
1011 "github.com/operator-framework/operator-registry/pkg/image"
12+ "k8s.io/apimachinery/pkg/util/yaml"
1113)
1214
15+ const schema string = "olm.template.basic"
16+
1317type Template struct {
1418 Registry image.Registry
1519}
1620
21+ type BasicTemplate struct {
22+ Schema string `json:"schema"`
23+ Entries []* declcfg.Meta `json:"entries"`
24+ }
25+
26+ func parseSpec (reader io.Reader ) (* BasicTemplate , error ) {
27+ bt := & BasicTemplate {}
28+ btDoc := json.RawMessage {}
29+ btDecoder := yaml .NewYAMLOrJSONDecoder (reader , 4096 )
30+ err := btDecoder .Decode (& btDoc )
31+ if err != nil {
32+ return nil , fmt .Errorf ("decoding template schema: %v" , err )
33+ }
34+ err = json .Unmarshal (btDoc , bt )
35+ if err != nil {
36+ return nil , fmt .Errorf ("unmarshalling template: %v" , err )
37+ }
38+
39+ if bt .Schema != schema {
40+ return nil , fmt .Errorf ("template has unknown schema (%q), should be %q" , bt .Schema , schema )
41+ }
42+
43+ return bt , nil
44+ }
45+
1746func (t Template ) Render (ctx context.Context , reader io.Reader ) (* declcfg.DeclarativeConfig , error ) {
18- cfg , err := declcfg .LoadReader (reader )
47+ bt , err := parseSpec (reader )
48+ if err != nil {
49+ return nil , err
50+ }
51+ cfg , err := declcfg .LoadSlice (bt .Entries )
1952 if err != nil {
2053 return cfg , err
2154 }
2255
23- outb := cfg .Bundles [:0 ] // allocate based on max size of input, but empty slice
56+ outb := cfg .Bundles [:0 ]
2457 // populate registry, incl any flags from CLI, and enforce only rendering bundle images
2558 r := action.Render {
2659 Registry : t .Registry ,
@@ -48,3 +81,38 @@ func (t Template) Render(ctx context.Context, reader io.Reader) (*declcfg.Declar
4881func isBundleTemplate (b * declcfg.Bundle ) bool {
4982 return b .Schema != "" && b .Image != "" && b .Package == "" && len (b .Properties ) == 0 && len (b .RelatedImages ) == 0
5083}
84+
85+ // FromReader reads FBC from a reader and generates a BasicTemplate from it
86+ func FromReader (r io.Reader ) (* BasicTemplate , error ) {
87+ var entries []* declcfg.Meta
88+ if err := declcfg .WalkMetasReader (r , func (meta * declcfg.Meta , err error ) error {
89+ if err != nil {
90+ return err
91+ }
92+ if meta .Schema == declcfg .SchemaBundle {
93+ var b declcfg.Bundle
94+ if err := json .Unmarshal (meta .Blob , & b ); err != nil {
95+ return fmt .Errorf ("parse bundle: %v" , err )
96+ }
97+ b2 := declcfg.Bundle {
98+ Schema : b .Schema ,
99+ Image : b .Image ,
100+ }
101+ meta .Blob , err = json .Marshal (b2 )
102+ if err != nil {
103+ return fmt .Errorf ("re-serialize bundle: %v" , err )
104+ }
105+ }
106+ entries = append (entries , meta )
107+ return nil
108+ }); err != nil {
109+ return nil , err
110+ }
111+
112+ bt := & BasicTemplate {
113+ Schema : schema ,
114+ Entries : entries ,
115+ }
116+
117+ return bt , nil
118+ }
0 commit comments