operator-framework / operator-sdk

SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
https://sdk.operatorframework.io
Apache License 2.0
7.24k stars 1.75k forks source link

Can't set package name when using `operator-sdk generate bundle` #4045

Closed horis233 closed 3 years ago

horis233 commented 4 years ago

Bug Report

I can't set package name when using operator-sdk generate bundle to generate bundle files.

What did you do?

When I use the make bundle-manifests command generated by the operator-sdk, I found I can't set the package name for my operator.


➜  operand-deployment-lifecycle-manager git:(update-odlm-package-name) operator-sdk generate bundle -h

Running 'generate bundle' is the first step to publishing your operator to a catalog and/or deploying it with OLM.
This command generates a set of bundle manifests, metadata, and a bundle.Dockerfile for your operator.
Typically one would run 'generate kustomize manifests' first to (re)generate kustomize bases consumed by this command.

Set '--version' to supply a semantic version for your bundle if you are creating one
for the first time or upgrading an existing one.

If '--output-dir' is set and you wish to build bundle images from that directory,
either manually update your bundle.Dockerfile or set '--overwrite'.

More information on bundles:
https://github.com/operator-framework/operator-registry/#manifest-format

Usage:
  operator-sdk generate bundle [flags]

Examples:

  # Generate bundle files and build your bundle image with these 'make' recipes:
  $ make bundle
  $ export USERNAME=<your registry username>
  $ export BUNDLE_IMG=quay.io/$USERNAME/memcached-operator-bundle:v0.0.1
  $ make bundle-build BUNDLE_IMG=$BUNDLE_IMG

  # The above recipe runs the following commands manually. First it creates bundle
  # manifests, metadata, and a bundle.Dockerfile:
  $ make manifests
  /home/user/go/bin/controller-gen "crd:trivialVersions=true" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
  $ operator-sdk generate kustomize manifests

  Display name for the operator (required):
  > memcached-operator
  ...

  $ tree config/manifests
  config/manifests
  ├── bases
  │   └── memcached-operator.clusterserviceversion.yaml
  └── kustomization.yaml
  $ kustomize build config/manifests | operator-sdk generate bundle --overwrite --version 0.0.1
  Generating bundle manifest version 0.0.1
  ...

  # After running the above commands, you should see this directory structure:
  $ tree bundle
  bundle
  ├── manifests
  │   ├── cache.my.domain_memcacheds.yaml
  │   └── memcached-operator.clusterserviceversion.yaml
  └── metadata
      └── annotations.yaml

  # Then it validates your bundle files and builds your bundle image:
  $ operator-sdk bundle validate ./bundle
  $ docker build -f bundle.Dockerfile -t $BUNDLE_IMG .
  Sending build context to Docker daemon  42.33MB
  Step 1/9 : FROM scratch
  ...

  # You can then push your bundle image:
  $ make docker-push IMG=$BUNDLE_IMG

Flags:
      --channels string          A comma-separated list of channels the bundle belongs to (default "alpha")
      --crds-dir string          Root directory for CustomResoureDefinition manifests
      --default-channel string   The default channel for the bundle
      --deploy-dir string        Root directory for operator manifests such as Deployments and RBAC, ex. 'deploy'. This directory is different from that passed to --input-dir
  -h, --help                     help for bundle
      --input-dir string         Directory to read an existing bundle from. This directory is the parent of your bundle 'manifests' directory, and different from --deploy-dir
      --kustomize-dir string     Directory containing kustomize bases and a kustomization.yaml for operator-framework manifests (default "config/manifests")
      --manifests                Generate bundle manifests
      --metadata                 Generate bundle metadata and Dockerfile
      --output-dir string        Directory to write the bundle to
      --overwrite                Overwrite the bundle's metadata and Dockerfile if they exist (default true)
  -q, --quiet                    Run in quiet mode
      --stdout                   Write bundle manifest to stdout
  -v, --version string           Semantic version of the operator in the generated bundle. Only set if creating a new bundle or upgrading your operator

Global Flags:
      --verbose   Enable verbose logging

The package name generated in the bundle.Dockerfile and bundle/metadata/annotations.yaml are the same as the projectName in the PROJECT file.

What did you expect to see?

I expect operator-sdk generate bundle can provide a tag for setting the package name as the opm command opm alpha bundle generate

➜  operand-deployment-lifecycle-manager git:(update-odlm-package-name) opm alpha bundle generate -h        The "opm alpha bundle generate" command will generate operator
        bundle metadata if needed and a Dockerfile to build Operator bundle image.

        $ opm alpha bundle generate --directory /test/0.1.0/ --package test-operator \
                --channels stable,beta --default stable

                Note:
                * All manifests yaml must be in the same directory.

Usage:
  opm alpha bundle generate [flags]

Flags:
  -c, --channels directory   The list of channels that bundle image belongs to(Required if directory is not pointing to a bundle in the nested bundle format)
  -e, --default string       The default channel for the bundle image
  -d, --directory string     The directory where bundle manifests for a specific version are located.
  -h, --help                 help for generate
  -u, --output-dir string    Optional output directory for operator manifests
  -p, --package directory    The name of the package that bundle image belongs to (Required if directory is not pointing to a bundle in the nested bundle format)

Global Flags:
      --skip-tls   skip TLS certificate verification for container image registries while pulling bundles or index

What did you see instead? Under which circumstances?

I have to manually update the package name after the bundle files are created.

Environment

Operator type:

go Operator

Kubernetes cluster type:

Openshift

$ operator-sdk version

operator-sdk version: "v1.0.1", commit: "4169b318b578156ed56530f373d328276d040a1b", kubernetes version: "v1.18.2", go version: "go1.15.2 darwin/amd64", GOOS: "darwin", GOARCH: "amd64"

$ go version (if language is Go)

go version go1.15.2 darwin/amd64

$ kubectl version

Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.8", GitCommit:"9f2892aab98fe339f3bd70e3c470144299398ace", GitTreeState:"clean", BuildDate:"2020-08-13T16:12:48Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"18+", GitVersion:"v1.18.3+47c0e71", GitCommit:"47c0e71", GitTreeState:"clean", BuildDate:"2020-09-17T23:10:07Z", GoVersion:"go1.13.4", Compiler:"gc", Platform:"linux/amd64"}

Possible Solution

Additional context

estroz commented 4 years ago

The package name generated in the bundle.Dockerfile and bundle/metadata/annotations.yaml are the same as the projectName in the PROJECT file.

This is by design since your PROJECT config should contain the name of your operator/package. Is the name of your package different from the name of your operator project?

We are going to be adding (back) an --operator-name flag (or similarly named) to generate subcommands, but the primary use case is for generating bundles outside of an operator project (i.e. when PROJECT is not available). Your PROJECT file really should contain projectName: <project and package name> to avoid ambiguity in other parts of the project.

/language go /triage support /assign

kumarrprashant2005 commented 3 years ago

@estroz In absence of such a flag, it becomes extremely difficult to create multiple bundles with different package names. This will be a common use-case for operators which have different package names for (upstream) community & Red Hat certified.

Also, if there was an option to just change the package name and not the CSV names, it would be helpful. Right now, the generated CSV file in the bundle default to the PROJECT name. This is required as most of the certified operators just change the package name (and not the CSV name) to differentiate from any existing community operators.

estroz commented 3 years ago

In that case, this is a duplicate of #3998 and is being worked on.

estroz commented 3 years ago

On further consideration, this isn't an exact duplicate of #3998, since that issue is asking for a --package-name flag so generate bundle can be run outside of a project. That flag would allow you to do part of what you want, since changing the package name would also change the CSV name (which is derived from project name).

@kumarrprashant2005 can you explain why changing your CSV name to align with package name is not desirable?

kumarrprashant2005 commented 3 years ago

@estroz Say if I have a certified operator already out there which has the CSV name which is different from package name (which I presume would be common as the recommendation was to just add the certified suffix to the package name), then this creates problems for upgrade. Once I migrate to the newer SDK, the CSV name would be different if I set the PROJECT to include the certified suffix. This new CSV can't "replace" my older CSV because they have different names now. So, an ability to set these the package name via an option with the generate command would be extremely helpful.

estroz commented 3 years ago

CSV name is meant to be unique, and whether the package name is used in the CSV name doesn't really matter. For example:

I have one CSV for package foo:

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  name: foo.v1.0.0

I create a new CSV for package foo with a higher version, then replace the old one:

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  name: foo.v1.0.1
spec:
  replaces: foo.v1.0.0

I also create a new CSV for package bar with a higher version and CSV name ~ package name, then replace the old foo one:

apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
  name: bar.v1.0.1
spec:
  replaces: foo.v1.0.0

As long as foo.v1.0.1 and bar.v1.0.1 are supplied to different indexes alongside foo.v1.0.0, the index will build fine. Does that clarify the situation, or are my assumptions about what you're asking off the mark? @kevinrizza @dinhxuanvu can you weigh in here?

dinhxuanvu commented 3 years ago

What Eric said is correct. The CSV name must be unique and using packagename.version schema is a popular choice to name the CSV that we've seen so far.

kumarrprashant2005 commented 3 years ago

@estroz @dinhxuanvu Thanks a lot for your clarification. I was not aware that you could replace a foo.v1.0.0 with a bar.v1.1.0 This eases some of the trouble while creating CSVs.

The problem with the separate bundles with separate package names still stand and an option to create one would help anyone with these problems.

I could technically create a separate bundle (with a different package name) with a combination of input-dir, output-dir flags & updating the package name by hand (in the Dockerfile & annotations). From this point onwards I can just use the --manifests instead of --overwrite option to just update the manifests (and not the bundle.Dockerfile & annotations). But this process is tedious and error prone and is difficult to maintain. If the operator-sdk just provided an option out of the box, then it would greatly help us.

estroz commented 3 years ago

I'm pretty sure this is taken care of by #4074. Feel free to re-open if not.