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
Add alpha command to kubectl #46151
Add alpha command to kubectl #46151
Conversation
/assign @pwittrock |
60c9cfc
to
eaa84d6
Compare
@k8s-bot pull-kubernetes-federation-e2e-gce test this |
pkg/kubectl/cmd/cmd.go
Outdated
@@ -252,6 +255,12 @@ var ( | |||
|
|||
// NewKubectlCommand creates the `kubectl` command and its nested children. | |||
func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { | |||
if f := os.Getenv("KUBECTL_FEATURE_GATES"); f != "" { |
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.
Document how to set this env?
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.
or give some help info via kubectl --help
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.
how about set feature gates via a subcommand or flag instead of setting env vars?
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.
Thanks for asking this, it made me realize that I hadn't actually Submitted my comment explaining my reasoning and it was just hanging out in a text box in another tab waiting for me to close my browser. Here it is: #45922 (comment)
There's a bit of a catch-22 with setting feature gates on kubectl itself. If we set them with a flag then the gates won't be available prior to flag parsing and so can't gate flags or the command tree.
We definitely should document this, but first let's reach consensus on how the feature gates will be implemented.
pkg/kubectl/cmd/cmd.go
Outdated
@@ -252,6 +255,12 @@ var ( | |||
|
|||
// NewKubectlCommand creates the `kubectl` command and its nested children. | |||
func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { | |||
if f := os.Getenv("KUBECTL_FEATURE_GATES"); f != "" { | |||
if e := utilfeature.DefaultFeatureGate.Set(f); e != nil { | |||
fmt.Fprintf(err, "Invalid KUBECTL_FEATURE_GATES %q. Available features:\n%s\n", f, strings.Join(utilfeature.DefaultFeatureGate.KnownFeatures(), "\n")) |
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.
provide some way to get KnownFeatures and whether they are enabled or not?
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.
Good idea. I'll include this in kubectl --help
as you suggested.
pkg/kubectl/cmd/cmd.go
Outdated
@@ -348,6 +357,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob | |||
}, | |||
}, | |||
} | |||
groups.PruneCommands() |
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.
What if users run a disabled command?
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.
When a command disables itself by returning nil
it's as if the command doesn't exist, which is intentional. My goal is that alpha features don't influence the behavior of kubectl
in any way unless they're enabled.
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.
@verb Thanks for the explanation!
We have had the discussion a number of times whether clients should depend on apiserver features. IMO if we want feature gates in kubectl at all, we should make them independent from the apiserver ones. /cc @smarterclayton |
@sttts Sure, it would be easy to use the feature gate framework with an independent configuration. I rather like the feature gate framework, but I'm not tied to it. If we do use feature gates do you like the environment-based approach? I think the alternative would have to be a |
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.
Code looks fine to me. I'll defer to the existing discussion on whether this is the correct path to take.
pkg/kubectl/cmd/cmd.go
Outdated
@@ -252,6 +255,12 @@ var ( | |||
|
|||
// NewKubectlCommand creates the `kubectl` command and its nested children. | |||
func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { | |||
if f := os.Getenv("KUBECTL_FEATURE_GATES"); f != "" { | |||
if e := utilfeature.DefaultFeatureGate.Set(f); e != nil { |
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.
If this is an error it should be named err
, no?
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.
Normally it would, but I want to print to the io.Writer
with the same name from the enclosing scope.
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.
Gotcha, thanks!
I tried a different approach and created a Right now alpha commands are visible if they exist, but it would be easy to hide them further. |
@verb pull-kubernetes-verify failed due to:
|
I like the alpha command more than the env var 👍 |
/cc @fabianofranz you are nearer to kubectl. What's your opinion? |
pkg/kubectl/cmd/alpha.go
Outdated
Long: templates.LongDesc(i18n.T("These commands correspond to alpha features that are not enabled in Kubernetes clusters by default.")), | ||
} | ||
|
||
// Alpha commands should be added to alphaGroups, which is arranged similar to the main |
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.
Where is alphaGroups
defined?
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.
Whoops, that was left over from a previous implementation. Updated the comment to reflect the current implementation.
pkg/kubectl/cmd/cmd.go
Outdated
@@ -354,6 +354,10 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob | |||
"options", | |||
Deprecated("kubectl", "delete", cmds, NewCmdStop(f, out)), | |||
} | |||
alpha := NewCmdAlpha(f, in, out, err) | |||
if !alpha.HasSubCommands() { | |||
filters = append(filters, alpha.Name()) |
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.
Comment might be nice here. Something like
// If there are no alpha commands in this build, hide the "alpha" subcommand.
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.
Good call, done.
@k8s-bot pull-kubernetes-federation-e2e-gce test this |
// NewCmdAlpha creates a command that acts as an alternate root command for features in alpha | ||
func NewCmdAlpha(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "alpha", |
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.
Maybe this should be:
Use: "alpha SUBCOMMAND",
To be consistent with other commands in the repo:
cmd/certificates.go:35: Use: "certificate SUBCOMMAND",
cmd/set/set.go:37: Use: "set SUBCOMMAND",
cmd/rollout/rollout.go:51: Use: "rollout SUBCOMMAND",
cmd/config/config.go:39: Use: "config SUBCOMMAND",
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 happy to do that, but alpha is a little bit different from set/rollout/config as its more of a container for commands rather than a command with subcommands. For example, config get
and config set
are related subcommands that operate on config
, but alpha debug
and alpha foo
are unrelated other than both being in an alpha state.
Also, the commands in alpha could themselves have subcommands, which would make the "Usage: kubectl alpha SUBCOMMAND [options]" not quite correct.
As its coded now, without a run function, Usage will be omitted from help and look like this:
These commands correspond to alpha features that are not enabled in Kubernetes clusters by default.
Available Commands:
debug Run a debug container in a pod
Use "kubectl <command> --help" for more information about a given command.
If we were to give it a default run function and set Use to "alpha COMMAND", then the help would be:
These commands correspond to alpha features that are not enabled in Kubernetes clusters by default.
Available Commands:
debug Run a debug container in a pod
Usage:
kubectl alpha COMMAND [options]
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
pkg/kubectl/cmd/alpha.go
Outdated
// NewKubeletCommand() will hide the alpha command if it has no subcommands. Overriding | ||
// the help function ensures a reasonable message if someone types the hidden command anyway. | ||
if !cmd.HasSubCommands() { | ||
cmd.SetHelpFunc(func(_ *cobra.Command, _ []string) { |
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.
You don't need the underscores 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.
whoops, fixed.
/lgtm |
@verb would you squash before I approve? |
Looks like the merge bot was over eager about the approve label |
Alpha commands can be added under `kubectl alpha` and are always accessible (regardless of feature gates). If no alpha commands have been defined then `alpha` is not displayed in `help`.
a02a614
to
01c7d12
Compare
squashed! |
/retest |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: pwittrock, verb Associated issue: 45922 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 |
Automatic merge from submit-queue |
Also allow new commands to disable themselves by returning a nil value. This can be used to disable commands based on feature gates.
What this PR does / why we need it: Method of enabling alpha functionality in kubectl
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged): ref #45922Special notes for your reviewer: Part of a discussion in #45922 with @pwittrock
Release note: