Skip to content

NO-ISSUE: Synchronize From Upstream Repositories #702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions staging/api/.github/workflows/go.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
branches:
- '**'
workflow_dispatch:
merge_group:
jobs:
build:
name: Build
Expand Down
1 change: 1 addition & 0 deletions staging/api/.github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
paths:
- '**'
workflow_dispatch:
merge_group:
jobs:
verify:
runs-on: ubuntu-latest
Expand Down
37 changes: 37 additions & 0 deletions staging/api/DCO
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or

(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or

(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.

(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
5 changes: 4 additions & 1 deletion staging/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ Api

Contains the API definitions used by [Operator Lifecycle Manager][olm] (OLM) and [Marketplace Operator][marketplace]

## Certificate of Origin
By contributing to this project you agree to the Developer Certificat of Origin (DCO). This document was created by the Linux Kernel community and is a simple statement that you, as a contributor, have the legal right to make the contribution. See the [DCO][DCO] file for details.

## `pkg/validation`: Operator Manifest Validation

`pkg/validation` exposes a convenient set of interfaces to validate Kubernetes object manifests, primarily for use in an Operator project.
Expand Down Expand Up @@ -128,4 +131,4 @@ To verify your ClusterServiceVersion yaml,
[olm]: https://github.com/operator-framework/operator-lifecycle-manager
[marketplace]: https://github.com/operator-framework/operator-marketplace
[bundle]: https://github.com/operator-framework/operator-registry/blob/v1.19.5/docs/design/operator-bundle.md
[sdk-command-doc]: https://master.sdk.operatorframework.io/docs/cli/operator-sdk_bundle_validate/
[sdk-command-doc]: https://master.sdk.operatorframework.io/docs/cli/operator-sdk_bundle_validate/
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- '**'
- '!doc/**'
merge_group:

jobs:
go-apidiff:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
pull_request: {}
merge_group:
defaults:
run:
shell: bash
Expand Down
1 change: 1 addition & 0 deletions staging/operator-registry/.github/workflows/sanity.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- '**'
- '!doc/**'
merge_group:

jobs:
sanity:
Expand Down
2 changes: 2 additions & 0 deletions staging/operator-registry/.github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
paths:
- '**'
- '!doc/**'
merge_group:

jobs:
e2e:
runs-on: ubuntu-20.04
Expand Down
1 change: 1 addition & 0 deletions staging/operator-registry/.github/workflows/unit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- '**'
- '!doc/**'
merge_group:

jobs:
unit:
Expand Down
159 changes: 124 additions & 35 deletions staging/operator-registry/alpha/action/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"sort"
"strings"
"sync"
"text/template"

"github.com/h2non/filetype"
"github.com/h2non/filetype/matchers"
Expand Down Expand Up @@ -39,6 +40,7 @@ const (
RefSqliteFile
RefDCImage
RefDCDir
RefBundleDir

RefAll = 0
)
Expand All @@ -50,10 +52,11 @@ func (r RefType) Allowed(refType RefType) bool {
var ErrNotAllowed = errors.New("not allowed")

type Render struct {
Refs []string
Registry image.Registry
AllowedRefMask RefType
Migrate bool
Refs []string
Registry image.Registry
AllowedRefMask RefType
Migrate bool
ImageRefTemplate *template.Template

skipSqliteDeprecationLog bool
}
Expand Down Expand Up @@ -125,25 +128,44 @@ func (r Render) createRegistry() (*containerdregistry.Registry, error) {
}

func (r Render) renderReference(ctx context.Context, ref string) (*declcfg.DeclarativeConfig, error) {
if stat, serr := os.Stat(ref); serr == nil {
if stat.IsDir() {
if !r.AllowedRefMask.Allowed(RefDCDir) {
return nil, fmt.Errorf("cannot render declarative config directory: %w", ErrNotAllowed)
}
return declcfg.LoadFS(ctx, os.DirFS(ref))
} else {
// The only supported file type is an sqlite DB file,
// since declarative configs will be in a directory.
if err := checkDBFile(ref); err != nil {
return nil, err
}
if !r.AllowedRefMask.Allowed(RefSqliteFile) {
return nil, fmt.Errorf("cannot render sqlite file: %w", ErrNotAllowed)
stat, err := os.Stat(ref)
if err != nil {
return r.imageToDeclcfg(ctx, ref)
}
if stat.IsDir() {
dirEntries, err := os.ReadDir(ref)
if err != nil {
return nil, err
}
if isBundle(dirEntries) {
// Looks like a bundle directory
if !r.AllowedRefMask.Allowed(RefBundleDir) {
return nil, fmt.Errorf("cannot render bundle directory %q: %w", ref, ErrNotAllowed)
}
return sqliteToDeclcfg(ctx, ref)
return r.renderBundleDirectory(ref)
}

// Otherwise, assume it is a declarative config root directory.
if !r.AllowedRefMask.Allowed(RefDCDir) {
return nil, fmt.Errorf("cannot render declarative config directory: %w", ErrNotAllowed)
}
return declcfg.LoadFS(ctx, os.DirFS(ref))
}
// The only supported file type is an sqlite DB file,
// since declarative configs will be in a directory.
if err := checkDBFile(ref); err != nil {
return nil, err
}
if !r.AllowedRefMask.Allowed(RefSqliteFile) {
return nil, fmt.Errorf("cannot render sqlite file: %w", ErrNotAllowed)
}

db, err := sqlite.Open(ref)
if err != nil {
return nil, err
}
return r.imageToDeclcfg(ctx, ref)
defer db.Close()
return sqliteToDeclcfg(ctx, db)
}

func (r Render) imageToDeclcfg(ctx context.Context, imageRef string) (*declcfg.DeclarativeConfig, error) {
Expand All @@ -169,7 +191,12 @@ func (r Render) imageToDeclcfg(ctx context.Context, imageRef string) (*declcfg.D
if !r.AllowedRefMask.Allowed(RefSqliteImage) {
return nil, fmt.Errorf("cannot render sqlite image: %w", ErrNotAllowed)
}
cfg, err = sqliteToDeclcfg(ctx, filepath.Join(tmpDir, dbFile))
db, err := sqlite.Open(filepath.Join(tmpDir, dbFile))
if err != nil {
return nil, err
}
defer db.Close()
cfg, err = sqliteToDeclcfg(ctx, db)
if err != nil {
return nil, err
}
Expand All @@ -190,10 +217,11 @@ func (r Render) imageToDeclcfg(ctx context.Context, imageRef string) (*declcfg.D
return nil, err
}

cfg, err = bundleToDeclcfg(img.Bundle)
bundle, err := bundleToDeclcfg(img.Bundle)
if err != nil {
return nil, err
}
cfg = &declcfg.DeclarativeConfig{Bundles: []declcfg.Bundle{*bundle}}
} else {
labelKeys := sets.StringKeySet(labels)
labelVals := []string{}
Expand Down Expand Up @@ -221,17 +249,11 @@ func checkDBFile(ref string) error {
return nil
}

func sqliteToDeclcfg(ctx context.Context, dbFile string) (*declcfg.DeclarativeConfig, error) {
func sqliteToDeclcfg(ctx context.Context, db *sql.DB) (*declcfg.DeclarativeConfig, error) {
logDeprecationMessage.Do(func() {
sqlite.LogSqliteDeprecation()
})

db, err := sqlite.Open(dbFile)
if err != nil {
return nil, err
}
defer db.Close()

migrator, err := sqlite.NewSQLLiteMigrator(db)
if err != nil {
return nil, err
Expand Down Expand Up @@ -303,7 +325,7 @@ func populateDBRelatedImages(ctx context.Context, cfg *declcfg.DeclarativeConfig
return nil
}

func bundleToDeclcfg(bundle *registry.Bundle) (*declcfg.DeclarativeConfig, error) {
func bundleToDeclcfg(bundle *registry.Bundle) (*declcfg.Bundle, error) {
objs, props, err := registry.ObjectsAndPropertiesFromBundle(bundle)
if err != nil {
return nil, fmt.Errorf("get properties for bundle %q: %v", bundle.Name, err)
Expand All @@ -323,7 +345,7 @@ func bundleToDeclcfg(bundle *registry.Bundle) (*declcfg.DeclarativeConfig, error
}
}

dBundle := declcfg.Bundle{
return &declcfg.Bundle{
Schema: "olm.bundle",
Name: bundle.Name,
Package: bundle.Package,
Expand All @@ -332,9 +354,7 @@ func bundleToDeclcfg(bundle *registry.Bundle) (*declcfg.DeclarativeConfig, error
RelatedImages: relatedImages,
Objects: objs,
CsvJSON: string(csvJson),
}

return &declcfg.DeclarativeConfig{Bundles: []declcfg.Bundle{dBundle}}, nil
}, nil
}

func getRelatedImages(b *registry.Bundle) ([]declcfg.RelatedImage, error) {
Expand Down Expand Up @@ -363,7 +383,7 @@ func getRelatedImages(b *registry.Bundle) ([]declcfg.RelatedImage, error) {
allImages = allImages.Insert(ri.Image)
}

if !allImages.Has(b.BundleImage) {
if b.BundleImage != "" && !allImages.Has(b.BundleImage) {
relatedImages = append(relatedImages, declcfg.RelatedImage{
Image: b.BundleImage,
})
Expand Down Expand Up @@ -454,3 +474,72 @@ func combineConfigs(cfgs []declcfg.DeclarativeConfig) *declcfg.DeclarativeConfig
}
return out
}

func isBundle(entries []os.DirEntry) bool {
foundManifests := false
foundMetadata := false
for _, e := range entries {
if e.IsDir() {
switch e.Name() {
case "manifests":
foundManifests = true
case "metadata":
foundMetadata = true
}
}
if foundMetadata && foundManifests {
return true
}
}
return false
}

type imageReferenceTemplateData struct {
Package string
Name string
Version string
}

func (r *Render) renderBundleDirectory(ref string) (*declcfg.DeclarativeConfig, error) {
img, err := registry.NewImageInput(image.SimpleReference(""), ref)
if err != nil {
return nil, err
}
if err := r.templateBundleImageRef(img.Bundle); err != nil {
return nil, fmt.Errorf("failed templating image reference from bundle for %q: %v", ref, err)
}
fbcBundle, err := bundleToDeclcfg(img.Bundle)
if err != nil {
return nil, err
}
return &declcfg.DeclarativeConfig{Bundles: []declcfg.Bundle{*fbcBundle}}, nil
}

func (r *Render) templateBundleImageRef(bundle *registry.Bundle) error {
if r.ImageRefTemplate == nil {
return nil
}

var pkgProp property.Package
for _, p := range bundle.Properties {
if p.Type != property.TypePackage {
continue
}
if err := json.Unmarshal(p.Value, &pkgProp); err != nil {
return err
}
break
}

var buf strings.Builder
tmplInput := imageReferenceTemplateData{
Package: bundle.Package,
Name: bundle.Name,
Version: pkgProp.Version,
}
if err := r.ImageRefTemplate.Execute(&buf, tmplInput); err != nil {
return err
}
bundle.BundleImage = buf.String()
return nil
}
Loading