-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Better stack list experience with Kubernetes and Swarm #1031
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
Conversation
|
⛑ comes after #991, only the 5 last commits are new. |
| flags := cmd.PersistentFlags() | ||
| flags.String("namespace", "default", "Kubernetes namespace to use") | ||
| flags.SetAnnotation("namespace", "kubernetes", nil) | ||
| flags.SetAnnotation("namespace", "experimentalCLI", 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.
This should stay
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 was moved into each sub-command, so still there in a way.
cli/command/stack/deploy.go
Outdated
| `Query the registry to resolve image digest and supported platforms ("`+swarm.ResolveImageAlways+`"|"`+swarm.ResolveImageChanged+`"|"`+swarm.ResolveImageNever+`")`) | ||
| flags.SetAnnotation("resolve-image", "version", []string{"1.30"}) | ||
| flags.SetAnnotation("resolve-image", "swarm", nil) | ||
| kubernetes.InstallFlags(flags) |
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.
Why making these flags per stack subcommand instead of putting the on the stack command and make the subcommand inherit ?
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.
Because stack ls now needs a different behaviour than other stack sub-commands for --namespace and we cannot set it once with type string and another time with []string (e.g. several namespaces).
So the drawback is a bit of code duplication setting the flags for all sub-commands, which was factorized into kubernetes.InstallFlags
cli/command/stack/list.go
Outdated
|
|
||
| flags := cmd.Flags() | ||
| flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template") | ||
| flags.StringSliceVar(&opts.Namespaces, "namespace", []string{"default"}, "Kubernetes namespaces to use") |
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.
Will setting a default here will override the default namespace defined in the context ?
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.
Hmm yes, I suppose it will, which is likely a bug.
However I don't think this has been introduced by this PR as the default for --namespace was already default.
Could this be fixed in a follow up?
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.
Actually there is code in kubernetes.WrapCli to deal with that and it seems to be working as expected
> docker stack ls --orchestrator=kubernetes
stacks.compose.docker.com is forbidden: User "uu" cannot list stacks.compose.docker.com in the namespace "default": access denied
> kubectl config set-context ucp_34.209.72.126:6443_uu --namespace=tutu
Context "ucp_34.209.72.126:6443_uu" modified.
> docker stack ls --orchestrator=kubernetes
NAME SERVICES ORCHESTRATOR NAMESPACE
dtc 5 Kubernetes tutu
| flags.SetAnnotation("namespace", "kubernetes", nil) | ||
| flags.SetAnnotation("namespace", "experimentalCLI", nil) | ||
| flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces") | ||
| flags.SetAnnotation("all-namespaces", "kubernetes", 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.
all-namespaces should probably be marked as experimentalCLI too
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.
Yes, I'll add that, thanks.
cli/command/stack/list.go
Outdated
| Output: dockerCli.Out(), | ||
| Format: formatter.NewStackFormat(format), | ||
| } | ||
| sort.Slice(stacks, |
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.
sort.Slice(stacks, func(i, j int) bool { …
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.
OK
cli/command/stack/list_test.go
Outdated
| )}, nil | ||
| }, | ||
| }) | ||
| cli.SetClientInfo(func() command.ClientInfo { return command.ClientInfo{Orchestrator: "swarm"} }) |
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.
Same here
cli/command/stack/list_test.go
Outdated
| )}, nil | ||
| }, | ||
| }) | ||
| cli.SetClientInfo(func() command.ClientInfo { return command.ClientInfo{Orchestrator: "swarm"} }) |
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.
and here …
cli/command/stack/list_test.go
Outdated
| return uc.swarmServices, nil | ||
| }, | ||
| }) | ||
| cli.SetClientInfo(func() command.ClientInfo { return command.ClientInfo{Orchestrator: "swarm"} }) |
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.
… and here
cli/command/stack/deploy.go
Outdated
| if dockerCli.ClientInfo().HasKubernetes() { | ||
| switch { | ||
| case dockerCli.ClientInfo().HasAll(): | ||
| return fmt.Errorf("Please specify an orchestrator (swarm|kubernetes)") |
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.
We may want to share this error somehow
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.
OK!
cmd/docker/docker.go
Outdated
| flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") | ||
| flags.StringVar(&opts.ConfigDir, "config", cliconfig.Dir(), "Location of client config files") | ||
| opts.Common.InstallFlags(flags) | ||
| opts.Common.InstallFlags(flags, cmd.PersistentFlags()) |
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 don't get this change, this feels really weird to add the flag twice (on cmd.Flags() and cmd.PersistentFlags())
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.
"orchestrator" is the only flag added to cmd.PersistentFlags() in InstallFlags, all the other flags are still in cmd.Flags()
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.
That being said if you would rather have me remove that last commit, I'd be fine with that!
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.
Slightly confused as well
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.
OK, I'll just remove the related commit.
|
@vdemeester I fixed all comments except the ones under discussion about the flags e.g.
Would you kindly please take another look? |
thaJeztah
left a comment
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 adds a lot of complexity to the codebase, and I'm not sure if all is needed. I left some comments inline, but must admit some of the flow is a bit hard to follow
cli/flags/common.go
Outdated
| flags.BoolVar(&commonOpts.TLS, "tls", dockerTLS, "Use TLS; implied by --tlsverify") | ||
| flags.BoolVar(&commonOpts.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote") | ||
| flags.StringVar(&commonOpts.Orchestrator, "orchestrator", "", "Which orchestrator to use with the docker cli (swarm|kubernetes) (default swarm) (experimental)") | ||
| flags.StringVar(&commonOpts.Orchestrator, "orchestrator", "", "Which orchestrator to use with the docker cli (swarm|kubernetes|all) (default swarm) (experimental)") |
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.
Looks like (default swarm) no longer matches reality (for example, having "orchestrator":"kubernetes" in my ~/.docker/config.json would set the default)
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.
That's a good point. I'll remove the (default swarm).
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.
Also this was there before but I don't thing with the docker cli brings anything and the other flag descriptions don't have it. I'll remove it too.
| flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template") | ||
| flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces") | ||
| flags.SetAnnotation("all-namespaces", "kubernetes", nil) | ||
| flags.SetAnnotation("all-namespaces", "experimentalCLI", 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.
Looks like this change to all-namespaces should be done in the other PR (#991)?
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're right, too late though as #991 has been merged in the meanwhile…
|
|
||
| flags := cmd.Flags() | ||
| flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template") | ||
| flags.StringSliceVar(&opts.Namespaces, "namespace", []string{}, "Kubernetes namespaces to use") |
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.
Is there a reason we use two separate approaches for the namespace flag? Looks like we define it twice now: once through AddNamespaceFlag()
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.
All docker stack sub-commands use AddNamespaceFlag and have a namespace flag defined as a StringVar except ls which has a namespace flag defined as a StringSliceVar.
This is because for all sub-commands but ls only one --namespace can be set whereas ls can have several, e.g. docker stack ls --namespace=tutu,default,bla or docker stack ls --namespace=tutu --namespace=default --namespace=bla.
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.
Wondering now if this should be a StringSliceVar or a StringVar; I think StringVar can be specified multiple times (--namespace=bla --namespace=foo), but does not support comma-separated values; we haven't documented using comma-separated values, and don't think we support it for other options (possibly --security-opt only)
(note that if a command only accepts a single namespace, we could still produce an error if multiple are given)
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'll take another look but from what I remember there was no way to make it look nice, for both cases, e.g.
$ docker stack ps --help
…
Options:
…
--namespace string Kubernetes namespace to use
VS
$ ./build/docker.exe stack ls --help
…
Options:
…
--namespace strings Kubernetes namespaces to use
Also I don't see how a single StringVar can hold multiple --namespace values…
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 StringVar can be specified multiple times (--namespace=bla --namespace=foo), but does not support comma-separated values
In that case the latest value is silently selected (here foo), I suppose the flags are simply processed in order.
If we just let comma-separated values out of the question we could indeed emulate both behaviors with a StringSliceVar by using the last element when only one namespace is required.
(Incidentally passing --namespace=bla,foo to a StringVar flag yields a value of bla,foo…)
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 best I could come up with by using []string on the stack command level is
$ ./build/docker.exe stack --help
Usage: docker stack COMMAND
Manage Docker stacks
Options:
--kubeconfig string Kubernetes config file
--namespace strings Kubernetes namespace to use
This is wrong for all sub-commands as for most of them it says strings plural whereas only one is supported (and differs for instance from kubeconfig), and for docker stack ls which supports several namespaces the description should have namespaces…
I don't see how to have types and descriptions accurate for all sub-commands without duplicating the flag.
cli/command/stack/list.go
Outdated
| } | ||
| mnms := map[string]struct{}{} | ||
| for _, nm := range nms { | ||
| mnms[nm] = struct{}{} |
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.
Looks like this is to get rid of duplicates? This feels a bit like premature optimisation, also I'd expected this to return a []string (matching the type before removing duplicates)
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.
Yes this is to remove duplicates, again to match kubectl behavior. I'll change the return type to a []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.
…and refactor it to
func removeDuplicates(namespaces []string) []string {
mnms := map[string]struct{}{}
for _, nm := range namespaces {
mnms[nm] = struct{}{}
}
namespaces = []string{}
for nm := range mnms {
namespaces = append(namespaces, nm)
}
return namespaces
}
cli/command/stack/kubernetes/cli.go
Outdated
| if len(namespace) > 0 { | ||
| opts.Namespace = namespace[0] | ||
| } else if nm, err := flags.GetString("namespace"); err == nil { | ||
| opts.Namespace = nm |
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's now opts.Namespaces (for stacks) and opts.Namespace, correct?
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.
Yes, there first one is of type []string and the latter string.
cli/command/stack/list.go
Outdated
| ss, err := kubernetes.GetStacks(kli, opts) | ||
| if err != nil { | ||
| return err | ||
| if opts.AllNamespaces || len(mnms) == 0 { |
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.
Wouldn't len(opts.Namespaces) give the same 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.
Oh yes, nice catch!
cli/command/stack/list.go
Outdated
| return ss, nil | ||
| } | ||
|
|
||
| func getNamespaces(cmd *cobra.Command) (map[string]struct{}, 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.
This could just take (flags *flag.FlagSet, or even namespaces []string, then call it with getNamespaces(cmd.Flags()), but see my other comments
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 has actually been changed to receive a flags *flag.FlagSet in a follow-up PR, but I might as well do it there.
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.
Hmm sorry I meant []string and passing it opts.Namespaces…
cli/command/stack/kubernetes/cli.go
Outdated
|
|
||
| // NewOptions returns an Options initialized with command line flags | ||
| func NewOptions(flags *flag.FlagSet) Options { | ||
| func NewOptions(flags *flag.FlagSet, namespace ...string) Options { |
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.
Both flags and namespace basically come from cmd.Flags(); why pass both, if we have all information in flags?
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 way Kubernetes works implies that listing the stacks (or anything else) must be made within the context of a namespace, thus as we want to merge the lists of stacks from different namespaces we create a new kubernetes.Options for each namespace when iterating over them for docker stack ls.
I'll refactor the code to separate the different behaviors in respect to namespaces.
cli/command/stack/kubernetes/cli.go
Outdated
| opts.Namespace = namespace | ||
| if len(namespace) > 0 { | ||
| opts.Namespace = namespace[0] | ||
| } else if nm, err := flags.GetString("namespace"); err == 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.
in what situation would flags.GetString("namespace") give anything different than namespace[0]? If we only expect a single namespace to be passed, it should not take more than one
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 is again due to the discrepancy between docker stack ls and the other docker stack sub-commands regarding the number of --namespace flags allowed.
cmd/docker/docker.go
Outdated
| flags.BoolVarP(&opts.Version, "version", "v", false, "Print version information and quit") | ||
| flags.StringVar(&opts.ConfigDir, "config", cliconfig.Dir(), "Location of client config files") | ||
| opts.Common.InstallFlags(flags) | ||
| opts.Common.InstallFlags(flags, cmd.PersistentFlags()) |
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.
Slightly confused as well
|
This needs a rebase now |
|
@thaJeztah I believe the code to be much clearer now, thank you for your comments! |
cli/command/stack/list.go
Outdated
| kopts := kubernetes.NewOptions(cmd.Flags()) | ||
| if opts.AllNamespaces || len(opts.Namespaces) == 0 { | ||
| if dockerCli.ClientInfo().HasAll() { | ||
| opts.AllNamespaces = true |
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 if you have orchestrator=all and then you do docker stack ls --namespace=foobar, this will still return all stacks in every namespace?
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 branch is only executed if opts.AllNamespaces || len(opts.Namespaces) == 0 e.g. there is already --orchestrator=all or no --namespace.
Here is what this gives me:
$ ./build/docker.exe --orchestrator=all stack ls
NAME SERVICES ORCHESTRATOR NAMESPACE
blaaaaaa 1 Kubernetes default
blaaaaaaaaa 1 Kubernetes default
dtc 5 Kubernetes tutu
dtc 5 Kubernetes tata
dtcccccc 5 Kubernetes default
$ ./build/docker.exe --orchestrator=all stack ls --namespace=tata
NAME SERVICES ORCHESTRATOR NAMESPACE
dtc 5 Kubernetes tata
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.
Ah, I see now.
wsong
left a comment
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 looks reasonable to me, but I'll let @vdemeester and @thaJeztah have the final say.
cli/command/stack/list.go
Outdated
| kopts := kubernetes.NewOptions(cmd.Flags()) | ||
| if opts.AllNamespaces || len(opts.Namespaces) == 0 { | ||
| if dockerCli.ClientInfo().HasAll() { | ||
| opts.AllNamespaces = true |
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.
Ah, I see now.
cli/command/stack/list.go
Outdated
| if dockerCli.ClientInfo().HasKubernetes() { | ||
| kopts := kubernetes.NewOptions(cmd.Flags()) | ||
| if opts.AllNamespaces || len(opts.Namespaces) == 0 { | ||
| if dockerCli.ClientInfo().HasAll() { |
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 is redundant, because we already checked HasKubernetes(), which also checks for HasAll();
// HasKubernetes checks if kubernetes orchestrator is enabled
func (c ClientInfo) HasKubernetes() bool {
return c.HasExperimental && (c.Orchestrator == OrchestratorKubernetes || c.Orchestrator == OrchestratorAll)
}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.
--orchestrator=kubernetes yields HasKubernetes() true and HasAll() false
--orchestrator=all yields both HasKubernetes() true and HasAll() true
So if HasAll() implies HasKubernetes(), the reverse is not necessary true.
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.
But here HasAll() (ie --orchestrator=all) is used to enable --all-namespaces; I don't see how those relate
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 is a UX requirement defined in the PRD
- Provide intuitive mechanisms for switching Kubernetes namespace:
- When targeting all orchestrators, target all namespaces by default
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'm having trouble conflating these; this may become very confusing:
- configuration has
"orchestrator: all":docker stack lsshows all stacks (both swarm and k8s) - I want to view only the
k8sstacks, so I add--orchestrator=kubernetes. Now I no longer see all my stacks, only those in thedefaultnamespace - confused
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 thinking behind this was as follows: When you list stacks across orchestrators your intention is to see all the stacks running on your cluster. When you specify kubernetes as your orchestrator; you are doing something more specific and want similar behaviour to what kubectl gives you.
I can see how this might be confusing for your flow. There will be a NAMESPACE column which should help the user understand what has happened.
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.
Ah, see you're referring to the case when a user has set orchestrator to all in their config file. I don't think many users will do this as they will only be able to list resources. In order to manipulate resources, they will need to specify an orchestrator.
cli/command/stack/list.go
Outdated
| } | ||
| namespaces = []string{} | ||
| for nm := range mnms { | ||
| namespaces = append(namespaces, nm) |
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.
no need to loop twice here, could be something like;
func removeDuplicates(namespaces []string) []string {
found := make(map[string]bool)
results := namespaces[:0]
for _, n := range namespaces {
if !found[n] {
results = append(results, n)
found[n] = true
}
}
return results
}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.
Fair enough, I'll change that.
|
|
||
| flags := cmd.Flags() | ||
| flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template") | ||
| flags.StringSliceVar(&opts.Namespaces, "namespace", []string{}, "Kubernetes namespaces to use") |
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.
Wondering now if this should be a StringSliceVar or a StringVar; I think StringVar can be specified multiple times (--namespace=bla --namespace=foo), but does not support comma-separated values; we haven't documented using comma-separated values, and don't think we support it for other options (possibly --security-opt only)
(note that if a command only accepts a single namespace, we could still produce an error if multiple are given)
|
Could there be something missing in this PR? Trying inside the build container (no kubernetes enabled, but experimental features on)' Now, trying this; |
|
This looks like what we want because The orchestrator flag must be right after Passing Or am I missing something? |
hm, right; I'm in doubt if we should only accept it as a global flag. I know users can get very confused as to "where" to pass a flag; existing examples are, e.g. |
|
@thaJeztah I brought the refactoring over from https://github.com/docker/cli/pull/1034/files/e0dbcb3b88f615d358fc5bed93ca3d14aa094d87..691eeff5a5db87be3fe5e0f1ca852024edf08f1c#diff-0ade8f01def39989ced9bb51bab08a69 |
Signed-off-by: Mathieu Champlon <[email protected]>
|
@vdemeester @thaJeztah I can remove the last commit if that helps moving forward with this PR (and either open a separate PR with it or just forget about it)? |
thaJeztah
left a comment
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 generally LGTM, but perhaps we should indeed move the refactor out of this PR (t.b.h., I don't recall suggesting that change, but it could've been me, idk)
cli/command/stack/cmd.go
Outdated
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| var errUnsupportedAllOrchestrator = fmt.Errorf("Please specify an orchestrator (swarm|kubernetes)") |
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.
Thinking of rephrasing this (also in light of #770); perhaps;
No orchestrator specified. Use either "kubernetes" or "swarm"
(better suggestions welcome)
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.
As an error message shouldn't it start with a lower case? I would probably avoid the dot too, e.g.
no orchestrator specified, use either "kubernetes" or "swarm"
or
no orchestrator specified: use either "kubernetes" or "swarm"
?
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 like this one:
no orchestrator specified: use either "kubernetes" or "swarm"
| return nil, err | ||
| } | ||
| stackSvc, err := composeClient.Stacks(allNamespaces) | ||
| stackSvc, err := composeClient.Stacks(opts.AllNamespaces) |
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.
Not for this PR, but we should consider passing an opts here, instead of a boolean (opts.AllNamespaces) to prevent future bloat in the signature
|
I still have reservations on the magic relation between I'm having trouble conflating these; this may become very confusing:
The thinking behind this was as follows: When you list stacks across orchestrators your intention is to see all the stacks running on your cluster. When you specify I can see how this might be confusing for your flow. There will be a NAMESPACE column which should help the user understand what has happened. @chris-crone : Ah, see you're referring to the case when a user has set
I'm actually not sure: I can definitely see it being useful to just run any Which brings me to two things to consider:
|
|
I removed the commit with the tests refactoring and changed the error message when an orchestrator must be explicitly specified. |
All other docker stack commands report an error when passed this value. Signed-off-by: Mathieu Champlon <[email protected]>
|
@mat007 could you move the It's three lines, so easy to review from a code-perspective, so if we get agreement on that one, we should be able to merge that one fast; if dockerCli.ClientInfo().HasAll() {
opts.AllNamespaces = true
} |
Signed-off-by: Mathieu Champlon <[email protected]>
|
@thaJeztah done! |
thaJeztah
left a comment
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.
LGTM
sorry for all the hence-and-forth 😅
vdemeester
left a comment
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.
LGTM 🐯
|
Just to keep track, the all orchestrator all namespace work is in #1059. |
- What I did
Made it easier to work with both swarm and kubernetes stacks combined, e.g.
stack lsfor the valueallin the--orchestratorflag which triggers the display of both swarm and kubernetes stacks--namespacefor docker stack ls- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)