Skip to content

Commit

Permalink
refactor catalogmetadata types used for resolution
Browse files Browse the repository at this point in the history
Signed-off-by: everettraven <everettraven@gmail.com>
  • Loading branch information
everettraven committed Jan 31, 2024
1 parent ef06f40 commit e37bb1c
Show file tree
Hide file tree
Showing 25 changed files with 727 additions and 677 deletions.
8 changes: 4 additions & 4 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ func main() {
}

if err = (&controllers.ClusterExtensionReconciler{
Client: cl,
BundleProvider: catalogClient,
Scheme: mgr.GetScheme(),
Resolver: resolver,
Client: cl,
CatalogProvider: catalogClient,
Scheme: mgr.GetScheme(),
Resolver: resolver,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ClusterExtension")
os.Exit(1)
Expand Down
82 changes: 61 additions & 21 deletions cmd/resolutioncli/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@ import (
"context"

"github.com/operator-framework/operator-registry/alpha/action"
"github.com/operator-framework/operator-registry/alpha/declcfg"

"github.com/operator-framework/operator-controller/internal/catalogmetadata"
"github.com/operator-framework/operator-controller/internal/catalogmetadata/client"
"github.com/operator-framework/operator-controller/internal/controllers"
)

type indexRefClient struct {
renderer action.Render
bundlesCache []*catalogmetadata.Bundle
renderer action.Render
bundlesCache []*catalogmetadata.Bundle
channelsCache []*catalogmetadata.Channel
packagesCache []*catalogmetadata.Package
}

var _ controllers.CatalogProvider = &indexRefClient{}

func newIndexRefClient(indexRef string) *indexRefClient {
return &indexRefClient{
renderer: action.Render{
Expand All @@ -39,47 +45,81 @@ func newIndexRefClient(indexRef string) *indexRefClient {
}
}

func (c *indexRefClient) Bundles(ctx context.Context) ([]*catalogmetadata.Bundle, error) {
if c.bundlesCache == nil {
func (c *indexRefClient) CatalogContents(ctx context.Context) (*client.Contents, error) {
if c.bundlesCache == nil || c.channelsCache == nil || c.packagesCache == nil {
cfg, err := c.renderer.Run(ctx)
if err != nil {
return nil, err
}

var (
channels []*catalogmetadata.Channel
bundles []*catalogmetadata.Bundle
deprecations []*catalogmetadata.Deprecation
channels []*catalogmetadata.Channel
bundles []*catalogmetadata.Bundle
packages []*catalogmetadata.Package
)

// TODO: update fake catalog name string to be catalog name once we support multiple catalogs in CLI
catalogName := "offline-catalog"

for i := range cfg.Packages {
packages = append(packages, &catalogmetadata.Package{
Package: cfg.Packages[i],
Catalog: catalogName,
})
}

for i := range cfg.Channels {
channels = append(channels, &catalogmetadata.Channel{
Channel: cfg.Channels[i],
Catalog: catalogName,
})
}

for i := range cfg.Bundles {
bundles = append(bundles, &catalogmetadata.Bundle{
Bundle: cfg.Bundles[i],
Bundle: cfg.Bundles[i],
Catalog: catalogName,
})
}

for i := range cfg.Deprecations {
deprecations = append(deprecations, &catalogmetadata.Deprecation{
Deprecation: cfg.Deprecations[i],
})
}

// TODO: update fake catalog name string to be catalog name once we support multiple catalogs in CLI
catalogName := "offline-catalog"

bundles, err = client.PopulateExtraFields(catalogName, channels, bundles, deprecations)
if err != nil {
return nil, err
for _, deprecation := range cfg.Deprecations {
for _, entry := range deprecation.Entries {
switch entry.Reference.Schema {
case declcfg.SchemaPackage:
for _, pkg := range packages {
if pkg.Name == deprecation.Package {
pkg.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
case declcfg.SchemaChannel:
for _, channel := range channels {
if channel.Package == deprecation.Package && channel.Name == entry.Reference.Name {
channel.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
case declcfg.SchemaBundle:
for _, bundle := range bundles {
if bundle.Package == deprecation.Package && bundle.Name == entry.Reference.Name {
bundle.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
}
}
}

c.bundlesCache = bundles
c.channelsCache = channels
c.packagesCache = packages
}

return c.bundlesCache, nil
return &client.Contents{}, nil
}
4 changes: 2 additions & 2 deletions cmd/resolutioncli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func run(ctx context.Context, packageName, packageChannel, packageVersionRange,

cl := clientBuilder.Build()
catalogClient := newIndexRefClient(indexRef)
allBundles, err := catalogClient.Bundles(ctx)
contents, err := catalogClient.CatalogContents(ctx)
if err != nil {
return err
}
Expand All @@ -162,7 +162,7 @@ func run(ctx context.Context, packageName, packageChannel, packageVersionRange,
if err := cl.List(ctx, &bundleDeploymentList); err != nil {
return err
}
variables, err := controllers.GenerateVariables(allBundles, clusterExtensionList.Items, bundleDeploymentList.Items)
variables, err := controllers.GenerateVariables(contents, clusterExtensionList.Items, bundleDeploymentList.Items)
if err != nil {
return err
}
Expand Down
107 changes: 54 additions & 53 deletions internal/catalogmetadata/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,31 @@ type Client struct {
fetcher Fetcher
}

func (c *Client) Bundles(ctx context.Context) ([]*catalogmetadata.Bundle, error) {
var allBundles []*catalogmetadata.Bundle
type Contents struct {
Packages []*catalogmetadata.Package
Channels []*catalogmetadata.Channel
Bundles []*catalogmetadata.Bundle
}

func (c *Client) CatalogContents(ctx context.Context) (*Contents, error) {
var catalogList catalogd.CatalogList
if err := c.cl.List(ctx, &catalogList); err != nil {
return nil, err
}

contents := &Contents{
Packages: []*catalogmetadata.Package{},
Channels: []*catalogmetadata.Channel{},
Bundles: []*catalogmetadata.Bundle{},
}

for _, catalog := range catalogList.Items {
// if the catalog has not been successfully unpacked, skip it
if !meta.IsStatusConditionPresentAndEqual(catalog.Status.Conditions, catalogd.TypeUnpacked, metav1.ConditionTrue) {
continue
}

packages := []*catalogmetadata.Package{}
channels := []*catalogmetadata.Channel{}
bundles := []*catalogmetadata.Bundle{}
deprecations := []*catalogmetadata.Deprecation{}
Expand All @@ -70,93 +83,81 @@ func (c *Client) Bundles(ctx context.Context) ([]*catalogmetadata.Bundle, error)
return fmt.Errorf("error was provided to the WalkMetasReaderFunc: %s", err)
}
switch meta.Schema {
case declcfg.SchemaPackage:
var content catalogmetadata.Package
if err := json.Unmarshal(meta.Blob, &content); err != nil {
return fmt.Errorf("error unmarshalling channel from catalog metadata: %s", err)
}
content.Catalog = catalog.Name
packages = append(packages, &content)
case declcfg.SchemaChannel:
var content catalogmetadata.Channel
if err := json.Unmarshal(meta.Blob, &content); err != nil {
return fmt.Errorf("error unmarshalling channel from catalog metadata: %s", err)
}
content.Catalog = catalog.Name
channels = append(channels, &content)
case declcfg.SchemaBundle:
var content catalogmetadata.Bundle
if err := json.Unmarshal(meta.Blob, &content); err != nil {
return fmt.Errorf("error unmarshalling bundle from catalog metadata: %s", err)
}
content.Catalog = catalog.Name
bundles = append(bundles, &content)
case declcfg.SchemaDeprecation:
var content catalogmetadata.Deprecation
if err := json.Unmarshal(meta.Blob, &content); err != nil {
return fmt.Errorf("error unmarshalling deprecation from catalog metadata: %s", err)
}
content.Catalog = catalog.Name
deprecations = append(deprecations, &content)
}

return nil
})
if err != nil {
return nil, fmt.Errorf("error processing response: %s", err)
}

bundles, err = PopulateExtraFields(catalog.Name, channels, bundles, deprecations)
if err != nil {
return nil, err
}

allBundles = append(allBundles, bundles...)
}

return allBundles, nil
}

func PopulateExtraFields(catalogName string, channels []*catalogmetadata.Channel, bundles []*catalogmetadata.Bundle, deprecations []*catalogmetadata.Deprecation) ([]*catalogmetadata.Bundle, error) {
bundlesMap := map[string]*catalogmetadata.Bundle{}
for i := range bundles {
bundleKey := fmt.Sprintf("%s-%s", bundles[i].Package, bundles[i].Name)
bundlesMap[bundleKey] = bundles[i]

bundles[i].CatalogName = catalogName
}

for _, ch := range channels {
for _, chEntry := range ch.Entries {
bundleKey := fmt.Sprintf("%s-%s", ch.Package, chEntry.Name)
bundle, ok := bundlesMap[bundleKey]
if !ok {
return nil, fmt.Errorf("bundle %q not found in catalog %q (package %q, channel %q)", chEntry.Name, catalogName, ch.Package, ch.Name)
}

bundle.InChannels = append(bundle.InChannels, ch)
return nil, fmt.Errorf("error processing response: %s", err)
}
}

// According to https://docs.google.com/document/d/1EzefSzoGZL2ipBt-eCQwqqNwlpOIt7wuwjG6_8ZCi5s/edit?usp=sharing
// the olm.deprecations FBC object is only valid when either 0 or 1 instances exist
// for any given package
deprecationMap := make(map[string]*catalogmetadata.Deprecation, len(deprecations))
for _, deprecation := range deprecations {
deprecationMap[deprecation.Package] = deprecation
}

for i := range bundles {
if dep, ok := deprecationMap[bundles[i].Package]; ok {
for _, entry := range dep.Entries {
for _, deprecation := range deprecations {
for _, entry := range deprecation.Entries {
switch entry.Reference.Schema {
case declcfg.SchemaPackage:
bundles[i].Deprecations = append(bundles[i].Deprecations, entry)
for _, pkg := range packages {
if pkg.Name == deprecation.Package {
pkg.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
case declcfg.SchemaChannel:
for _, ch := range bundles[i].InChannels {
if ch.Name == entry.Reference.Name {
bundles[i].Deprecations = append(bundles[i].Deprecations, entry)
break
for _, channel := range channels {
if channel.Package == deprecation.Package && channel.Name == entry.Reference.Name {
channel.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
case declcfg.SchemaBundle:
if bundles[i].Name == entry.Reference.Name {
bundles[i].Deprecations = append(bundles[i].Deprecations, entry)
for _, bundle := range bundles {
if bundle.Package == deprecation.Package && bundle.Name == entry.Reference.Name {
bundle.Deprecation = &declcfg.DeprecationEntry{
Reference: entry.Reference,
Message: entry.Message,
}
}
}
}
}
}

contents.Packages = append(contents.Packages, packages...)
contents.Channels = append(contents.Channels, channels...)
contents.Bundles = append(contents.Bundles, bundles...)
}

return bundles, nil
return contents, nil
}
Loading

0 comments on commit e37bb1c

Please sign in to comment.