Skip to content

Commit 2f2e8c4

Browse files
committed
render: support rendering DC from packagemanifest and bundle directories
Signed-off-by: Joe Lanford <[email protected]>
1 parent 7c8187a commit 2f2e8c4

File tree

7 files changed

+369
-27
lines changed

7 files changed

+369
-27
lines changed

alpha/action/render.go

Lines changed: 103 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ type RefType uint
3434

3535
const (
3636
RefBundleImage RefType = 1 << iota
37+
RefBundleDir
3738
RefSqliteImage
3839
RefSqliteFile
3940
RefDCImage
4041
RefDCDir
42+
RefPackageManifestDir
4143

4244
RefAll = 0
4345
)
@@ -117,25 +119,54 @@ func (r Render) createRegistry() (*containerdregistry.Registry, error) {
117119
}
118120

119121
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)
124135
}
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 {
130138
return nil, err
131139
}
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)
134145
}
135-
return sqliteToDeclcfg(ctx, ref)
146+
return renderPackageManifest(ctx, ref)
136147
}
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)
137162
}
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)
139170
}
140171

141172
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
161192
if !r.AllowedRefMask.Allowed(RefSqliteImage) {
162193
return nil, fmt.Errorf("cannot render sqlite image: %w", ErrNotAllowed)
163194
}
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)
165201
if err != nil {
166202
return nil, err
167203
}
@@ -213,17 +249,11 @@ func checkDBFile(ref string) error {
213249
return nil
214250
}
215251

216-
func sqliteToDeclcfg(ctx context.Context, dbFile string) (*declcfg.DeclarativeConfig, error) {
252+
func sqliteToDeclcfg(ctx context.Context, db *sql.DB) (*declcfg.DeclarativeConfig, error) {
217253
logDeprecationMessage.Do(func() {
218254
sqlite.LogSqliteDeprecation()
219255
})
220256

221-
db, err := sqlite.Open(dbFile)
222-
if err != nil {
223-
return nil, err
224-
}
225-
defer db.Close()
226-
227257
migrator, err := sqlite.NewSQLLiteMigrator(db)
228258
if err != nil {
229259
return nil, err
@@ -354,7 +384,7 @@ func getRelatedImages(b *registry.Bundle) ([]declcfg.RelatedImage, error) {
354384
allImages = allImages.Insert(ri.Image)
355385
}
356386

357-
if !allImages.Has(b.BundleImage) {
387+
if b.BundleImage != "" && !allImages.Has(b.BundleImage) {
358388
relatedImages = append(relatedImages, declcfg.RelatedImage{
359389
Image: b.BundleImage,
360390
})
@@ -402,3 +432,54 @@ func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig
402432
}
403433
return out
404434
}
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

Comments
 (0)