Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate (new CLI): change default output dirs #3257

Merged
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
120 changes: 43 additions & 77 deletions cmd/operator-sdk/generate/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,27 @@ import (
genutil "github.com/operator-framework/operator-sdk/cmd/operator-sdk/generate/internal"
gencsv "github.com/operator-framework/operator-sdk/internal/generate/clusterserviceversion"
"github.com/operator-framework/operator-sdk/internal/generate/collector"
"github.com/operator-framework/operator-sdk/internal/scaffold/kustomize"
"github.com/operator-framework/operator-sdk/internal/util/projutil"
)

//nolint:lll
const examples = `
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.
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
`

//nolint:lll
examples = `
# Generate bundle files and build your bundle image with these 'make' recipes:
$ make bundle
$ export USERNAME=<your registry username>
Expand All @@ -42,30 +58,32 @@ const examples = `
# 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 bundle -q --kustomize
$ operator-sdk generate kustomize manifests

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

$ kustomize build config/bundle | operator-sdk generate bundle --manifests --metadata --overwrite --version 0.0.1
$ 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:
$ tree config/bundle
config/bundle
├── bases
│   └── memcached-operator.clusterserviceversion.yaml
├── kustomization.yaml
# 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 config/bundle
$ 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
Expand All @@ -74,15 +92,10 @@ const examples = `
# You can then push your bundle image:
$ make docker-push IMG=$BUNDLE_IMG
`
)

// kustomization.yaml file contents for manifests. This should always be written to
// config/bundle/kustomization.yaml since it only references files in config.
const manifestsKustomization = `resources:
- ../default
- ../samples
`

var defaultDir = filepath.Join("config", "bundle")
// defaultRootDir is the default root directory in which to generate bundle files.
const defaultRootDir = "bundle"

// setCommonDefaults sets defaults useful to all modes of this subcommand.
func (c *bundleCmd) setCommonDefaults(cfg *config.Config) {
Expand All @@ -96,51 +109,6 @@ func (c *bundleCmd) setCommonDefaults(cfg *config.Config) {
}
}

// runKustomize generates kustomize bundle bases.
func (c bundleCmd) runKustomize(cfg *config.Config) error {

if !c.quiet {
fmt.Println("Generating bundle manifest kustomize bases")
}

if c.inputDir == "" {
c.inputDir = defaultDir
}
if c.outputDir == "" {
c.outputDir = defaultDir
}
if c.apisDir == "" {
if cfg.MultiGroup {
c.apisDir = "apis"
} else {
c.apisDir = "api"
}
}

csvGen := gencsv.Generator{
OperatorName: c.operatorName,
OperatorType: genutil.PluginKeyToOperatorType(cfg.Layout),
}
opts := []gencsv.Option{
gencsv.WithBase(c.inputDir, c.apisDir, c.interactiveLevel),
gencsv.WithBaseWriter(c.outputDir),
}
if err := csvGen.Generate(cfg, opts...); err != nil {
return fmt.Errorf("error generating ClusterServiceVersion: %v", err)
}

// Write a kustomization.yaml to the config directory.
if err := kustomize.Write(defaultDir, manifestsKustomization); err != nil {
return err
}

if !c.quiet {
fmt.Println("Bases generated successfully in", c.outputDir)
}

return nil
}

// validateManifests validates c for bundle manifests generation.
func (c bundleCmd) validateManifests(*config.Config) (err error) {
if c.version != "" {
Expand All @@ -149,6 +117,10 @@ func (c bundleCmd) validateManifests(*config.Config) (err error) {
}
}

if c.kustomizeDir == "" {
return errors.New("--kustomize-dir must be set")
Comment on lines +120 to +121
Copy link
Contributor

Choose a reason for hiding this comment

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

So --kustomize-dir seems to be a required flag now. Unless it should be defaulted to config/manifests.
Can we mark it as such, and also I didn't see it used in the example text:

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

Copy link
Member Author

@estroz estroz Jun 19, 2020

Choose a reason for hiding this comment

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

This flag is required but defaults to config/manifests.

Copy link
Member

Choose a reason for hiding this comment

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

Just double checking. It is required in the sense that it can't be empty, but not required in the sense that it doesn't have to be provided on the command line?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct, much like --deploy-dir in the legacy CLI.

}

if !genutil.IsPipeReader() {
if c.deployDir == "" {
return errors.New("--deploy-dir must be set if not reading from stdin")
Expand Down Expand Up @@ -179,19 +151,11 @@ func (c bundleCmd) runManifests(cfg *config.Config) (err error) {
}

if c.inputDir == "" {
c.inputDir = defaultDir
c.inputDir = defaultRootDir
}
if !c.stdout {
if c.outputDir == "" {
c.outputDir = defaultDir
}
}
// Only regenerate API definitions once.
if c.apisDir == "" && !c.kustomize {
if cfg.MultiGroup {
c.apisDir = "apis"
} else {
c.apisDir = "api"
c.outputDir = defaultRootDir
}
}

Expand All @@ -216,7 +180,9 @@ func (c bundleCmd) runManifests(cfg *config.Config) (err error) {

stdout := genutil.NewMultiManifestWriter(os.Stdout)
opts := []gencsv.Option{
gencsv.WithBase(c.inputDir, c.apisDir, c.interactiveLevel),
// By not passing apisDir and turning interactive prompts on, we forcibly rely on the kustomize base
// for UI metadata and uninferrable data.
gencsv.WithBase(c.kustomizeDir, "", projutil.InteractiveHardOff),
}
if c.stdout {
opts = append(opts, gencsv.WithWriter(stdout))
Expand Down Expand Up @@ -270,7 +236,7 @@ func (c bundleCmd) runMetadata() error {
if directory == "" {
// There may be no existing bundle at the default path, so assume manifests
// only exist in the output directory.
defaultDirectory := filepath.Join(defaultDir, bundle.ManifestsDir)
defaultDirectory := filepath.Join(defaultRootDir, bundle.ManifestsDir)
if c.outputDir != "" && genutil.IsNotExist(defaultDirectory) {
directory = filepath.Join(c.outputDir, bundle.ManifestsDir)
} else {
Expand Down
31 changes: 25 additions & 6 deletions cmd/operator-sdk/generate/bundle/bundle_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,25 @@ import (
"github.com/operator-framework/operator-sdk/internal/util/projutil"
)

const examplesLegacy = `
const (
longHelpLegacy = `
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
`

examplesLegacy = `
# 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
Expand Down Expand Up @@ -56,9 +74,10 @@ const examplesLegacy = `
...
$ docker push $BUNDLE_IMG
`
)

// setCommonDefaultsLegacy sets defaults useful to all modes of this subcommand.
func (c *bundleCmd) setCommonDefaultsLegacy() {
func (c *bundleCmdLegacy) setCommonDefaults() {
if c.operatorName == "" {
c.operatorName = filepath.Base(projutil.MustGetwd())
}
Expand All @@ -71,7 +90,7 @@ func (c *bundleCmd) setCommonDefaultsLegacy() {

// validateManifestsLegacy validates c for bundle manifests generation for
// legacy project layouts.
func (c bundleCmd) validateManifestsLegacy() error {
func (c bundleCmdLegacy) validateManifests() error {
if c.version != "" {
if err := genutil.ValidateVersion(c.version); err != nil {
return err
Expand All @@ -81,7 +100,7 @@ func (c bundleCmd) validateManifestsLegacy() error {
}

// runManifestsLegacy generates bundle manifests for legacy project layouts.
func (c bundleCmd) runManifestsLegacy() (err error) {
func (c bundleCmdLegacy) runManifests() (err error) {

if !c.quiet {
if c.version == "" {
Expand Down Expand Up @@ -149,7 +168,7 @@ func (c bundleCmd) runManifestsLegacy() (err error) {

// validateMetadataLegacy validates c for bundle metadata generation for
// legacy project layouts.
func (c bundleCmd) validateMetadataLegacy() (err error) {
func (c bundleCmdLegacy) validateMetadata() (err error) {
// Ensure a default channel is present.
if c.defaultChannel == "" {
return fmt.Errorf("--default-channel must be set if setting multiple channels")
Expand All @@ -160,7 +179,7 @@ func (c bundleCmd) validateMetadataLegacy() (err error) {

// runMetadataLegacy generates a bundle.Dockerfile and bundle metadata for
// legacy project layouts.
func (c bundleCmd) runMetadataLegacy() error {
func (c bundleCmdLegacy) runMetadata() error {

directory := c.inputDir
if directory == "" {
Expand Down
Loading