@@ -34,10 +34,12 @@ type RefType uint
34
34
35
35
const (
36
36
RefBundleImage RefType = 1 << iota
37
+ RefBundleDir
37
38
RefSqliteImage
38
39
RefSqliteFile
39
40
RefDCImage
40
41
RefDCDir
42
+ RefPackageManifestDir
41
43
42
44
RefAll = 0
43
45
)
@@ -117,25 +119,54 @@ func (r Render) createRegistry() (*containerdregistry.Registry, error) {
117
119
}
118
120
119
121
func (r Render ) renderReference (ctx context.Context , ref string ) (* declcfg.DeclarativeConfig , error ) {
120
- if stat , serr := os .Stat (ref ); serr == nil {
121
- if stat .IsDir () {
122
- if ! r .AllowedRefMask .Allowed (RefDCDir ) {
123
- return nil , fmt .Errorf ("cannot render declarative config directory: %w" , ErrNotAllowed )
122
+ stat , err := os .Stat (ref )
123
+ if err != nil {
124
+ return r .imageToDeclcfg (ctx , ref )
125
+ }
126
+ if stat .IsDir () {
127
+ dirEntries , err := os .ReadDir (ref )
128
+ if err != nil {
129
+ return nil , err
130
+ }
131
+ if isBundle (dirEntries ) {
132
+ // Looks like a bundle directory
133
+ if ! r .AllowedRefMask .Allowed (RefBundleDir ) {
134
+ return nil , fmt .Errorf ("cannot render bundle directory: %w" , ErrNotAllowed )
124
135
}
125
- return declcfg .LoadFS (os .DirFS (ref ))
126
- } else {
127
- // The only supported file type is an sqlite DB file,
128
- // since declarative configs will be in a directory.
129
- if err := checkDBFile (ref ); err != nil {
136
+ img , err := registry .NewImageInput (image .SimpleReference ("" ), ref )
137
+ if err != nil {
130
138
return nil , err
131
139
}
132
- if ! r .AllowedRefMask .Allowed (RefSqliteFile ) {
133
- return nil , fmt .Errorf ("cannot render sqlite file: %w" , ErrNotAllowed )
140
+ return bundleToDeclcfg (img .Bundle )
141
+ } else if isPackageManifest (dirEntries ) {
142
+ // Looks like a package manifest directory
143
+ if ! r .AllowedRefMask .Allowed (RefPackageManifestDir ) {
144
+ return nil , fmt .Errorf ("cannot render package manifest directory: %w" , ErrNotAllowed )
134
145
}
135
- return sqliteToDeclcfg (ctx , ref )
146
+ return renderPackageManifest (ctx , ref )
136
147
}
148
+
149
+ // Otherwise, assume it is a declarative config root directory.
150
+ if ! r .AllowedRefMask .Allowed (RefDCDir ) {
151
+ return nil , fmt .Errorf ("cannot render declarative config directory: %w" , ErrNotAllowed )
152
+ }
153
+ return declcfg .LoadFS (os .DirFS (ref ))
154
+ }
155
+ // The only supported file type is an sqlite DB file,
156
+ // since declarative configs will be in a directory.
157
+ if err := checkDBFile (ref ); err != nil {
158
+ return nil , err
159
+ }
160
+ if ! r .AllowedRefMask .Allowed (RefSqliteFile ) {
161
+ return nil , fmt .Errorf ("cannot render sqlite file: %w" , ErrNotAllowed )
137
162
}
138
- return r .imageToDeclcfg (ctx , ref )
163
+
164
+ db , err := sqlite .Open (ref )
165
+ if err != nil {
166
+ return nil , err
167
+ }
168
+ defer db .Close ()
169
+ return sqliteToDeclcfg (ctx , db )
139
170
}
140
171
141
172
func (r Render ) imageToDeclcfg (ctx context.Context , imageRef string ) (* declcfg.DeclarativeConfig , error ) {
@@ -161,7 +192,12 @@ func (r Render) imageToDeclcfg(ctx context.Context, imageRef string) (*declcfg.D
161
192
if ! r .AllowedRefMask .Allowed (RefSqliteImage ) {
162
193
return nil , fmt .Errorf ("cannot render sqlite image: %w" , ErrNotAllowed )
163
194
}
164
- cfg , err = sqliteToDeclcfg (ctx , filepath .Join (tmpDir , dbFile ))
195
+ db , err := sqlite .Open (filepath .Join (tmpDir , dbFile ))
196
+ if err != nil {
197
+ return nil , err
198
+ }
199
+ defer db .Close ()
200
+ cfg , err = sqliteToDeclcfg (ctx , db )
165
201
if err != nil {
166
202
return nil , err
167
203
}
@@ -213,17 +249,11 @@ func checkDBFile(ref string) error {
213
249
return nil
214
250
}
215
251
216
- func sqliteToDeclcfg (ctx context.Context , dbFile string ) (* declcfg.DeclarativeConfig , error ) {
252
+ func sqliteToDeclcfg (ctx context.Context , db * sql. DB ) (* declcfg.DeclarativeConfig , error ) {
217
253
logDeprecationMessage .Do (func () {
218
254
sqlite .LogSqliteDeprecation ()
219
255
})
220
256
221
- db , err := sqlite .Open (dbFile )
222
- if err != nil {
223
- return nil , err
224
- }
225
- defer db .Close ()
226
-
227
257
migrator , err := sqlite .NewSQLLiteMigrator (db )
228
258
if err != nil {
229
259
return nil , err
@@ -354,7 +384,7 @@ func getRelatedImages(b *registry.Bundle) ([]declcfg.RelatedImage, error) {
354
384
allImages = allImages .Insert (ri .Image )
355
385
}
356
386
357
- if ! allImages .Has (b .BundleImage ) {
387
+ if b . BundleImage != "" && ! allImages .Has (b .BundleImage ) {
358
388
relatedImages = append (relatedImages , declcfg.RelatedImage {
359
389
Image : b .BundleImage ,
360
390
})
@@ -402,3 +432,54 @@ func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig
402
432
}
403
433
return out
404
434
}
435
+
436
+ func isBundle (entries []os.DirEntry ) bool {
437
+ foundManifests := false
438
+ foundMetadata := false
439
+ for _ , e := range entries {
440
+ if e .IsDir () {
441
+ switch e .Name () {
442
+ case "manifests" :
443
+ foundManifests = true
444
+ case "metadata" :
445
+ foundMetadata = true
446
+ }
447
+ }
448
+ if foundMetadata && foundManifests {
449
+ return true
450
+ }
451
+ }
452
+ return false
453
+ }
454
+
455
+ func isPackageManifest (entries []os.DirEntry ) bool {
456
+ for _ , e := range entries {
457
+ if strings .HasSuffix (e .Name (), ".package.yaml" ) || strings .HasSuffix (e .Name (), ".package.yml" ) {
458
+ return true
459
+ }
460
+ }
461
+ return false
462
+ }
463
+
464
+ func renderPackageManifest (ctx context.Context , ref string ) (* declcfg.DeclarativeConfig , error ) {
465
+ db , err := sql .Open ("sqlite3" , fmt .Sprintf ("file:%s?mode=memory&cache=shared&_foreign_keys=on" , ref ))
466
+ if err != nil {
467
+ return nil , err
468
+ }
469
+ defer db .Close ()
470
+
471
+ dbLoader , err := sqlite .NewSQLLiteLoader (db )
472
+ if err != nil {
473
+ return nil , err
474
+ }
475
+ if err := dbLoader .Migrate (ctx ); err != nil {
476
+ return nil , err
477
+ }
478
+
479
+ loader := sqlite .NewSQLLoaderForDirectory (dbLoader , ref )
480
+ if err := loader .Populate (); err != nil {
481
+ return nil , fmt .Errorf ("error loading manifests from directory: %s" , err )
482
+ }
483
+
484
+ return sqliteToDeclcfg (ctx , db )
485
+ }
0 commit comments