Skip to content

Commit

Permalink
Image digests for referencing bundles
Browse files Browse the repository at this point in the history
- Change schema of OperatorBundle to include field 'bundlepath'
- Extend GetBundle API to return bundle image path
- Modify GetBundle API to return struct with avaiable fields
  instead of error while querrying empty bundles
  • Loading branch information
anik120 committed Oct 28, 2019
1 parent 161f66a commit 748192e
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 154 deletions.
3 changes: 2 additions & 1 deletion pkg/api/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func BundleStringToObjectStrings(bundleString string) ([]string, error) {
return objs, nil
}

func BundleStringToAPIBundle(bundleString string, entry *registry.ChannelEntry) (*Bundle, error) {
func BundleStringToAPIBundle(bundleString string, bundlepathString string, entry *registry.ChannelEntry) (*Bundle, error) {
objs, err := BundleStringToObjectStrings(bundleString)
if err != nil {
return nil, err
Expand All @@ -80,5 +80,6 @@ func BundleStringToAPIBundle(bundleString string, entry *registry.ChannelEntry)
}
out.ChannelName = entry.ChannelName
out.PackageName = entry.PackageName
out.BundlePath = bundlepathString
return out, nil
}
242 changes: 149 additions & 93 deletions pkg/api/registry.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pkg/api/registry.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ message Bundle{
string channelName = 3;
string csvJson = 4;
repeated string object = 5;
string bundlePath = 6;
}

message ChannelEntry{
Expand Down
16 changes: 8 additions & 8 deletions pkg/registry/empty.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ func (EmptyQuery) GetPackage(ctx context.Context, name string) (*PackageManifest
return nil, errors.New("empty querier: cannot get package")
}

func (EmptyQuery) GetBundle(ctx context.Context, pkgName, channelName, csvName string) (string, error) {
return "", errors.New("empty querier: cannot get bundle")
func (EmptyQuery) GetBundle(ctx context.Context, pkgName, channelName, csvName string) (string, string, error) {
return "", "", errors.New("empty querier: cannot get bundle")
}

func (EmptyQuery) GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (string, error) {
return "", errors.New("empty querier: cannot get bundle for channel")
func (EmptyQuery) GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (string, string, error) {
return "", "", errors.New("empty querier: cannot get bundle for channel")
}

func (EmptyQuery) GetChannelEntriesThatReplace(ctx context.Context, name string) (entries []*ChannelEntry, err error) {
return nil, errors.New("empty querier: cannot get channel entries that replace")
}

func (EmptyQuery) GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (string, error) {
return "", errors.New("empty querier: cannot get bundle that replaces")
func (EmptyQuery) GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (string, string, error) {
return "", "", errors.New("empty querier: cannot get bundle that replaces")
}

func (EmptyQuery) GetChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*ChannelEntry, err error) {
Expand All @@ -46,8 +46,8 @@ func (EmptyQuery) GetLatestChannelEntriesThatProvide(ctx context.Context, group,
return nil, errors.New("empty querier: cannot get latest channel entries that provide")
}

func (EmptyQuery) GetBundleThatProvides(ctx context.Context, group, version, kind string) (string, *ChannelEntry, error) {
return "", nil, errors.New("empty querier: cannot get bundle that provides")
func (EmptyQuery) GetBundleThatProvides(ctx context.Context, group, version, kind string) (string, string, *ChannelEntry, error) {
return "", "", nil, errors.New("empty querier: cannot get bundle that provides")
}

func (EmptyQuery) ListImages(ctx context.Context) ([]string, error) {
Expand Down
8 changes: 4 additions & 4 deletions pkg/registry/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ type Query interface {
ListTables(ctx context.Context) ([]string, error)
ListPackages(ctx context.Context) ([]string, error)
GetPackage(ctx context.Context, name string) (*PackageManifest, error)
GetBundle(ctx context.Context, pkgName, channelName, csvName string) (string, error)
GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (string, error)
GetBundle(ctx context.Context, pkgName, channelName, csvName string) (string, string, error)
GetBundleForChannel(ctx context.Context, pkgName string, channelName string) (string, string, error)
// Get all channel entries that say they replace this one
GetChannelEntriesThatReplace(ctx context.Context, name string) (entries []*ChannelEntry, err error)
// Get the bundle in a package/channel that replace this one
GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (string, error)
GetBundleThatReplaces(ctx context.Context, name, pkgName, channelName string) (string, string, error)
// Get all channel entries that provide an api
GetChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*ChannelEntry, err error)
// Get latest channel entries that provide an api
GetLatestChannelEntriesThatProvide(ctx context.Context, group, version, kind string) (entries []*ChannelEntry, err error)
// Get the the latest bundle that provides the API in a default channel
GetBundleThatProvides(ctx context.Context, group, version, kind string) (string, *ChannelEntry, error)
GetBundleThatProvides(ctx context.Context, group, version, kind string) (string, string, *ChannelEntry, error)
// List all images in the database
ListImages(ctx context.Context) ([]string, error)
// List all images for a particular bundle
Expand Down
29 changes: 21 additions & 8 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,40 @@ func (s *RegistryServer) GetPackage(ctx context.Context, req *api.GetPackageRequ
}

func (s *RegistryServer) GetBundle(ctx context.Context, req *api.GetBundleRequest) (*api.Bundle, error) {
bundleString, err := s.store.GetBundle(ctx, req.GetPkgName(), req.GetChannelName(), req.GetCsvName())
bundleString, bundlepathString, err := s.store.GetBundle(ctx, req.GetPkgName(), req.GetChannelName(), req.GetCsvName())
if err != nil {
return nil, err
}
// If the value of the `bundle` field in the OperatorBundle table is NULL, return a
// Bundle struct with available fields
if bundleString == "" {
bundle := &api.Bundle{
PackageName: req.PkgName,
ChannelName: req.ChannelName,
CsvName: req.CsvName,
CsvJson: "",
Object: []string{},
BundlePath: bundlepathString,
}
return bundle, nil
}
entry := &registry.ChannelEntry{
PackageName: req.GetPkgName(),
ChannelName: req.GetChannelName(),
}
return api.BundleStringToAPIBundle(bundleString, entry)
return api.BundleStringToAPIBundle(bundleString, bundlepathString, entry)
}

func (s *RegistryServer) GetBundleForChannel(ctx context.Context, req *api.GetBundleInChannelRequest) (*api.Bundle, error) {
bundleString, err := s.store.GetBundleForChannel(ctx, req.GetPkgName(), req.GetChannelName())
bundleString, bundlepathString, err := s.store.GetBundleForChannel(ctx, req.GetPkgName(), req.GetChannelName())
if err != nil {
return nil, err
}
entry := &registry.ChannelEntry{
PackageName: req.GetPkgName(),
ChannelName: req.GetChannelName(),
}
return api.BundleStringToAPIBundle(bundleString, entry)
return api.BundleStringToAPIBundle(bundleString, bundlepathString, entry)
}

func (s *RegistryServer) GetChannelEntriesThatReplace(req *api.GetAllReplacementsRequest, stream api.Registry_GetChannelEntriesThatReplaceServer) error {
Expand All @@ -76,7 +89,7 @@ func (s *RegistryServer) GetChannelEntriesThatReplace(req *api.GetAllReplacement
}

func (s *RegistryServer) GetBundleThatReplaces(ctx context.Context, req *api.GetReplacementRequest) (*api.Bundle, error) {
bundleString, err := s.store.GetBundleThatReplaces(ctx, req.GetCsvName(), req.GetPkgName(), req.GetChannelName())
bundleString, bundlepathString, err := s.store.GetBundleThatReplaces(ctx, req.GetCsvName(), req.GetPkgName(), req.GetChannelName())
if err != nil {
return nil, err
}
Expand All @@ -85,7 +98,7 @@ func (s *RegistryServer) GetBundleThatReplaces(ctx context.Context, req *api.Get
ChannelName: req.GetChannelName(),
Replaces: req.GetCsvName(),
}
return api.BundleStringToAPIBundle(bundleString, entry)
return api.BundleStringToAPIBundle(bundleString, bundlepathString, entry)
}

func (s *RegistryServer) GetChannelEntriesThatProvide(req *api.GetAllProvidersRequest, stream api.Registry_GetChannelEntriesThatProvideServer) error {
Expand Down Expand Up @@ -115,9 +128,9 @@ func (s *RegistryServer) GetLatestChannelEntriesThatProvide(req *api.GetLatestPr
}

func (s *RegistryServer) GetDefaultBundleThatProvides(ctx context.Context, req *api.GetDefaultProviderRequest) (*api.Bundle, error) {
bundleString, channelEntry, err := s.store.GetBundleThatProvides(ctx, req.GetGroup(), req.GetVersion(), req.GetKind())
bundleString, bundlepathString, channelEntry, err := s.store.GetBundleThatProvides(ctx, req.GetGroup(), req.GetVersion(), req.GetKind())
if err != nil {
return nil, err
}
return api.BundleStringToAPIBundle(bundleString, channelEntry)
return api.BundleStringToAPIBundle(bundleString, bundlepathString, channelEntry)
}
5 changes: 5 additions & 0 deletions pkg/server/server_test.go

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions pkg/sqlite/configmap_test.go

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions pkg/sqlite/directory_test.go

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pkg/sqlite/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (s *SQLLoader) AddOperatorBundle(bundle *registry.Bundle) error {
tx.Rollback()
}()

stmt, err := tx.Prepare("insert into operatorbundle(name, csv, bundle) values(?, ?, ?)")
stmt, err := tx.Prepare("insert into operatorbundle(name, csv, bundle, bundlepath) values(?, ?, ?, ?)")
if err != nil {
return err
}
Expand All @@ -77,7 +77,7 @@ func (s *SQLLoader) AddOperatorBundle(bundle *registry.Bundle) error {
return fmt.Errorf("csv name not found")
}

if _, err := stmt.Exec(csvName, csvBytes, bundleBytes); err != nil {
if _, err := stmt.Exec(csvName, csvBytes, bundleBytes, nil); err != nil {
return err
}

Expand Down
55 changes: 55 additions & 0 deletions pkg/sqlite/migrations/002_bundle_path.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package migrations

import (
"context"
"database/sql"
)

const BundlePathMigrationKey = 2

var bundlePathMigration = &Migration{
Id: BundlePathMigrationKey,
Up: func(ctx context.Context, tx *sql.Tx) error {
sql := `
ALTER TABLE operatorbundle
ADD COLUMN bundlepath TEXT;
`
_, err := tx.ExecContext(ctx, sql)
return err
},
Down: func(ctx context.Context, tx *sql.Tx) error {
foreingKeyOff := `PRAGMA foreign_keys = 0`
createTempTable := `CREATE TABLE operatorbundle_backup (name TEXT,csv TEXT,bundle TEXT)`
backupTargetTable := `INSERT INTO operatorbundle_backup SELECT name,csv,bundle FROM operatorbundle`
dropTargetTable := `DROP TABLE operatorbundle`
renameBackUpTable := `ALTER TABLE operatorbundle_backup RENAME TO operatorbundle;`
foreingKeyOn := `PRAGMA foreign_keys = 1`
_, err := tx.ExecContext(ctx, foreingKeyOff)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, createTempTable)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, backupTargetTable)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, dropTargetTable)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, renameBackUpTable)
if err != nil {
return err
}
_, err = tx.ExecContext(ctx, foreingKeyOn)
return err
},
}

// Register this migration
func init() {
migrations[BundlePathMigrationKey] = bundlePathMigration
}
44 changes: 44 additions & 0 deletions pkg/sqlite/migrations/002_bundle_path_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package migrations_test

import (
"context"
"testing"

"github.com/operator-framework/operator-registry/pkg/sqlite"
"github.com/operator-framework/operator-registry/pkg/sqlite/migrations"
"github.com/stretchr/testify/require"
)

func TestBundlePathUp(t *testing.T) {
db, migrator, cleanup := CreateTestDbAt(t, migrations.BundlePathMigrationKey-1)
defer cleanup()

err := migrator.Up(context.TODO(), migrations.Only(migrations.BundlePathMigrationKey))
require.NoError(t, err)

// Adding row with bundlepath colum should not fail after migrating up
tx, err := db.Begin()
stmt, err := tx.Prepare("insert into operatorbundle(name, csv, bundle, bundlepath) values(?, ?, ?, ?)")
require.NoError(t, err)
defer stmt.Close()

_, err = stmt.Exec("testName", "testCSV", "testBundle", "quay.io/test")
require.NoError(t, err)

}

func TestBundlePathDown(t *testing.T) {
db, migrator, cleanup := CreateTestDbAt(t, migrations.BundlePathMigrationKey)
defer cleanup()

querier := sqlite.NewSQLLiteQuerierFromDb(db)
imagesBeforeMigration, err := querier.GetImagesForBundle(context.TODO(), "etcdoperator.v0.6.1")

err = migrator.Down(context.TODO(), migrations.Only(migrations.BundlePathMigrationKey))
require.NoError(t, err)

imagesAfterMigration, err := querier.GetImagesForBundle(context.TODO(), "etcdoperator.v0.6.1")

// Migrating down entails sensitive operations. Ensure data is preserved accross down migration
require.Equal(t, len(imagesBeforeMigration), len(imagesAfterMigration))
}
Loading

0 comments on commit 748192e

Please sign in to comment.