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

make the kubelet cobra command complete #58405

Merged
merged 1 commit into from Jan 18, 2018

Conversation

deads2k
Copy link
Contributor

@deads2k deads2k commented Jan 17, 2018

This pull attempts a move from the cmd/kubelet to the cobra command where it can re-used.

/assign @mtaufen
/assign @liggitt
@ncdc fyi

xref: #34732

NONE

@k8s-ci-robot k8s-ci-robot added do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Jan 17, 2018
@deads2k deads2k added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Jan 17, 2018
}

// initialize logging and defer flush
utilflag.InitFlags()
Copy link
Member

Choose a reason for hiding this comment

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

Don't think you can do this - see

// TODO: once we switch everything over to Cobra commands, we can go back to calling
// utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
// normalize func and add the go flag set by hand.

Copy link
Contributor Author

@deads2k deads2k Jan 17, 2018

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to work ok for the scheduler: https://github.com/kubernetes/kubernetes/blob/master/cmd/kube-scheduler/scheduler.go#L32-L34

I see the bug. Registering global flags is naughty. Fixed.

Copy link
Member

Choose a reason for hiding this comment

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

As we discussed on slack, the scheduler is registering its flags globally into pflag.CommandLine. The kube-proxy registers its flags into the cobra command's .Flags(), which is why utilflag.InitFlags() doesn't work for kube-proxy but does for the scheduler. We need to fix the scheduler, finish converting all the executables to use cobra (#34732), then we can use InitFlags.

@@ -97,8 +98,9 @@ const (
// NewKubeletCommand creates a *cobra.Command object with default parameters
func NewKubeletCommand() *cobra.Command {
// ignore the error, as this is just for generating docs and the like
Copy link
Member

Choose a reason for hiding this comment

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

This comment isn't true any more

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This comment isn't true any more

That is a code error. Updated to panic

// TODO(mtaufen): won't need this this once dynamic config is GA
// set feature gates so we can check if dynamic config is enabled
if err := utilfeature.DefaultFeatureGate.SetFromMap(kubeletServer.KubeletConfiguration.FeatureGates); err != nil {
glog.Fatal(err)
Copy link
Member

Choose a reason for hiding this comment

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

I know this was a move, but consider cmdutil.CheckErr() here and below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know this was a move, but consider cmdutil.CheckErr() here and below?

That will tie us to pkg/kubectl. I'd rather not end up with that linkage.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, maybe we should consider taking that out of e.g. kube-proxy and (if it uses it) kube-scheduler in follow-ups.

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably the base checkErr stuff should move out of kubectl.

@deads2k deads2k force-pushed the kubelet-01-start branch 2 times, most recently from 35c0111 to 126cdba Compare January 17, 2018 18:09
// set the normalize func, similar to k8s.io/apiserver/pkg/util/flag/flags.go:InitFlags
fs.SetNormalizeFunc(flag.WordSepNormalizeFunc)
// explicitly add flags from libs that register global flags
options.AddGlobalFlags(fs)
Copy link
Member

Choose a reason for hiding this comment

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

does the switch to cobra cmd expose us to picking up all the globally registered flags again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

does the switch to cobra cmd expose us to picking up all the globally registered flags again?

Nothing new that I know. It makes some of the previously registered ones more obvious via help since the help is accurate now, but it doesn't mess with the parsing.

Copy link
Member

Choose a reason for hiding this comment

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

this was selectively adding specific global flags, not all global flags, and marked most deprecated. does cobra just pick all the global ones up again?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this was selectively adding specific global flags, not all global flags, and marked most deprecated. does cobra just pick all the global ones up again?

It is consistent with the other commands. I'd much prefer to build a common whitelist if its a thing we want. After this, we have #58408 and then we can start dealing with all the command uniformally and fix it everywhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should take a step backwards just to be "consistent" with other commands - which are probably doing it wrong by leaking flags anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I can update this tomorrow morning

Copy link
Contributor

@mtaufen mtaufen left a comment

Choose a reason for hiding this comment

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

I think you mostly got things in the right place, but we should try to accomplish this without regressing on the Kubelet's existing behavior.

// set the normalize func, similar to k8s.io/apiserver/pkg/util/flag/flags.go:InitFlags
fs.SetNormalizeFunc(flag.WordSepNormalizeFunc)
// explicitly add flags from libs that register global flags
options.AddGlobalFlags(fs)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should take a step backwards just to be "consistent" with other commands - which are probably doing it wrong by leaking flags anyway.

// utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
// normalize func and add the go flag set by hand.
pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please don't leak the global command line into the Kubelet here. We already did a lot of work to fix this for the Kubelet in #57613. This will be a regression.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why we can't just construct the private flagset in Run (above) and apply the passed in args []string to it, just like we do in main today. Effectively, why can't you just copy the body of today's main to Run, and substitute Run's args for today's os.Args? Does cobra do something special that gets in the way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's non-cobra-y and doesn't reflect the patterns we've found to work well in kubectl and openshift. I think you'll be happier take a different tack that separates your data and transformation phases more cleanly. This doesn't preclude such a follow-up or make it harder to do, but you should carefully consider the data flow.

@@ -121,8 +124,52 @@ is checked every 20 seconds (also configurable with a flag).
HTTP server: The kubelet can also listen for HTTP and respond to a simple API
(underspec'd currently) to submit a new manifest.`,
Run: func(cmd *cobra.Command, args []string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We will need to make sure it's still possible for the Kubelet to re-parse its command line multiple times during its bootstrap, see #56995 and #56171. I'd suppose this can be done with the args []string passed in here but need to make sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reparsing is possible. I'll link you to some OpenShift code that does it. In general, be careful about doing it.

}

// construct a KubeletServer from kubeletFlags and kubeletConfig
kubeletServer.KubeletConfiguration = *kubeletConfig
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer we construct the kubeletFlags and kubeletConfig independently, and construct the kubeletServer just before we pass it to Run. The code reads more cleanly if it consists of a sequence of constructions rather than a sequence of mutations to a pre-constructed object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like that too, but I think the order should be 1) split the flag struct out, 2) write code to go from structul to runtime, 3) update command

// ignore the error, as this is just for generating docs and the like
s, _ := options.NewKubeletServer()
s.AddFlags(pflag.CommandLine)
kubeletServer, err := options.NewKubeletServer()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we construct this inside Run, just like it's constructed in main() today?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You need to use it to later add flags.

@mtaufen
Copy link
Contributor

mtaufen commented Jan 17, 2018

/approve
/hold
(hold for global flags changes, as discussed on slack)
ping me on slack when it's ready, thanks for understanding

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 17, 2018
@derekwaynecarr
Copy link
Member

/approve
/hold

@k8s-github-robot k8s-github-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 18, 2018
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 18, 2018
@deads2k
Copy link
Contributor Author

deads2k commented Jan 18, 2018

Global flags suppressed. Made it slightly more forward building too.

@k8s-ci-robot k8s-ci-robot added do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. and removed release-note-none Denotes a PR that doesn't merit a release note. labels Jan 18, 2018
@deads2k
Copy link
Contributor Author

deads2k commented Jan 18, 2018

/approve no-issue

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Jan 18, 2018
@deads2k
Copy link
Contributor Author

deads2k commented Jan 18, 2018

/approve
/hold
(hold for global flags changes, as discussed on slack)
ping me on slack when it's ready, thanks for understanding

global flags update and managed to move the kubeletServer instantiation down, though now there are two sources for flags (kubeletconfiguration and kubeletflags)

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jan 18, 2018
if err := app.Run(kubeletServer, kubeletDeps); err != nil {
die(err)
if err := command.Execute(); err != nil {
os.Exit(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

where I can see the error?

@mfojtik
Copy link
Contributor

mfojtik commented Jan 18, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jan 18, 2018
@deads2k deads2k added lgtm Indicates that a PR is ready to be merged. and removed lgtm Indicates that a PR is ready to be merged. labels Jan 18, 2018
@deads2k
Copy link
Contributor Author

deads2k commented Jan 18, 2018

/retest

@mtaufen
Copy link
Contributor

mtaufen commented Jan 18, 2018

/lgtm

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: deads2k, derekwaynecarr, mfojtik, mtaufen

Associated issue: #34732

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@mtaufen
Copy link
Contributor

mtaufen commented Jan 18, 2018

not sure what's going on with that GPU test... maybe the nvidia driver install flaked on that one node?
/retest

@k8s-github-robot
Copy link
Contributor

Automatic merge from submit-queue (batch tested with PRs 58209, 57561, 58405). If you want to cherry-pick this change to another branch, please follow the instructions here.

@k8s-github-robot k8s-github-robot merged commit 7f6dae7 into kubernetes:master Jan 18, 2018
@deads2k deads2k mentioned this pull request Jan 18, 2018
@deads2k deads2k deleted the kubelet-01-start branch July 3, 2018 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm Indicates that a PR is ready to be merged. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants