-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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: add packagemanifests
subcommand for new project layouts
#3096
generate: add packagemanifests
subcommand for new project layouts
#3096
Conversation
c11c5a9
to
4b664da
Compare
packagemanifests
subcommand for new project layoutspackagemanifests
subcommand for new project layouts
192fac7
to
ad4ba12
Compare
ad4ba12
to
da29124
Compare
Something to think about: perhaps a better name would be |
that's a lot of spew. maybe add a default value (1.0.0?), and I think we should add the -version flag to the example usage. It also looks like errors are bubbling up from multiple places? I'm not sure what
more to come, I gotta go over the tests |
@jberkhahn thanks for giving this a test run!
|
Is this still WIP? I was reviewing it as if it weren't because the label got taken off. just some quick responses to some of your points.
|
2. $ mkdir custom
$ kustomize build config/default > custom/operator-manifests.yaml
$ operator-sdk generate packagemanifests --manifest-root custom/ 4. I'll update flag help. |
cmd := &cobra.Command{ | ||
Use: "packagemanifests", | ||
Short: "Generates a package manifests format", | ||
RunE: func(cmd *cobra.Command, args []string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be worth it to separate some of this out into functions instead of declaring it all inline. Maybe a validate() and a run() like in some of the other commands?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be better in a follow-up because both packagemanifests
and bundle
are organized as such.
@@ -0,0 +1,146 @@ | |||
// Copyright 2020 The Operator-SDK Authors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems very little of the cmd layer of the CLI is tested. Do we have any goals to add tests for all of this? I'm nervous about this much untested code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think it would be worthwhile to add unit tests here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of these command files are just configuration for the underlying generator, so at this point unit tests would just be testing different inputs which is covered by the e2e and subcommand tests I linked above. I'd like to add subcommand tests in a follow-up. However I will add an e2e test here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be down to hash out some unit tests for these bits.
CurrentCSVName: csvName, | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implementation seems good 👍
one more thing, I think the generator overwrites a pre-existing file, right? Might want to add a test for that so that is explicitly intended behavior. |
@jberkhahn file overwrites (CSV updates/upgrades) are tested here. We should make sure those tests cover more scenario's. |
5b8967c
to
ebd8b35
Compare
ebd8b35
to
472c830
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still going through the rest. Works pretty much like the old csv generator which is good but the new workflow of reading manifests from stdin needs an example.
Also @estroz maybe this is just a limitation in the new workflow, but given that we don't have a
And so the The old layout would be fine since Any reason we can't have the same resources:
- ../default
- ../samples |
Also I don't want to rethink and redo the UX here.
Which led me to think there should be a |
@hasbro17 the EP example should have included
After some thought however the flow I'd like to see users follow is: $ operator-sdk init
$ operator-sdk create api
$ operator-sdk generate packagemanifests --kustomize
$ kustomize build config/bundle | operator-sdk generate packagemanifests --version 0.0.1 since we want to push users towards using bundles by setting up We could take the above workflow a step further and set the default location for $ cp config/packages/0.0.1/ config/bundle/manifests
$ operator-sdk generate bundle --metadata While the UX may seem a little more confusing at first, I don't think it actually is because all operator-framework manifest kustomize bases and the |
@estroz I may not be totally following your above comment, but IMO, the packagemanifest CLI shouldn't depend on someone having already run I think users would expect the following sequence of commands to work:
If we want to push users toward bundles, I think there may be other better ways of doing that (docs, log messages when using packagemanifests, etc.) Also for sake of consistency and discoverability, should we rename |
@joelanford to clarify: $ kustomize build config/bundle | operator-sdk generate packagemanfiests The only feasible way I see to scaffold a I'm fine with |
…manifests --kustomize'
c7137c4
to
284902a
Compare
This is mostly a nit, since I don't think it matters that much. What would you think about having the CSV generated in That way:
This approach may mean having to touch the Would this get us out of doing merging into the base CSV? |
@joelanford ultimately that's what we should implemented have before even moving to full Also |
True, but isn't controller-gen fully idempotent, where it just rewrites the whole base without considering what's already there? |
e2f6bc9
to
dfd161e
Compare
fs.StringVar(&c.channelName, "channel", "", "Channel name for the generated package") | ||
fs.BoolVar(&c.isDefaultChannel, "default-channel", false, "Use the channel passed to --channel "+ | ||
"as the package manifest file's default channel") | ||
fs.BoolVar(&c.updateCRDs, "update-crds", false, "Update CustomResoureDefinition manifests in this package. "+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So --update-crds=false
as the default implies the opposite of the help text This will occur automatically when a new package is generated
.
Is it possible to simplify this by just having --update-crds=true
as the default.
And that simplifies our internal logic at L222 as just:
if c.updateCRDs {
var objs []interface{}
...
without having to do L181-L183:
// When generating a new package, CRDs should be written unless --update-crds has been explicitly set to false.
updateCRDsOff := c.updateCRDsFlag.Changed && !c.updateCRDs
writeNewPackageCRDs := !updateCRDsOff && genutil.IsNotExist(packageDir)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The UX gets a little weird here because you can update older package manifests versions of your operator, but you may not necessarily want to update CRDs for that version. That was the original thought at least.
Now that I think about this, I can imagine that developers tend to work on the latest package manifests version in master then check out the related release branch if they need to work on a prior version, in which the older version is latest. Given that premise I am ok with defaulting to --update-crds=true
. Thoughts @joelanford?
internal/generate/clusterserviceversion/clusterserviceversion.go
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few non-blocking nits but LGTM.
|
||
//nolint:lll | ||
const examples = ` | ||
# Generate manifests then create the package manifests base: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align spacing with the rest of the example.
# Generate manifests then create the package manifests base: | |
# Generate manifests then create the package manifests base: |
"--kustomize", | ||
"--interactive=false") | ||
_, err = tc.Run(genPkgManCmd) | ||
Expect(err).Should(Succeed()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super pedantic nit but Expect(err).Should(Succeed())
just sounds a little odd when I read it out loud.
From the godocs for Suceed()
it's meant to be passed the function and not the error it seems. And a single error return function at that.
Succeed passes if actual is a nil error Succeed is intended to be used with functions that return a single error value. Instead of
err := SomethingThatMightFail()
Expect(err).ShouldNot(HaveOccurred())
You can write:
Expect(SomethingThatMightFail()).Should(Succeed())
If we're getting the err value first then Expect(err).ShouldNot(HaveOccurred())
reads better.
But non-blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, these should be Expect(err).NotTo(HaveOccurred())
, which is idiomatic. Will fix this in a follow-up.
Description of the change:
operator-sdk generate packagemanifests
with:--kustomize
:config/packagemanifests/bases
with UI metadata. The base contains no manifests. This command will read API type data to generatecustomresourcedefinitions
metadata using GVK's inPROJECT
.config/packagemanifests/kustomization.yaml
if it does not already exist.--manifests
: reads either from stdin or on-disk files and applies them to a base to write CSV and CRD manifests toconfig/packagemanifests/<version>
. This command emulateskustomize build
.Motivation for the change: See operator-framework/enhancements#16.
TODO's: