1
0
mirror of https://github.com/docker/cli.git synced 2026-01-22 03:22:01 +03:00

remove obsolete mutli-orchestrator support

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof
2022-02-22 13:46:35 +01:00
parent 1d48749c1c
commit 193ede9b12
44 changed files with 186 additions and 581 deletions

View File

@@ -1,45 +1,20 @@
package stack
import (
"errors"
"fmt"
"strings"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type commonOptions struct {
orchestrator command.Orchestrator
}
func (o *commonOptions) Orchestrator() command.Orchestrator {
if o == nil {
return command.OrchestratorSwarm
}
return o.orchestrator
}
// NewStackCommand returns a cobra command for `stack` subcommands
func NewStackCommand(dockerCli command.Cli) *cobra.Command {
var opts commonOptions
cmd := &cobra.Command{
Use: "stack [OPTIONS]",
Short: "Manage Docker stacks",
Args: cli.NoArgs,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
orchestrator, err := getOrchestrator(dockerCli, cmd)
if err != nil {
return err
}
opts.orchestrator = orchestrator
hideOrchestrationFlags(cmd, orchestrator)
return checkSupportedFlag(cmd, orchestrator)
},
RunE: command.ShowHelp(dockerCli.Err()),
RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{
"version": "1.25",
},
@@ -50,62 +25,18 @@ func NewStackCommand(dockerCli command.Cli) *cobra.Command {
fmt.Fprintln(dockerCli.Err(), err)
return
}
if err := cmd.PersistentPreRunE(c, args); err != nil {
fmt.Fprintln(dockerCli.Err(), err)
return
}
hideOrchestrationFlags(c, opts.orchestrator)
defaultHelpFunc(c, args)
})
cmd.AddCommand(
newDeployCommand(dockerCli, &opts),
newListCommand(dockerCli, &opts),
newPsCommand(dockerCli, &opts),
newRemoveCommand(dockerCli, &opts),
newServicesCommand(dockerCli, &opts),
newDeployCommand(dockerCli),
newListCommand(dockerCli),
newPsCommand(dockerCli),
newRemoveCommand(dockerCli),
newServicesCommand(dockerCli),
)
flags := cmd.PersistentFlags()
flags.String("orchestrator", "", "Orchestrator to use (swarm|all)")
flags.SetAnnotation("orchestrator", "deprecated", nil)
flags.MarkDeprecated("orchestrator", "option will be ignored")
return cmd
}
func getOrchestrator(dockerCli command.Cli, cmd *cobra.Command) (command.Orchestrator, error) {
var orchestratorFlag string
if o, err := cmd.Flags().GetString("orchestrator"); err == nil {
orchestratorFlag = o
}
return dockerCli.StackOrchestrator(orchestratorFlag)
}
func hideOrchestrationFlags(cmd *cobra.Command, orchestrator command.Orchestrator) {
cmd.Flags().VisitAll(func(f *pflag.Flag) {
if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() {
f.Hidden = true
}
})
for _, subcmd := range cmd.Commands() {
hideOrchestrationFlags(subcmd, orchestrator)
}
}
func checkSupportedFlag(cmd *cobra.Command, orchestrator command.Orchestrator) error {
errs := []string{}
cmd.Flags().VisitAll(func(f *pflag.Flag) {
if !f.Changed {
return
}
if _, ok := f.Annotations["swarm"]; ok && !orchestrator.HasSwarm() {
errs = append(errs, fmt.Sprintf(`"--%s" is only supported on a Docker cli with swarm features enabled`, f.Name))
}
})
for _, subcmd := range cmd.Commands() {
if err := checkSupportedFlag(subcmd, orchestrator); err != nil {
errs = append(errs, err.Error())
}
}
if len(errs) > 0 {
return errors.New(strings.Join(errs, "\n"))
}
return nil
}

View File

@@ -11,7 +11,7 @@ import (
"github.com/spf13/pflag"
)
func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
func newDeployCommand(dockerCli command.Cli) *cobra.Command {
var opts options.Deploy
cmd := &cobra.Command{
@@ -28,7 +28,7 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma
if err != nil {
return err
}
return RunDeploy(dockerCli, cmd.Flags(), config, common.Orchestrator(), opts)
return RunDeploy(dockerCli, cmd.Flags(), config, opts)
},
}
@@ -47,7 +47,7 @@ func newDeployCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma
return cmd
}
// RunDeploy performs a stack deploy against the specified orchestrator
func RunDeploy(dockerCli command.Cli, flags *pflag.FlagSet, config *composetypes.Config, commonOrchestrator command.Orchestrator, opts options.Deploy) error {
// RunDeploy performs a stack deploy against the specified swarm cluster
func RunDeploy(dockerCli command.Cli, flags *pflag.FlagSet, config *composetypes.Config, opts options.Deploy) error {
return swarm.RunDeploy(dockerCli, opts, config)
}

View File

@@ -9,7 +9,7 @@ import (
)
func TestDeployWithEmptyName(t *testing.T) {
cmd := newDeployCommand(test.NewFakeCli(&fakeClient{}), nil)
cmd := newDeployCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"' '"})
cmd.SetOut(ioutil.Discard)

View File

@@ -8,10 +8,9 @@ import (
const (
// SwarmStackTableFormat is the default Swarm stack format
SwarmStackTableFormat formatter.Format = "table {{.Name}}\t{{.Services}}\t{{.Orchestrator}}"
SwarmStackTableFormat formatter.Format = "table {{.Name}}\t{{.Services}}"
stackServicesHeader = "SERVICES"
stackOrchestrastorHeader = "ORCHESTRATOR"
stackServicesHeader = "SERVICES"
// TableFormatKey is an alias for formatter.TableFormatKey
TableFormatKey = formatter.TableFormatKey
@@ -29,8 +28,6 @@ type Stack struct {
Name string
// Services is the number of the services
Services int
// Orchestrator is the platform where the stack is deployed
Orchestrator string
}
// StackWrite writes formatted stacks using the Context
@@ -54,9 +51,8 @@ type stackContext struct {
func newStackContext() *stackContext {
stackCtx := stackContext{}
stackCtx.Header = formatter.SubHeaderContext{
"Name": formatter.NameHeader,
"Services": stackServicesHeader,
"Orchestrator": stackOrchestrastorHeader,
"Name": formatter.NameHeader,
"Services": stackServicesHeader,
}
return &stackCtx
}
@@ -72,7 +68,3 @@ func (s *stackContext) Name() string {
func (s *stackContext) Services() string {
return strconv.Itoa(s.s.Services)
}
func (s *stackContext) Orchestrator() string {
return s.s.Orchestrator
}

View File

@@ -27,9 +27,9 @@ func TestStackContextWrite(t *testing.T) {
// Table format
{
formatter.Context{Format: SwarmStackTableFormat},
`NAME SERVICES ORCHESTRATOR
baz 2 orchestrator1
bar 1 orchestrator2
`NAME SERVICES
baz 2
bar 1
`,
},
{
@@ -49,8 +49,8 @@ bar
}
stacks := []*Stack{
{Name: "baz", Services: 2, Orchestrator: "orchestrator1"},
{Name: "bar", Services: 1, Orchestrator: "orchestrator2"},
{Name: "baz", Services: 2},
{Name: "bar", Services: 1},
}
for _, tc := range cases {
tc := tc

View File

@@ -12,7 +12,7 @@ import (
"github.com/spf13/cobra"
)
func newListCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
func newListCommand(dockerCli command.Cli) *cobra.Command {
opts := options.List{}
cmd := &cobra.Command{
@@ -21,7 +21,7 @@ func newListCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command
Short: "List stacks",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return RunList(cmd, dockerCli, opts, common.orchestrator)
return RunList(cmd, dockerCli, opts)
},
}
@@ -30,16 +30,14 @@ func newListCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command
return cmd
}
// RunList performs a stack list against the specified orchestrator
func RunList(cmd *cobra.Command, dockerCli command.Cli, opts options.List, orchestrator command.Orchestrator) error {
// RunList performs a stack list against the specified swarm cluster
func RunList(cmd *cobra.Command, dockerCli command.Cli, opts options.List) error {
stacks := []*formatter.Stack{}
if orchestrator.HasSwarm() {
ss, err := swarm.GetStacks(dockerCli)
if err != nil {
return err
}
stacks = append(stacks, ss...)
ss, err := swarm.GetStacks(dockerCli)
if err != nil {
return err
}
stacks = append(stacks, ss...)
return format(dockerCli, opts, stacks)
}

View File

@@ -4,7 +4,6 @@ import (
"io/ioutil"
"testing"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/test"
. "github.com/docker/cli/internal/test/builders" // Import builders to get the builder function as package function
"github.com/docker/docker/api/types"
@@ -14,10 +13,6 @@ import (
"gotest.tools/v3/golden"
)
var (
orchestrator = commonOptions{orchestrator: command.OrchestratorSwarm}
)
func TestListErrors(t *testing.T) {
testCases := []struct {
args []string
@@ -52,7 +47,7 @@ func TestListErrors(t *testing.T) {
for _, tc := range testCases {
cmd := newListCommand(test.NewFakeCli(&fakeClient{
serviceListFunc: tc.serviceListFunc,
}), &orchestrator)
}))
cmd.SetArgs(tc.args)
cmd.SetOut(ioutil.Discard)
for key, value := range tc.flags {
@@ -118,7 +113,7 @@ func TestStackList(t *testing.T) {
return services, nil
},
})
cmd := newListCommand(cli, &orchestrator)
cmd := newListCommand(cli)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}

View File

@@ -10,7 +10,7 @@ import (
"github.com/spf13/pflag"
)
func newPsCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
func newPsCommand(dockerCli command.Cli) *cobra.Command {
opts := options.PS{Filter: cliopts.NewFilterOpt()}
cmd := &cobra.Command{
@@ -22,7 +22,7 @@ func newPsCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
if err := validateStackName(opts.Namespace); err != nil {
return err
}
return RunPs(dockerCli, cmd.Flags(), common.Orchestrator(), opts)
return RunPs(dockerCli, cmd.Flags(), opts)
},
}
flags := cmd.Flags()
@@ -34,7 +34,7 @@ func newPsCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
return cmd
}
// RunPs performs a stack ps against the specified orchestrator
func RunPs(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.PS) error {
// RunPs performs a stack ps against the specified swarm cluster
func RunPs(dockerCli command.Cli, flags *pflag.FlagSet, opts options.PS) error {
return swarm.RunPS(dockerCli, opts)
}

View File

@@ -43,7 +43,7 @@ func TestStackPsErrors(t *testing.T) {
for _, tc := range testCases {
cmd := newPsCommand(test.NewFakeCli(&fakeClient{
taskListFunc: tc.taskListFunc,
}), &orchestrator)
}))
cmd.SetArgs(tc.args)
cmd.SetOut(ioutil.Discard)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
@@ -164,7 +164,7 @@ func TestStackPs(t *testing.T) {
})
cli.SetConfigFile(&tc.config)
cmd := newPsCommand(cli, &orchestrator)
cmd := newPsCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)

View File

@@ -9,7 +9,7 @@ import (
"github.com/spf13/pflag"
)
func newRemoveCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
func newRemoveCommand(dockerCli command.Cli) *cobra.Command {
var opts options.Remove
cmd := &cobra.Command{
@@ -22,13 +22,13 @@ func newRemoveCommand(dockerCli command.Cli, common *commonOptions) *cobra.Comma
if err := validateStackNames(opts.Namespaces); err != nil {
return err
}
return RunRemove(dockerCli, cmd.Flags(), common.Orchestrator(), opts)
return RunRemove(dockerCli, cmd.Flags(), opts)
},
}
return cmd
}
// RunRemove performs a stack remove against the specified orchestrator
func RunRemove(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Remove) error {
// RunRemove performs a stack remove against the specified swarm cluster
func RunRemove(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Remove) error {
return swarm.RunRemove(dockerCli, opts)
}

View File

@@ -42,7 +42,7 @@ func fakeClientForRemoveStackTest(version string) *fakeClient {
}
func TestRemoveWithEmptyName(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}), &orchestrator)
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"good", "' '", "alsogood"})
cmd.SetOut(ioutil.Discard)
@@ -51,7 +51,7 @@ func TestRemoveWithEmptyName(t *testing.T) {
func TestRemoveStackVersion124DoesNotRemoveConfigsOrSecrets(t *testing.T) {
client := fakeClientForRemoveStackTest("1.24")
cmd := newRemoveCommand(test.NewFakeCli(client), &orchestrator)
cmd := newRemoveCommand(test.NewFakeCli(client))
cmd.SetArgs([]string{"foo", "bar"})
assert.NilError(t, cmd.Execute())
@@ -63,7 +63,7 @@ func TestRemoveStackVersion124DoesNotRemoveConfigsOrSecrets(t *testing.T) {
func TestRemoveStackVersion125DoesNotRemoveConfigs(t *testing.T) {
client := fakeClientForRemoveStackTest("1.25")
cmd := newRemoveCommand(test.NewFakeCli(client), &orchestrator)
cmd := newRemoveCommand(test.NewFakeCli(client))
cmd.SetArgs([]string{"foo", "bar"})
assert.NilError(t, cmd.Execute())
@@ -75,7 +75,7 @@ func TestRemoveStackVersion125DoesNotRemoveConfigs(t *testing.T) {
func TestRemoveStackVersion130RemovesEverything(t *testing.T) {
client := fakeClientForRemoveStackTest("1.30")
cmd := newRemoveCommand(test.NewFakeCli(client), &orchestrator)
cmd := newRemoveCommand(test.NewFakeCli(client))
cmd.SetArgs([]string{"foo", "bar"})
assert.NilError(t, cmd.Execute())
@@ -106,7 +106,7 @@ func TestRemoveStackSkipEmpty(t *testing.T) {
configs: allConfigs,
}
fakeCli := test.NewFakeCli(fakeClient)
cmd := newRemoveCommand(fakeCli, &orchestrator)
cmd := newRemoveCommand(fakeCli)
cmd.SetArgs([]string{"foo", "bar"})
assert.NilError(t, cmd.Execute())
@@ -154,7 +154,7 @@ func TestRemoveContinueAfterError(t *testing.T) {
return nil
},
}
cmd := newRemoveCommand(test.NewFakeCli(cli), &orchestrator)
cmd := newRemoveCommand(test.NewFakeCli(cli))
cmd.SetOut(ioutil.Discard)
cmd.SetArgs([]string{"foo", "bar"})

View File

@@ -17,7 +17,7 @@ import (
"github.com/spf13/pflag"
)
func newServicesCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
func newServicesCommand(dockerCli command.Cli) *cobra.Command {
opts := options.Services{Filter: cliopts.NewFilterOpt()}
cmd := &cobra.Command{
@@ -29,7 +29,7 @@ func newServicesCommand(dockerCli command.Cli, common *commonOptions) *cobra.Com
if err := validateStackName(opts.Namespace); err != nil {
return err
}
return RunServices(dockerCli, cmd.Flags(), common.Orchestrator(), opts)
return RunServices(dockerCli, cmd.Flags(), opts)
},
}
flags := cmd.Flags()
@@ -39,17 +39,17 @@ func newServicesCommand(dockerCli command.Cli, common *commonOptions) *cobra.Com
return cmd
}
// RunServices performs a stack services against the specified orchestrator
func RunServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Services) error {
services, err := GetServices(dockerCli, flags, commonOrchestrator, opts)
// RunServices performs a stack services against the specified swarm cluster
func RunServices(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Services) error {
services, err := GetServices(dockerCli, flags, opts)
if err != nil {
return err
}
return formatWrite(dockerCli, services, opts)
}
// GetServices returns the services for the specified orchestrator
func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, commonOrchestrator command.Orchestrator, opts options.Services) ([]swarmtypes.Service, error) {
// GetServices returns the services for the specified swarm cluster
func GetServices(dockerCli command.Cli, flags *pflag.FlagSet, opts options.Services) ([]swarmtypes.Service, error) {
return swarm.GetServices(dockerCli, opts)
}

View File

@@ -74,7 +74,7 @@ func TestStackServicesErrors(t *testing.T) {
nodeListFunc: tc.nodeListFunc,
taskListFunc: tc.taskListFunc,
})
cmd := newServicesCommand(cli, &orchestrator)
cmd := newServicesCommand(cli)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
@@ -86,7 +86,7 @@ func TestStackServicesErrors(t *testing.T) {
}
func TestRunServicesWithEmptyName(t *testing.T) {
cmd := newServicesCommand(test.NewFakeCli(&fakeClient{}), &orchestrator)
cmd := newServicesCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"' '"})
cmd.SetOut(ioutil.Discard)
@@ -99,7 +99,7 @@ func TestStackServicesEmptyServiceList(t *testing.T) {
return []swarm.Service{}, nil
},
})
cmd := newServicesCommand(fakeCli, &orchestrator)
cmd := newServicesCommand(fakeCli)
cmd.SetArgs([]string{"foo"})
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("", fakeCli.OutBuffer().String()))
@@ -112,7 +112,7 @@ func TestStackServicesWithQuietOption(t *testing.T) {
return []swarm.Service{*Service(ServiceID("id-foo"))}, nil
},
})
cmd := newServicesCommand(cli, &orchestrator)
cmd := newServicesCommand(cli)
cmd.Flags().Set("quiet", "true")
cmd.SetArgs([]string{"foo"})
assert.NilError(t, cmd.Execute())
@@ -127,7 +127,7 @@ func TestStackServicesWithFormat(t *testing.T) {
}, nil
},
})
cmd := newServicesCommand(cli, &orchestrator)
cmd := newServicesCommand(cli)
cmd.SetArgs([]string{"foo"})
cmd.Flags().Set("format", "{{ .Name }}")
assert.NilError(t, cmd.Execute())
@@ -145,7 +145,7 @@ func TestStackServicesWithConfigFormat(t *testing.T) {
cli.SetConfigFile(&configfile.ConfigFile{
ServicesFormat: "{{ .Name }}",
})
cmd := newServicesCommand(cli, &orchestrator)
cmd := newServicesCommand(cli)
cmd.SetArgs([]string{"foo"})
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "stack-services-with-config-format.golden")
@@ -168,7 +168,7 @@ func TestStackServicesWithoutFormat(t *testing.T) {
)}, nil
},
})
cmd := newServicesCommand(cli, &orchestrator)
cmd := newServicesCommand(cli)
cmd.SetArgs([]string{"foo"})
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "stack-services-without-format.golden")

View File

@@ -29,9 +29,8 @@ func GetStacks(dockerCli command.Cli) ([]*formatter.Stack, error) {
ztack, ok := m[name]
if !ok {
m[name] = &formatter.Stack{
Name: name,
Services: 1,
Orchestrator: "Swarm",
Name: name,
Services: 1,
}
} else {
ztack.Services++

View File

@@ -1,4 +1,4 @@
NAME SERVICES ORCHESTRATOR
service-name-1-foo 1 Swarm
service-name-2-foo 1 Swarm
service-name-10-foo 1 Swarm
NAME SERVICES
service-name-1-foo 1
service-name-2-foo 1
service-name-10-foo 1

View File

@@ -1,3 +1,3 @@
NAME SERVICES ORCHESTRATOR
service-name-bar 1 Swarm
service-name-foo 1 Swarm
NAME SERVICES
service-name-bar 1
service-name-foo 1

View File

@@ -1,2 +1,2 @@
NAME SERVICES ORCHESTRATOR
service-name-foo 1 Swarm
NAME SERVICES
service-name-foo 1