Skip to content
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Added

- Added [`run`](./doc/cli/operator-sdk_alpha_run.md) and [`cleanup`](./doc/cli/operator-sdk_alpha_cleanup.md) subcommands (under the `alpha` subcommand) to manage deployment/deletion of operators. These commands currently interact with OLM via an in-cluster registry-server created using an operator's on-disk manifests and managed by `operator-sdk`. ([#2402](ttps://github.com/operator-framework/operator-sdk/pull/2402))
- Added [`bundle build`](./doc/cli/operator-sdk_alpha_bundle_build.md) (under the `alpha` subcommand) which builds, and optionally generates metadata for, [operator bundle images](https://github.com/openshift/enhancements/blob/ec2cf96/enhancements/olm/operator-registry.md). ([#2076](https://github.com/operator-framework/operator-sdk/pull/2076))

### Changed

Expand Down
129 changes: 129 additions & 0 deletions cmd/operator-sdk/alpha/bundle/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2020 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bundle

import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"

catalog "github.com/operator-framework/operator-sdk/internal/scaffold/olm-catalog"
"github.com/operator-framework/operator-sdk/internal/util/projutil"

"github.com/operator-framework/operator-registry/pkg/lib/bundle"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

// newBundleBuildCmd returns a command that will build operator bundle image.
func newBundleBuildCmd() *cobra.Command {
c := bundleCmd{}
cmd := &cobra.Command{
Use: "build",
Short: "Build an operator bundle image",
Long: `The 'operator-sdk bundle build' command will build an operator
bundle image containing operator metadata and manifests, tagged with the
provided image tag.

To write metadata and a bundle image Dockerfile to disk, set '--generate-only=true'.
Bundle metadata will be generated in <directory-arg>/metadata, and the Dockerfile
in <directory-arg>. This flag is useful if you want to build an operator's
bundle image manually or modify metadata before building an image.

More information on operator bundle images and metadata:
https://github.com/openshift/enhancements/blob/master/enhancements/olm/operator-bundle.md#docker

NOTE: bundle images are not runnable.`,
Example: `The following invocation will build a test-operator bundle image using Docker.
This image will contain manifests for package channels 'stable' and 'beta':

$ operator-sdk bundle build quay.io/example/test-operator:v0.1.0 \
--directory ./deploy/olm-catalog/test-operator \
--package test-operator \
--channels stable,beta \
--default-channel stable

Assuming your operator has the same name as your operator and the only channel
is 'stable', the above command can be abbreviated to:

$ operator-sdk bundle build quay.io/example/test-operator:v0.1.0

The following invocation will generate test-operator bundle metadata and
Dockerfile without building the image:

$ operator-sdk bundle build \
--generate-only \
--directory ./deploy/olm-catalog/test-operator \
--package test-operator \
--channels stable,beta \
--default-channel stable`,
RunE: func(cmd *cobra.Command, args []string) error {
channels := strings.Join(c.channels, ",")
if c.generateOnly {
if len(args) != 0 {
return fmt.Errorf("command %s does not accept any arguments", cmd.CommandPath())
}
err := bundle.GenerateFunc(c.directory, c.packageName, channels,
c.defaultChannel, true)
if err != nil {
log.Fatalf("Error generating bundle image files: %v", err)
}
return nil
}
// An image tag is required for build only.
if len(args) != 1 {
return errors.New("a bundle image tag is a required argument, ex. example.com/test-operator:v0.1.0")
}
c.imageTag = args[0]
// Clean up transient metadata and Dockerfile once the image is built,
// as they are no longer needed.
for _, cleanup := range c.cleanupFuncs() {
defer cleanup()
}
// Build but never overwrite existing metadata/Dockerfile.
err := bundle.BuildFunc(c.directory, c.imageTag, c.imageBuilder,
c.packageName, channels, c.defaultChannel, false)
if err != nil {
log.Fatalf("Error building bundle image: %v", err)
}
return nil
},
}

// Set up default values.
projectName := filepath.Base(projutil.MustGetwd())
defaultDir := ""
if _, err := os.Stat(catalog.OLMCatalogDir); err == nil || os.IsExist(err) {
defaultDir = filepath.Join(catalog.OLMCatalogDir, projectName)
}
defaultChannels := []string{"stable"}

cmd.Flags().StringVarP(&c.directory, "directory", "d", defaultDir,
"The directory where bundle manifests are located")
cmd.Flags().StringVarP(&c.packageName, "package", "p", projectName,
"The name of the package that bundle image belongs to. Set if package name differs from project name")
cmd.Flags().StringSliceVarP(&c.channels, "channels", "c", defaultChannels,
"The list of channels that bundle image belongs to")
cmd.Flags().BoolVarP(&c.generateOnly, "generate-only", "g", false,
"Generate metadata and a Dockerfile on disk without building the bundle image")
cmd.Flags().StringVarP(&c.imageBuilder, "image-builder", "b", "docker",
"Tool to build container images. One of: [docker, podman, buildah]")
cmd.Flags().StringVarP(&c.defaultChannel, "default-channel", "e", "",
"The default channel for the bundle image")

return cmd
}
74 changes: 74 additions & 0 deletions cmd/operator-sdk/alpha/bundle/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2020 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package bundle

import (
"os"
"path/filepath"

"github.com/operator-framework/operator-registry/pkg/lib/bundle"
"github.com/spf13/cobra"
)

func NewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "bundle",
Short: "Work with operator bundle metadata and bundle images",
Long: `Generate operator bundle metadata and build operator bundle images, which
are used to manage operators in the Operator Lifecycle Manager.

More information on operator bundle images and metadata:
https://github.com/openshift/enhancements/blob/master/enhancements/olm/operator-bundle.md#docker`,
}

cmd.AddCommand(newBundleBuildCmd())
return cmd
}

type bundleCmd struct {
directory string
packageName string
imageTag string
imageBuilder string
defaultChannel string
channels []string
generateOnly bool
}

// cleanupFuncs returns a set of general funcs to clean up after a bundle
// subcommand.
func (c bundleCmd) cleanupFuncs() (fs []func()) {
metaDir := filepath.Join(c.directory, bundle.MetadataDir)
dockerFile := filepath.Join(c.directory, bundle.DockerFile)
metaExists := isExist(metaDir)
dockerFileExists := isExist(dockerFile)
fs = append(fs,
func() {
if !metaExists {
_ = os.RemoveAll(metaDir)
}
},
func() {
if !dockerFileExists {
_ = os.RemoveAll(dockerFile)
}
})
return fs
}

func isExist(path string) bool {
_, err := os.Stat(path)
return os.IsExist(err)
}
2 changes: 2 additions & 0 deletions cmd/operator-sdk/alpha/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package alpha

import (
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/bundle"
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/cleanup"
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/kubebuilder"
"github.com/operator-framework/operator-sdk/cmd/operator-sdk/alpha/olm"
Expand All @@ -34,6 +35,7 @@ func NewCmd() *cobra.Command {
kubebuilder.NewCmd(),
run.NewCmd(),
cleanup.NewCmd(),
bundle.NewCmd(),
Copy link
Member

Choose a reason for hiding this comment

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

We need to pretty quickly decide where to put the OLM integration subcommands in the CLI. I think alpha is probably okay for this PR, but we'll need a follow-up on the heels of this to promote these OLM alpha subcommands.

)
return cmd
}
1 change: 1 addition & 0 deletions doc/cli/operator-sdk_alpha.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Run an alpha subcommand
### SEE ALSO

* [operator-sdk](operator-sdk.md) - An SDK for building operators with ease
* [operator-sdk alpha bundle](operator-sdk_alpha_bundle.md) - Work with operator bundle metadata and bundle images
* [operator-sdk alpha cleanup](operator-sdk_alpha_cleanup.md) - Delete and clean up after a running Operator
* [operator-sdk alpha olm](operator-sdk_alpha_olm.md) - Manage the Operator Lifecycle Manager installation in your cluster
* [operator-sdk alpha run](operator-sdk_alpha_run.md) - Run an Operator in a variety of environments
Expand Down
23 changes: 23 additions & 0 deletions doc/cli/operator-sdk_alpha_bundle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## operator-sdk alpha bundle

Work with operator bundle metadata and bundle images

### Synopsis

Generate operator bundle metadata and build operator bundle images, which
are used to manage operators in the Operator Lifecycle Manager.

More information on operator bundle images and metadata:
https://github.com/openshift/enhancements/blob/master/enhancements/olm/operator-bundle.md#docker

### Options

```
-h, --help help for bundle
```

### SEE ALSO

* [operator-sdk alpha](operator-sdk_alpha.md) - Run an alpha subcommand
* [operator-sdk alpha bundle build](operator-sdk_alpha_bundle_build.md) - Build an operator bundle image

68 changes: 68 additions & 0 deletions doc/cli/operator-sdk_alpha_bundle_build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## operator-sdk alpha bundle build

Build an operator bundle image

### Synopsis

The 'operator-sdk bundle build' command will build an operator
bundle image containing operator metadata and manifests, tagged with the
provided image tag.

To write metadata and a bundle image Dockerfile to disk, set '--generate-only=true'.
Bundle metadata will be generated in <directory-arg>/metadata, and the Dockerfile
in <directory-arg>. This flag is useful if you want to build an operator's
bundle image manually or modify metadata before building an image.

More information on operator bundle images and metadata:
https://github.com/openshift/enhancements/blob/master/enhancements/olm/operator-bundle.md#docker

NOTE: bundle images are not runnable.

```
operator-sdk alpha bundle build [flags]
```

### Examples

```
The following invocation will build a test-operator bundle image using Docker.
This image will contain manifests for package channels 'stable' and 'beta':

$ operator-sdk bundle build quay.io/example/test-operator:v0.1.0 \
--directory ./deploy/olm-catalog/test-operator \
--package test-operator \
--channels stable,beta \
--default-channel stable

Assuming your operator has the same name as your operator and the only channel
is 'stable', the above command can be abbreviated to:

$ operator-sdk bundle build quay.io/example/test-operator:v0.1.0

The following invocation will generate test-operator bundle metadata and
Dockerfile without building the image:

$ operator-sdk bundle build \
--generate-only \
--directory ./deploy/olm-catalog/test-operator \
--package test-operator \
--channels stable,beta \
--default-channel stable
```

### Options

```
-c, --channels strings The list of channels that bundle image belongs to (default [stable])
-e, --default-channel string The default channel for the bundle image
-d, --directory string The directory where bundle manifests are located
-g, --generate-only Generate metadata and a Dockerfile on disk without building the bundle image
-h, --help help for build
-b, --image-builder string Tool to build container images. One of: [docker, podman, buildah] (default "docker")
-p, --package string The name of the package that bundle image belongs to. Set if package name differs from project name (default "operator-sdk")
```

### SEE ALSO

* [operator-sdk alpha bundle](operator-sdk_alpha_bundle.md) - Work with operator bundle metadata and bundle images