Skip to content
Closed
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
20 changes: 20 additions & 0 deletions internal/olm/operator/bundle/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

type Install struct {
BundleImage string
CatalogOnly bool

*registry.IndexImageCatalogCreator
*registry.OperatorInstaller
Expand All @@ -55,6 +56,7 @@ func (i *Install) BindFlags(fs *pflag.FlagSet) {
"the registry pod to decompress the compressed catalog contents. cat and gzip binaries are expected to exist "+
"in the PATH")
fs.Var(&i.InstallMode, "install-mode", "install mode")
fs.BoolVar(&i.CatalogOnly, "catalog-only", false, "create only the catalog source without creating a subscription")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking the time to look into this and contribute to the project!

A few questions to better understand the need for this flag:

  • How do you plan to use it?
  • Why do you believe this flag should be added?
  • What is the use case or scenario it addresses?
  • Can you describe the expected flow and how this change would help?

Also, if we move forward with adding this flag, we’ll need to make sure tests properly cover it.
Could you please take a look at that as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Motivation for the change:

Currently, the operator-sdk run bundle command creates both a catalog source and a subscription. However, there are use cases where users need only the catalog source:

Testing tokenized auth install flows: For testing the OpenShift Console's operator install frontend with tokenized authentication (see operator-hub-subscribe.tsx#L502-L555), automatic subscription creation is not desirable. The frontend needs to handle the subscription creation flow itself to properly manage authentication tokens.
Manual subscription management: Users may want to create the catalog source first and then manually create subscriptions with specific configurations
Integration with other tools: Other automation tools or operators may need to create subscriptions programmatically after the catalog source is available
Testing: Developers may want to test catalog source creation independently from operator installation
Multi-tenant scenarios: In environments where different teams manage catalog sources and subscriptions separately

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't understand the need for this, there are n number of other ways to create a catalog/subscription.

  • call oc apply -f - <<'EOF' with the file content
  • call the api in code via k8s libraries

Copy link
Copy Markdown
Contributor Author

@kaovilai kaovilai May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course there is always a more manual way.. this is just a way to reuse your (operator-sdk) existing logic around creating catalogsource from an already existing bundle image.

See here

The subscription created by operator-sdk run bundle does not have the right env etc and requries deletion. It's just inconvenient that we have do maintain another target for creating a bundle image, push, catalogsource, push.. when that already exists here except it also creates subscription without all the required environments.

Copy link
Copy Markdown
Contributor Author

@kaovilai kaovilai May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't understand the need for this, there are n number of other ways to create a catalog/subscription.

call oc apply -f - <<'EOF' with the file content
call the api in code via k8s libraries

By this logic, operator-sdk run bundle doesn't need to exists at all.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For what it's worth, I think this feature request makes a lot of sense. There's a bunch of special sauce in run bundle to get a working catalogsource in place without having to build/push a catalog image that would be impractical to duplicate elsewhere. And as far as I know, the run bundle code has required very little maintenance.

To me this seems like a simple change that can solve a real problem.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joelanford my keyword was 'here', as in this repo.

Fair, but I think the thinking at the time was that operator-sdk was a natural place because run bundle was geared toward operator authors and they were likely using operator-sdk to generate their bundle.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RFE created. Thanks all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my keyword was 'here', as in this repo.

Another repo suggestions would be cool as well. If OPM is the most appropriate I can PR there.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for the RFE — it’s amazing! 🙌

Just to clarify: OPM is the tool used to create catalogs, so we don’t need to open a PR there.
That said, I totally understand the frustration around the number of tools and the lack of abstraction — you're not alone on that!

For now, I think a good approach would be:

Reference
Check out this guide: https://olm.operatorframework.io/docs/tasks/creating-a-catalog/
The pipeline uses OPM and render to produce a final FBC format.

Feel free to reach out us in the Slack channel if you find issues with OPM to do your scenario and need a help.


// --mode is hidden so only users who know what they're doing can alter add mode.
fs.StringVar((*string)(&i.BundleAddMode), "mode", "", "mode to use for adding bundle to index")
Expand All @@ -67,9 +69,27 @@ func (i Install) Run(ctx context.Context) (*v1alpha1.ClusterServiceVersion, erro
if err := i.setup(ctx); err != nil {
return nil, err
}

// If catalog-only mode is enabled, create only the catalog source
if i.CatalogOnly {
return i.RunCatalogOnly(ctx)
}

return i.InstallOperator(ctx)
}

func (i *Install) RunCatalogOnly(ctx context.Context) (*v1alpha1.ClusterServiceVersion, error) {
cs, err := i.CatalogCreator.CreateCatalog(ctx, i.CatalogSourceName)
if err != nil {
return nil, fmt.Errorf("create catalog: %v", err)
}
log.Infof("Created CatalogSource: %s", cs.GetName())
log.Infof("Catalog-only mode: skipping subscription creation")

// Return nil CSV since we're not installing the operator
return nil, nil
}

func (i *Install) setup(ctx context.Context) error {
// Validate add mode in case it was set by a user.
if i.BundleAddMode != "" {
Expand Down
Loading