Skip to content

Commit ee575b1

Browse files
committedOct 27, 2019
Clean up minor issues with command-line code and documentation
1. Clarify a few helper texts in cli code 2. Improve librar document to specific input information 3. Move `bundle` comands under hidden `alpha` command Signed-off-by: Vu Dinh <[email protected]>
1 parent 9762fd5 commit ee575b1

File tree

9 files changed

+163
-88
lines changed

9 files changed

+163
-88
lines changed
 

‎cmd/opm/bundle/build.go ‎cmd/opm/alpha/bundle/build.go

+28-8
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ import (
77
)
88

99
var (
10-
dirBuildArgs string
11-
tagBuildArgs string
12-
imageBuilderArgs string
10+
dirBuildArgs string
11+
tagBuildArgs string
12+
imageBuilderArgs string
13+
packageNameArgs string
14+
channelsArgs string
15+
channelDefaultArgs string
16+
overwriteArgs bool
1317
)
1418

1519
// newBundleBuildCmd returns a command that will build operator bundle image.
1620
func newBundleBuildCmd() *cobra.Command {
1721
bundleBuildCmd := &cobra.Command{
1822
Use: "build",
1923
Short: "Build operator bundle image",
20-
Long: `The opm bundle build command will generate operator
24+
Long: `The "opm alpha bundle build" command will generate operator
2125
bundle metadata if needed and build bundle image with operator manifest
2226
and metadata.
2327
@@ -29,30 +33,46 @@ func newBundleBuildCmd() *cobra.Command {
2933
After the build process is completed, a container image would be built
3034
locally in docker and available to push to a container registry.
3135
32-
$ opm bundle build -dir /test/0.0.1/ -t quay.io/example/operator:v0.0.1
36+
$ opm alpha bundle build --directory /test/ --tag quay.io/example/operator:v0.1.0 \
37+
--package test-operator --channels stable,beta --default stable --overwrite
3338
3439
Note: Bundle image is not runnable.
3540
`,
3641
RunE: buildFunc,
3742
}
3843

39-
bundleBuildCmd.Flags().StringVarP(&dirBuildArgs, "directory", "d", "", "The directory where bundle manifests are located.")
44+
bundleBuildCmd.Flags().StringVarP(&dirBuildArgs, "directory", "d", "", "The directory where bundle manifests and metadata are located")
4045
if err := bundleBuildCmd.MarkFlagRequired("directory"); err != nil {
4146
log.Fatalf("Failed to mark `directory` flag for `build` subcommand as required")
4247
}
4348

44-
bundleBuildCmd.Flags().StringVarP(&tagBuildArgs, "tag", "t", "", "The name of the bundle image will be built.")
49+
bundleBuildCmd.Flags().StringVarP(&tagBuildArgs, "tag", "t", "", "The image tag applied to the bundle image")
4550
if err := bundleBuildCmd.MarkFlagRequired("tag"); err != nil {
4651
log.Fatalf("Failed to mark `tag` flag for `build` subcommand as required")
4752
}
4853

54+
bundleBuildCmd.Flags().StringVarP(&packageNameArgs, "package", "p", "", "The name of the package that bundle image belongs to")
55+
if err := bundleBuildCmd.MarkFlagRequired("package"); err != nil {
56+
log.Fatalf("Failed to mark `package` flag for `build` subcommand as required")
57+
}
58+
59+
bundleBuildCmd.Flags().StringVarP(&channelsArgs, "channels", "c", "", "The list of channels that bundle image belongs to")
60+
if err := bundleBuildCmd.MarkFlagRequired("channels"); err != nil {
61+
log.Fatalf("Failed to mark `channels` flag for `build` subcommand as required")
62+
}
63+
4964
bundleBuildCmd.Flags().StringVarP(&imageBuilderArgs, "image-builder", "b", "docker", "Tool to build container images. One of: [docker, podman, buildah]")
5065

66+
bundleBuildCmd.Flags().StringVarP(&channelDefaultArgs, "default", "e", "", "The default channel for the bundle image")
67+
68+
bundleBuildCmd.Flags().BoolVarP(&overwriteArgs, "overwrite", "o", false, "To overwrite annotations.yaml locally if existed. By default, overwrite is set to `false`.")
69+
5170
return bundleBuildCmd
5271
}
5372

5473
func buildFunc(cmd *cobra.Command, args []string) error {
55-
err := bundle.BuildFunc(dirBuildArgs, tagBuildArgs, imageBuilderArgs)
74+
err := bundle.BuildFunc(dirBuildArgs, tagBuildArgs, imageBuilderArgs,
75+
packageNameArgs, channelsArgs, channelDefaultArgs, overwriteArgs)
5676
if err != nil {
5777
return err
5878
}

‎cmd/opm/bundle/cmd.go ‎cmd/opm/alpha/bundle/cmd.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import (
66

77
func NewCmd() *cobra.Command {
88
runCmd := &cobra.Command{
9-
Hidden: true,
10-
Use: "bundle",
11-
Short: "Operator bundle commands",
12-
Long: `Generate operator bundle metadata and build bundle image.`,
9+
Use: "bundle",
10+
Short: "Operator bundle commands",
11+
Long: `Generate operator bundle metadata and build bundle image.`,
1312
}
1413

1514
runCmd.AddCommand(newBundleGenerateCmd())

‎cmd/opm/alpha/bundle/generate.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package bundle
2+
3+
import (
4+
"github.com/operator-framework/operator-registry/pkg/lib/bundle"
5+
log "github.com/sirupsen/logrus"
6+
"github.com/spf13/cobra"
7+
)
8+
9+
// newBundleGenerateCmd returns a command that will generate operator bundle
10+
// annotations.yaml metadata
11+
func newBundleGenerateCmd() *cobra.Command {
12+
bundleGenerateCmd := &cobra.Command{
13+
Use: "generate",
14+
Short: "Generate operator bundle metadata and Dockerfile",
15+
Long: `The "opm alpha bundle generate" command will generate operator
16+
bundle metadata if needed and a Dockerfile to build Operator bundle image.
17+
18+
$ opm alpha bundle generate --directory /test/ --package test-operator \
19+
--channels stable,beta --default stable
20+
`,
21+
RunE: generateFunc,
22+
}
23+
24+
bundleGenerateCmd.Flags().StringVarP(&dirBuildArgs, "directory", "d", "", "The directory where bundle manifests are located.")
25+
if err := bundleGenerateCmd.MarkFlagRequired("directory"); err != nil {
26+
log.Fatalf("Failed to mark `directory` flag for `generate` subcommand as required")
27+
}
28+
29+
bundleGenerateCmd.Flags().StringVarP(&packageNameArgs, "package", "p", "", "The name of the package that bundle image belongs to")
30+
if err := bundleGenerateCmd.MarkFlagRequired("package"); err != nil {
31+
log.Fatalf("Failed to mark `package` flag for `generate` subcommand as required")
32+
}
33+
34+
bundleGenerateCmd.Flags().StringVarP(&channelsArgs, "channels", "c", "", "The list of channels that bundle image belongs to")
35+
if err := bundleGenerateCmd.MarkFlagRequired("channels"); err != nil {
36+
log.Fatalf("Failed to mark `channels` flag for `generate` subcommand as required")
37+
}
38+
39+
bundleGenerateCmd.Flags().StringVarP(&channelDefaultArgs, "default", "e", "", "The default channel for the bundle image")
40+
41+
return bundleGenerateCmd
42+
}
43+
44+
func generateFunc(cmd *cobra.Command, args []string) error {
45+
err := bundle.GenerateFunc(dirBuildArgs, packageNameArgs, channelsArgs, channelDefaultArgs, true)
46+
if err != nil {
47+
return err
48+
}
49+
50+
return nil
51+
}

‎cmd/opm/alpha/cmd.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package alpha
2+
3+
import (
4+
"github.com/operator-framework/operator-registry/cmd/opm/alpha/bundle"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func NewCmd() *cobra.Command {
9+
runCmd := &cobra.Command{
10+
Hidden: true,
11+
Use: "alpha",
12+
Short: "Run an alpha subcommand",
13+
}
14+
15+
runCmd.AddCommand(bundle.NewCmd())
16+
return runCmd
17+
}

‎cmd/opm/bundle/generate.go

-59
This file was deleted.

‎cmd/opm/main.go

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package main
22

33
import (
4+
"os"
5+
46
"github.com/sirupsen/logrus"
57
"github.com/spf13/cobra"
68

7-
"github.com/operator-framework/operator-registry/cmd/opm/bundle"
9+
"github.com/operator-framework/operator-registry/cmd/opm/alpha"
810
"github.com/operator-framework/operator-registry/cmd/opm/registry"
911
)
1012

@@ -13,12 +15,23 @@ func main() {
1315
Use: "opm",
1416
Short: "operator package manager",
1517
Long: "CLI to interact with operator-registry and build indexes of operator content",
18+
PreRunE: func(cmd *cobra.Command, args []string) error {
19+
if debug, _ := cmd.Flags().GetBool("debug"); debug {
20+
logrus.SetLevel(logrus.DebugLevel)
21+
}
22+
return nil
23+
},
1624
}
1725

1826
rootCmd.AddCommand(registry.NewOpmRegistryCmd())
19-
rootCmd.AddCommand(bundle.NewCmd())
27+
rootCmd.AddCommand(alpha.NewCmd())
2028

21-
if err := rootCmd.Execute(); err != nil {
29+
rootCmd.Flags().Bool("debug", false, "enable debug logging")
30+
if err := rootCmd.Flags().MarkHidden("debug"); err != nil {
2231
logrus.Panic(err.Error())
2332
}
33+
34+
if err := rootCmd.Execute(); err != nil {
35+
os.Exit(1)
36+
}
2437
}

‎docs/design/operator-bundle.md

+29-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
overwrite# Operator Bundle
1+
# Operator Bundle
22

33
An `Operator Bundle` is a container image that stores Kubernetes manifests and metadata associated with an operator. A bundle is meant to present a *specific* version of an operator.
44

@@ -18,19 +18,27 @@ An `Operator Bundle` is built as a scratch (non-runnable) container image that c
1818
### Bundle Annotations
1919

2020
We use the following labels to annotate the operator bundle image.
21-
* The label `operators.operatorframework.io.bundle.resources` represents the bundle type:
22-
* The value `manifests` implies that this bundle contains operator manifests only.
23-
* The value `metadata` implies that this bundle has operator metadata only.
24-
* The value `manifests+metadata` implies that this bundle contains both operator metadata and manifests.
25-
* The label `operators.operatorframework.io.bundle.mediatype` reflects the media type or format of the operator bundle. It could be helm charts, plain Kubernetes manifests etc.
21+
* The label `operators.operatorframework.io.bundle.mediatype.v1` reflects the media type or format of the operator bundle. It could be helm charts, plain Kubernetes manifests etc.
22+
* The label `operators.operatorframework.io.bundle.manifests.v1 `reflects the path in the image to the directory that contains the operator manifests.
23+
* The label `operators.operatorframework.io.bundle.metadata.v1` reflects the path in the image to the directory that contains metadata files about the bundle.
24+
* The `manifests.v1` and `metadata.v1` labels imply the bundle type:
25+
* The value `manifests.v1` implies that this bundle contains operator manifests.
26+
* The value `metadata.v1` implies that this bundle has operator metadata.
27+
* The label `operators.operatorframework.io.bundle.package.v1` reflects the package name of the bundle.
28+
* The label `operators.operatorframework.io.bundle.channels.v1` reflects the list of channels the bundle is subscribing to when added into an operator registry
29+
* The label `operators.operatorframework.io.bundle.channel.default.v1` reflects the default channel an operator should be subscribed to when installed from a registry
2630

2731
The labels will also be put inside a YAML file, as shown below.
2832

2933
*annotations.yaml*
3034
```yaml
3135
annotations:
32-
operators.operatorframework.io.bundle.resources: "manifests+metadata"
33-
operators.operatorframework.io.bundle.mediatype: "registry+v1"
36+
operators.operatorframework.io.bundle.mediatype.v1: "registry+v1"
37+
operators.operatorframework.io.bundle.manifests.v1: "manifests/"
38+
operators.operatorframework.io.bundle.metadata.v1: "metadata/"
39+
operators.operatorframework.io.bundle.package.v1: "test-operator"
40+
operators.operatorframework.io.bundle.channels.v1: "beta,stable"
41+
operators.operatorframework.io.bundle.channel.default.v1: "stable"
3442
```
3543
3644
*Notes:*
@@ -57,11 +65,15 @@ FROM scratch
5765

5866
# We are pushing an operator-registry bundle
5967
# that has both metadata and manifests.
60-
LABEL operators.operatorframework.io.bundle.resources=manifests+metadata
61-
LABEL operators.operatorframework.io.bundle.mediatype=registry+v1
68+
LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1
69+
LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
70+
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
71+
LABEL operators.operatorframework.io.bundle.package.v1=test-operator
72+
LABEL operators.operatorframework.io.bundle.channels.v1=beta,stable
73+
LABEL operators.operatorframework.io.bundle.channel.default.v1=stable
6274

6375
ADD test/*.yaml /manifests
64-
ADD test/annotations.yaml /metadata/annotations.yaml
76+
ADD test/metadata/annotations.yaml /metadata/annotations.yaml
6577
```
6678
6779
Below is the directory layout of the operator bundle inside the image:
@@ -126,7 +138,8 @@ The `--directory/-d`, `--channels/-c`, `--package/-p` are required flags while `
126138

127139
The command for `generate` task is:
128140
```bash
129-
$ ./operator-sdk bundle generate --directory /test --package test-operator --channels stable,beta --default stable
141+
$ ./operator-sdk bundle generate --directory /test --package test-operator \
142+
--channels stable,beta --default stable
130143
```
131144

132145
The `--directory` or `-d` specifies the directory where the operator manifests are located. The `Dockerfile` is generated in the same directory where the YAML manifests are located while the `annotations.yaml` file is located in a folder named `metadata`. For example:
@@ -166,14 +179,16 @@ Flags:
166179
167180
The command for `build` task is:
168181
```bash
169-
$ ./operator-sdk bundle build --directory /test --tag quay.io/coreos/test-operator.v0.1.0:latest --package test-operator --channels stable,beta --default stable
182+
$ ./operator-sdk bundle build --directory /test --tag quay.io/coreos/test-operator.v0.1.0:latest \
183+
--package test-operator --channels stable,beta --default stable
170184
```
171185
172186
The `--directory` or `-d` specifies the directory where the operator manifests are located. The `--tag` or `-t` specifies the image tag that you want the operator bundle image to have. By using `build` command, the `annotations.yaml` and `Dockerfile` are automatically generated in the background.
173187
174188
The default image builder is `Docker`. However, ` Buildah` and `Podman` are also supported. An image builder can specified via `--image-builder` or `-b` optional tag in `build` command. For example:
175189
```bash
176-
$ ./operator-sdk bundle build --directory /test/0.1.0/ --tag quay.io/coreos/test-operator.v0.1.0:latest --image-builder podman --package test-operator --channels stable,beta --default stable
190+
$ ./operator-sdk bundle build --directory /test/0.1.0/ --tag quay.io/coreos/test-operator.v0.1.0:latest \
191+
--image-builder podman --package test-operator --channels stable,beta --default stable
177192
```
178193
179194
The `--package` or `-p` is the name of package fo the operator such as `etcd` which which map `channels` to a particular application definition. `channels` allow package authors to write different upgrade paths for different users (e.g. `beta` vs. `stable`). The `channels` list is provided via `--channels` or `-c` flag. Multiple `channels` are separated by a comma (`,`). The default channel is provided optionally via `--default` or `-e` flag. If the default channel is not provided, the first channel in channel list is selected as default.

‎pkg/lib/bundle/build.go

+13
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ func ExecuteCommand(cmd *exec.Cmd) error {
4040
return nil
4141
}
4242

43+
// BuildFunc is used to build bundle container image from a list of manifests
44+
// that exist in local directory and it also generates Dockerfile annotations.yaml
45+
// which contains media type, package name and channels information if the file
46+
// doesn't exist locally.
47+
// Inputs:
48+
// @directory: The local directory where bundle manifests and metadata are located
49+
// @imageTag: The image tag that is applied to the bundle image
50+
// @imageBuilder: The image builder tool that is used to build container image
51+
// (docker, buildah or podman)
52+
// @packageName: The name of the package that bundle image belongs to
53+
// @channels: The list of channels that bundle image belongs to
54+
// @channelDefault: The default channel for the bundle image
55+
// @overwrite: Boolean flag to enable overwriting annotations.yaml locally if existed
4356
func BuildFunc(directory, imageTag, imageBuilder, packageName, channels, channelDefault string, overwrite bool) error {
4457
// Generate annotations.yaml and Dockerfile
4558
err := GenerateFunc(directory, packageName, channels, channelDefault, overwrite)

‎pkg/lib/bundle/generate.go

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ type AnnotationMetadata struct {
3636
// GenerateFunc builds annotations.yaml with mediatype, manifests &
3737
// metadata directories in bundle image, package name, channels and default
3838
// channels information and then writes the file to `/metadata` directory.
39+
// Inputs:
40+
// @directory: The local directory where bundle manifests and metadata are located
41+
// @packageName: The name of the package that bundle image belongs to
42+
// @channels: The list of channels that bundle image belongs to
43+
// @channelDefault: The default channel for the bundle image
44+
// @overwrite: Boolean flag to enable overwriting annotations.yaml locally if existed
3945
func GenerateFunc(directory, packageName, channels, channelDefault string, overwrite bool) error {
4046
var mediaType string
4147

0 commit comments

Comments
 (0)
Please sign in to comment.