Skip to content

Commit 4d947de

Browse files
committed
Support 'all' in orchestrator flag for docker stack ls
All other docker stack commands report an error when passed this value. Signed-off-by: Mathieu Champlon <[email protected]>
1 parent 0d7bb8a commit 4d947de

File tree

15 files changed

+144
-98
lines changed

15 files changed

+144
-98
lines changed

‎cli/command/cli.go‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,17 @@ type ClientInfo struct {
244244

245245
// HasKubernetes checks if kubernetes orchestrator is enabled
246246
func (c ClientInfo) HasKubernetes() bool {
247-
return c.HasExperimental && c.Orchestrator == OrchestratorKubernetes
247+
return c.HasExperimental && (c.Orchestrator == OrchestratorKubernetes || c.Orchestrator == OrchestratorAll)
248+
}
249+
250+
// HasSwarm checks if swarm orchestrator is enabled
251+
func (c ClientInfo) HasSwarm() bool {
252+
return c.Orchestrator == OrchestratorSwarm || c.Orchestrator == OrchestratorAll
253+
}
254+
255+
// HasAll checks if all orchestrator is enabled
256+
func (c ClientInfo) HasAll() bool {
257+
return c.Orchestrator == OrchestratorAll
248258
}
249259

250260
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.

‎cli/command/cli_test.go‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ func TestOrchestratorSwitch(t *testing.T) {
171171
flagOrchestrator string
172172
expectedOrchestrator string
173173
expectedKubernetes bool
174+
expectedSwarm bool
174175
}{
175176
{
176177
doc: "default",
@@ -179,6 +180,7 @@ func TestOrchestratorSwitch(t *testing.T) {
179180
}`,
180181
expectedOrchestrator: "swarm",
181182
expectedKubernetes: false,
183+
expectedSwarm: true,
182184
},
183185
{
184186
doc: "kubernetesIsExperimental",
@@ -190,6 +192,7 @@ func TestOrchestratorSwitch(t *testing.T) {
190192
flagOrchestrator: "kubernetes",
191193
expectedOrchestrator: "swarm",
192194
expectedKubernetes: false,
195+
expectedSwarm: true,
193196
},
194197
{
195198
doc: "kubernetesConfigFile",
@@ -199,6 +202,7 @@ func TestOrchestratorSwitch(t *testing.T) {
199202
}`,
200203
expectedOrchestrator: "kubernetes",
201204
expectedKubernetes: true,
205+
expectedSwarm: false,
202206
},
203207
{
204208
doc: "kubernetesEnv",
@@ -208,6 +212,7 @@ func TestOrchestratorSwitch(t *testing.T) {
208212
envOrchestrator: "kubernetes",
209213
expectedOrchestrator: "kubernetes",
210214
expectedKubernetes: true,
215+
expectedSwarm: false,
211216
},
212217
{
213218
doc: "kubernetesFlag",
@@ -217,6 +222,17 @@ func TestOrchestratorSwitch(t *testing.T) {
217222
flagOrchestrator: "kubernetes",
218223
expectedOrchestrator: "kubernetes",
219224
expectedKubernetes: true,
225+
expectedSwarm: false,
226+
},
227+
{
228+
doc: "allOrchestratorFlag",
229+
configfile: `{
230+
"experimental": "enabled"
231+
}`,
232+
flagOrchestrator: "all",
233+
expectedOrchestrator: "all",
234+
expectedKubernetes: true,
235+
expectedSwarm: true,
220236
},
221237
{
222238
doc: "envOverridesConfigFile",
@@ -227,6 +243,7 @@ func TestOrchestratorSwitch(t *testing.T) {
227243
envOrchestrator: "swarm",
228244
expectedOrchestrator: "swarm",
229245
expectedKubernetes: false,
246+
expectedSwarm: true,
230247
},
231248
{
232249
doc: "flagOverridesEnv",
@@ -237,6 +254,7 @@ func TestOrchestratorSwitch(t *testing.T) {
237254
flagOrchestrator: "swarm",
238255
expectedOrchestrator: "swarm",
239256
expectedKubernetes: false,
257+
expectedSwarm: true,
240258
},
241259
}
242260

@@ -260,6 +278,7 @@ func TestOrchestratorSwitch(t *testing.T) {
260278
err := cli.Initialize(options)
261279
assert.NilError(t, err)
262280
assert.Check(t, is.Equal(testcase.expectedKubernetes, cli.ClientInfo().HasKubernetes()))
281+
assert.Check(t, is.Equal(testcase.expectedSwarm, cli.ClientInfo().HasSwarm()))
263282
assert.Check(t, is.Equal(testcase.expectedOrchestrator, string(cli.ClientInfo().Orchestrator)))
264283
})
265284
}

‎cli/command/orchestrator.go‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const (
1313
OrchestratorKubernetes = Orchestrator("kubernetes")
1414
// OrchestratorSwarm orchestrator
1515
OrchestratorSwarm = Orchestrator("swarm")
16+
// OrchestratorAll orchestrator
17+
OrchestratorAll = Orchestrator("all")
1618
orchestratorUnset = Orchestrator("unset")
1719

1820
defaultOrchestrator = OrchestratorSwarm
@@ -27,8 +29,10 @@ func normalize(value string) (Orchestrator, error) {
2729
return OrchestratorSwarm, nil
2830
case "":
2931
return orchestratorUnset, nil
32+
case "all":
33+
return OrchestratorAll, nil
3034
default:
31-
return defaultOrchestrator, fmt.Errorf("specified orchestrator %q is invalid, please use either kubernetes or swarm", value)
35+
return defaultOrchestrator, fmt.Errorf("specified orchestrator %q is invalid, please use either kubernetes, swarm or all", value)
3236
}
3337
}
3438

‎cli/command/stack/cmd.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package stack
22

33
import (
4+
"fmt"
5+
46
"github.com/docker/cli/cli"
57
"github.com/docker/cli/cli/command"
68
"github.com/spf13/cobra"
79
)
810

11+
var errUnsupportedAllOrchestrator = fmt.Errorf(`no orchestrator specified: use either "kubernetes" or "swarm"`)
12+
913
// NewStackCommand returns a cobra command for `stack` subcommands
1014
func NewStackCommand(dockerCli command.Cli) *cobra.Command {
1115
cmd := &cobra.Command{

‎cli/command/stack/deploy.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
1919
Args: cli.ExactArgs(1),
2020
RunE: func(cmd *cobra.Command, args []string) error {
2121
opts.Namespace = args[0]
22-
if dockerCli.ClientInfo().HasKubernetes() {
22+
switch {
23+
case dockerCli.ClientInfo().HasAll():
24+
return errUnsupportedAllOrchestrator
25+
case dockerCli.ClientInfo().HasKubernetes():
2326
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
2427
if err != nil {
2528
return err
2629
}
2730
return kubernetes.RunDeploy(kli, opts)
31+
default:
32+
return swarm.RunDeploy(dockerCli, opts)
2833
}
29-
return swarm.RunDeploy(dockerCli, opts)
3034
},
3135
}
3236

‎cli/command/stack/kubernetes/list.go‎

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,18 @@
11
package kubernetes
22

33
import (
4-
"sort"
5-
64
"github.com/docker/cli/cli/command/formatter"
75
"github.com/docker/cli/cli/command/stack/options"
86
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9-
"vbom.ml/util/sortorder"
107
)
118

12-
// RunList is the kubernetes implementation of docker stack ls
13-
func RunList(dockerCli *KubeCli, opts options.List) error {
14-
stacks, err := getStacks(dockerCli, opts.AllNamespaces)
15-
if err != nil {
16-
return err
17-
}
18-
format := opts.Format
19-
if format == "" || format == formatter.TableFormatKey {
20-
format = formatter.KubernetesStackTableFormat
21-
}
22-
stackCtx := formatter.Context{
23-
Output: dockerCli.Out(),
24-
Format: formatter.Format(format),
25-
}
26-
sort.Sort(byName(stacks))
27-
return formatter.StackWrite(stackCtx, stacks)
28-
}
29-
30-
type byName []*formatter.Stack
31-
32-
func (n byName) Len() int { return len(n) }
33-
func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
34-
func (n byName) Less(i, j int) bool { return sortorder.NaturalLess(n[i].Name, n[j].Name) }
35-
36-
func getStacks(kubeCli *KubeCli, allNamespaces bool) ([]*formatter.Stack, error) {
9+
// GetStacks lists the kubernetes stacks.
10+
func GetStacks(kubeCli *KubeCli, opts options.List) ([]*formatter.Stack, error) {
3711
composeClient, err := kubeCli.composeClient()
3812
if err != nil {
3913
return nil, err
4014
}
41-
stackSvc, err := composeClient.Stacks(allNamespaces)
15+
stackSvc, err := composeClient.Stacks(opts.AllNamespaces)
4216
if err != nil {
4317
return nil, err
4418
}

‎cli/command/stack/list.go‎

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package stack
22

33
import (
4+
"sort"
5+
46
"github.com/docker/cli/cli"
57
"github.com/docker/cli/cli/command"
8+
"github.com/docker/cli/cli/command/formatter"
69
"github.com/docker/cli/cli/command/stack/kubernetes"
710
"github.com/docker/cli/cli/command/stack/options"
811
"github.com/docker/cli/cli/command/stack/swarm"
912
"github.com/spf13/cobra"
13+
"vbom.ml/util/sortorder"
1014
)
1115

1216
func newListCommand(dockerCli command.Cli) *cobra.Command {
@@ -18,20 +22,51 @@ func newListCommand(dockerCli command.Cli) *cobra.Command {
1822
Short: "List stacks",
1923
Args: cli.NoArgs,
2024
RunE: func(cmd *cobra.Command, args []string) error {
21-
if dockerCli.ClientInfo().HasKubernetes() {
22-
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
23-
if err != nil {
24-
return err
25-
}
26-
return kubernetes.RunList(kli, opts)
27-
}
28-
return swarm.RunList(dockerCli, opts)
25+
return runList(cmd, dockerCli, opts)
2926
},
3027
}
3128

3229
flags := cmd.Flags()
3330
flags.StringVar(&opts.Format, "format", "", "Pretty-print stacks using a Go template")
3431
flags.BoolVarP(&opts.AllNamespaces, "all-namespaces", "", false, "List stacks among all Kubernetes namespaces")
3532
flags.SetAnnotation("all-namespaces", "kubernetes", nil)
33+
flags.SetAnnotation("all-namespaces", "experimentalCLI", nil)
3634
return cmd
3735
}
36+
37+
func runList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error {
38+
stacks := []*formatter.Stack{}
39+
if dockerCli.ClientInfo().HasSwarm() {
40+
ss, err := swarm.GetStacks(dockerCli)
41+
if err != nil {
42+
return err
43+
}
44+
stacks = append(stacks, ss...)
45+
}
46+
if dockerCli.ClientInfo().HasKubernetes() {
47+
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
48+
if err != nil {
49+
return err
50+
}
51+
ss, err := kubernetes.GetStacks(kli, opts)
52+
if err != nil {
53+
return err
54+
}
55+
stacks = append(stacks, ss...)
56+
}
57+
format := opts.Format
58+
if format == "" || format == formatter.TableFormatKey {
59+
format = formatter.SwarmStackTableFormat
60+
if dockerCli.ClientInfo().HasKubernetes() {
61+
format = formatter.KubernetesStackTableFormat
62+
}
63+
}
64+
stackCtx := formatter.Context{
65+
Output: dockerCli.Out(),
66+
Format: formatter.Format(format),
67+
}
68+
sort.Slice(stacks, func(i, j int) bool {
69+
return sortorder.NaturalLess(stacks[i].Name, stacks[j].Name)
70+
})
71+
return formatter.StackWrite(stackCtx, stacks)
72+
}

‎cli/command/stack/list_test.go‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func TestListErrors(t *testing.T) {
4848
for _, tc := range testCases {
4949
cmd := newListCommand(test.NewFakeCli(&fakeClient{
5050
serviceListFunc: tc.serviceListFunc,
51-
}))
51+
}, test.OrchestratorSwarm))
5252
cmd.SetArgs(tc.args)
5353
cmd.SetOutput(ioutil.Discard)
5454
for key, value := range tc.flags {
@@ -59,16 +59,17 @@ func TestListErrors(t *testing.T) {
5959
}
6060

6161
func TestListWithFormat(t *testing.T) {
62-
cli := test.NewFakeCli(&fakeClient{
63-
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
64-
return []swarm.Service{
65-
*Service(
66-
ServiceLabels(map[string]string{
67-
"com.docker.stack.namespace": "service-name-foo",
68-
}),
69-
)}, nil
70-
},
71-
})
62+
cli := test.NewFakeCli(
63+
&fakeClient{
64+
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
65+
return []swarm.Service{
66+
*Service(
67+
ServiceLabels(map[string]string{
68+
"com.docker.stack.namespace": "service-name-foo",
69+
}),
70+
)}, nil
71+
},
72+
}, test.OrchestratorSwarm)
7273
cmd := newListCommand(cli)
7374
cmd.Flags().Set("format", "{{ .Name }}")
7475
assert.NilError(t, cmd.Execute())
@@ -85,7 +86,7 @@ func TestListWithoutFormat(t *testing.T) {
8586
}),
8687
)}, nil
8788
},
88-
})
89+
}, test.OrchestratorSwarm)
8990
cmd := newListCommand(cli)
9091
assert.NilError(t, cmd.Execute())
9192
golden.Assert(t, cli.OutBuffer().String(), "stack-list-without-format.golden")
@@ -138,7 +139,7 @@ func TestListOrder(t *testing.T) {
138139
serviceListFunc: func(options types.ServiceListOptions) ([]swarm.Service, error) {
139140
return uc.swarmServices, nil
140141
},
141-
})
142+
}, test.OrchestratorSwarm)
142143
cmd := newListCommand(cli)
143144
assert.NilError(t, cmd.Execute())
144145
golden.Assert(t, cli.OutBuffer().String(), uc.golden)

‎cli/command/stack/ps.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ func newPsCommand(dockerCli command.Cli) *cobra.Command {
1919
Args: cli.ExactArgs(1),
2020
RunE: func(cmd *cobra.Command, args []string) error {
2121
opts.Namespace = args[0]
22-
if dockerCli.ClientInfo().HasKubernetes() {
22+
switch {
23+
case dockerCli.ClientInfo().HasAll():
24+
return errUnsupportedAllOrchestrator
25+
case dockerCli.ClientInfo().HasKubernetes():
2326
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
2427
if err != nil {
2528
return err
2629
}
2730
return kubernetes.RunPS(kli, opts)
31+
default:
32+
return swarm.RunPS(dockerCli, opts)
2833
}
29-
return swarm.RunPS(dockerCli, opts)
3034
},
3135
}
3236
flags := cmd.Flags()

‎cli/command/stack/remove.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
1919
Args: cli.RequiresMinArgs(1),
2020
RunE: func(cmd *cobra.Command, args []string) error {
2121
opts.Namespaces = args
22-
if dockerCli.ClientInfo().HasKubernetes() {
22+
switch {
23+
case dockerCli.ClientInfo().HasAll():
24+
return errUnsupportedAllOrchestrator
25+
case dockerCli.ClientInfo().HasKubernetes():
2326
kli, err := kubernetes.WrapCli(dockerCli, kubernetes.NewOptions(cmd.Flags()))
2427
if err != nil {
2528
return err
2629
}
2730
return kubernetes.RunRemove(kli, opts)
31+
default:
32+
return swarm.RunRemove(dockerCli, opts)
2833
}
29-
return swarm.RunRemove(dockerCli, opts)
3034
},
3135
}
3236
return cmd

0 commit comments

Comments
 (0)