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
14 changes: 13 additions & 1 deletion cmd/operator-sdk/bundle/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type bundleCmd struct {
generateOnly bool
}

func NewCmd() *cobra.Command {
func newCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "bundle",
Short: "Manage operator bundle metadata",
Expand All @@ -44,10 +44,22 @@ More information about the integration with OLM via SDK:
https://sdk.operatorframework.io/docs/olm-integration/
`,
}
return cmd
}

Comment thread
estroz marked this conversation as resolved.
func NewCmdLegacy() *cobra.Command {
Comment thread
estroz marked this conversation as resolved.
cmd := newCmd()
cmd.AddCommand(
newCreateCmd(),
Comment thread
estroz marked this conversation as resolved.
newValidateCmd(),
)
return cmd
}

func NewCmd() *cobra.Command {
cmd := newCmd()
cmd.AddCommand(
newValidateCmd(),
)
return cmd
}
2 changes: 1 addition & 1 deletion cmd/operator-sdk/cli/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func GetCLIRoot() *cobra.Command {
add.NewCmd(),
alpha.NewCmd(),
build.NewCmd(),
bundle.NewCmd(),
bundle.NewCmdLegacy(),
Comment thread
estroz marked this conversation as resolved.
cleanup.NewCmd(),
completion.NewCmd(),
execentrypoint.NewCmd(),
Expand Down
72 changes: 72 additions & 0 deletions cmd/operator-sdk/generate/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,78 @@ import (
"github.com/operator-framework/operator-sdk/internal/generate/collector"
)

const (
//nolint:lll
examples = `
# Using the example 'memcached-operator' and assuming a directory structure
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.

Is required to add the tree? What value does it bring?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It isn't strictly necessary, although other commands show trees.

# similar to the following exists:
$ tree api/ config/
api/
└── v1alpha1
├── groupversion_info.go
├── memcached_types.go
└── zz_generated.deepcopy.go
config/
├── bundle
│   └── kustomization.yaml
├── crd
│   ├── bases
│   │   └── cache.my.domain_memcacheds.yaml
│   ├── kustomization.yaml
│   ├── kustomizeconfig.yaml
│   ...
├── default
│   ├── kustomization.yaml
│   ...
├── manager
│   ├── kustomization.yaml
│   └── manager.yaml
...

# 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
Comment thread
estroz marked this conversation as resolved.
/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 bundle -q --kustomize

Display name for the operator (required):
> memcached-operator
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.

Is required to add its output?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nope, just helps the user know what expected output should be. I can see this drifting from actual output though.

...

$ kustomize build config/bundle | operator-sdk generate bundle --manifests --metadata --overwrite --version 0.0.1
Generating bundle manifest version 0.0.1
...

# After running the above commands, you should see:
$ tree config/bundle
config/bundle
├── bases
│   └── memcached-operator.clusterserviceversion.yaml
├── kustomization.yaml
├── 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 config/bundle
$ docker build -f bundle.Dockerfile -t $BUNDLE_IMG .
Sending build context to Docker daemon 42.33MB
Step 1/9 : FROM scratch
Copy link
Copy Markdown
Contributor

@camilamacedo86 camilamacedo86 May 27, 2020

Choose a reason for hiding this comment

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

Is required to add the output?

...

# You can then push your bundle image:
$ make docker-push IMG=$BUNDLE_IMG
`
Comment thread
estroz marked this conversation as resolved.
)

Comment thread
estroz marked this conversation as resolved.
// setCommonDefaults sets defaults useful to all modes of this subcommand.
func (c *bundleCmd) setCommonDefaults(cfg *config.Config) {
if c.operatorName == "" {
Expand Down
52 changes: 51 additions & 1 deletion cmd/operator-sdk/generate/bundle/bundle_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,56 @@ import (
"github.com/operator-framework/operator-sdk/internal/util/projutil"
)

const (
examplesLegacy = `
# Using the example 'memcached-operator' and assuming a directory structure
# similar to the following exists:
$ tree pkg/apis/ deploy/
pkg/apis/
├── ...
└── cache
├── group.go
└── v1alpha1
├── ...
└── memcached_types.go
deploy/
├── crds
│   ├── cache.example.com_memcacheds_crd.yaml
│   └── cache.example.com_v1alpha1_memcached_cr.yaml
├── operator.yaml
├── role.yaml
├── role_binding.yaml
└── service_account.yaml

# Create bundle manifests, metadata, and a bundle.Dockerfile:
$ operator-sdk generate bundle --version 0.0.1
INFO[0000] Generating bundle manifest version 0.0.1

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

# After running the above commands, you should see:
$ tree deploy/olm-catalog
deploy/olm-catalog
└── memcached-operator
├── manifests
│ ├── cache.example.com_memcacheds_crd.yaml
│ └── memcached-operator.clusterserviceversion.yaml
└── metadata
└── annotations.yaml

# Then build and push your bundle image:
$ export USERNAME=<your registry username>
$ export BUNDLE_IMG=quay.io/$USERNAME/memcached-operator-bundle:v0.0.1
$ docker build -f bundle.Dockerfile -t $BUNDLE_IMG .
Sending build context to Docker daemon 42.33MB
Step 1/9 : FROM scratch
...
$ docker push $BUNDLE_IMG
`
)

// setCommonDefaultsLegacy sets defaults useful to all modes of this subcommand.
func (c *bundleCmd) setCommonDefaultsLegacy() {
if c.operatorName == "" {
Expand Down Expand Up @@ -58,7 +108,7 @@ func (c bundleCmd) runManifestsLegacy() (err error) {
if c.version == "" {
log.Info("Generating bundle manifests")
} else {
log.Info("Generating bundle manifests version", c.version)
log.Infoln("Generating bundle manifests version", c.version)
}
}

Expand Down
31 changes: 27 additions & 4 deletions cmd/operator-sdk/generate/bundle/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ import (
"github.com/operator-framework/operator-sdk/internal/util/projutil"
)

const (
longHelp = `
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, and will interactively ask
for UI metadata, an important component of publishing your operator, by default unless
a bundle for your operator exists or you set '--interactive=false'.

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
`
)

//nolint:maligned
type bundleCmd struct {
// Options to turn on different parts of bundling.
Expand Down Expand Up @@ -57,8 +76,10 @@ type bundleCmd struct {
func NewCmd() *cobra.Command {
c := &bundleCmd{}
cmd := &cobra.Command{
Use: "bundle",
Short: "Generates bundle data for the operator",
Use: "bundle",
Short: "Generates bundle data for the operator",
Long: longHelp,
Example: examples,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
Expand Down Expand Up @@ -138,8 +159,10 @@ func NewCmd() *cobra.Command {
func NewCmdLegacy() *cobra.Command {
c := &bundleCmd{}
cmd := &cobra.Command{
Use: "bundle",
Short: "Generates bundle data for the operator",
Use: "bundle",
Short: "Generates bundle data for the operator",
Long: longHelp,
Example: examplesLegacy,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 0 {
return fmt.Errorf("command %s doesn't accept any arguments", cmd.CommandPath())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func readClusterServiceVersionBase(path string) (*v1alpha1.ClusterServiceVersion
if typeMeta.Kind == v1alpha1.ClusterServiceVersionKind {
csv := &v1alpha1.ClusterServiceVersion{}
if err := yaml.Unmarshal(manifest, csv); err != nil {
return nil, fmt.Errorf("error unmarshalling ClusterServiceVersion from manifest %s: %v", path, err)
return nil, fmt.Errorf("error unmarshaling ClusterServiceVersion from manifest %s: %v", path, err)
}
return csv, nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ func validate(csv *operatorsv1alpha1.ClusterServiceVersion) error {
if csv == nil {
return errors.New("empty ClusterServiceVersion")
}

hasErrors := false
results := validation.ClusterServiceVersionValidator.Validate(csv)
for _, r := range results {
for _, w := range r.Warnings {
Expand All @@ -323,8 +325,13 @@ func validate(csv *operatorsv1alpha1.ClusterServiceVersion) error {
log.Errorf("ClusterServiceVersion validation: [%s] %s", e.Type, e.Detail)
}
if r.HasError() {
return errors.New("got ClusterServiceVersion validation errors")
hasErrors = true
}
}
Comment thread
estroz marked this conversation as resolved.

if hasErrors {
return errors.New("generated ClusterServiceVersion is invalid")
}

return nil
}
3 changes: 0 additions & 3 deletions internal/generate/olm-catalog/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ import (
"sigs.k8s.io/yaml"
)

// KB_INTEGRATION_TODO(estroz): generate these using kustomize and pass
// from stdin, like 'make deploy'.

const (
OLMCatalogChildDir = "olm-catalog"
// OLMCatalogDir is the default location for OLM catalog directory.
Expand Down
29 changes: 29 additions & 0 deletions internal/plugins/golang/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,22 @@
package golang

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

"github.com/operator-framework/operator-sdk/internal/scaffold/kustomize"

"github.com/spf13/pflag"
"sigs.k8s.io/kubebuilder/pkg/model/config"
"sigs.k8s.io/kubebuilder/pkg/plugin"
)

// sampleKustomizationFragment is a template for samples/kustomization.yaml.
const sampleKustomizationFragment = `## This file is auto-generated, do not modify ##
resources:
`

type createAPIPlugin struct {
plugin.CreateAPI

Expand Down Expand Up @@ -52,5 +63,23 @@ func (p *createAPIPlugin) Run() error {

// SDK plugin-specific scaffolds.
func (p *createAPIPlugin) run() error {

// Write CR paths to the samples' kustomization file. This file has a
// "do not modify" comment so it is safe to overwrite.
samplesKustomization := sampleKustomizationFragment
for _, gvk := range p.config.Resources {
samplesKustomization += fmt.Sprintf("- %s\n", makeCRFileName(gvk))
}
kpath := filepath.Join("config", "samples")
if err := kustomize.Write(kpath, samplesKustomization); err != nil {
return err
}
Comment thread
camilamacedo86 marked this conversation as resolved.

return nil
}

// makeCRFileName returns a Custom Resource example file name in the same format
// as kubebuilder's CreateAPI plugin for a gvk.
func makeCRFileName(gvk config.GVK) string {
return fmt.Sprintf("%s_%s_%s.yaml", gvk.Group, gvk.Version, strings.ToLower(gvk.Kind))
}
Loading