diff --git a/cli/command/cli.go b/cli/command/cli.go index 97d72993332e..c01a66d886e3 100644 --- a/cli/command/cli.go +++ b/cli/command/cli.go @@ -60,7 +60,6 @@ type Cli interface { ContentTrustEnabled() bool ContextStore() store.Store CurrentContext() string - StackOrchestrator(flagValue string) (Orchestrator, error) DockerEndpoint() docker.Endpoint } @@ -367,25 +366,6 @@ func (cli *DockerCli) CurrentContext() string { return cli.currentContext } -// StackOrchestrator resolves which stack orchestrator is in use -func (cli *DockerCli) StackOrchestrator(flagValue string) (Orchestrator, error) { - currentContext := cli.CurrentContext() - ctxRaw, err := cli.ContextStore().GetMetadata(currentContext) - if store.IsErrContextDoesNotExist(err) { - // case where the currentContext has been removed (CLI behavior is to fallback to using DOCKER_HOST based resolution) - return GetStackOrchestrator(flagValue, "", cli.ConfigFile().StackOrchestrator, cli.Err()) - } - if err != nil { - return "", err - } - ctxMeta, err := GetDockerContext(ctxRaw) - if err != nil { - return "", err - } - ctxOrchestrator := string(ctxMeta.StackOrchestrator) - return GetStackOrchestrator(flagValue, ctxOrchestrator, cli.ConfigFile().StackOrchestrator, cli.Err()) -} - // DockerEndpoint returns the current docker endpoint func (cli *DockerCli) DockerEndpoint() docker.Endpoint { return cli.dockerEndpoint diff --git a/cli/command/context.go b/cli/command/context.go index 9c357a99d2ab..f6367c4a480e 100644 --- a/cli/command/context.go +++ b/cli/command/context.go @@ -9,9 +9,8 @@ import ( // DockerContext is a typed representation of what we put in Context metadata type DockerContext struct { - Description string - StackOrchestrator Orchestrator - AdditionalFields map[string]interface{} + Description string + AdditionalFields map[string]interface{} } // MarshalJSON implements custom JSON marshalling @@ -20,9 +19,6 @@ func (dc DockerContext) MarshalJSON() ([]byte, error) { if dc.Description != "" { s["Description"] = dc.Description } - if dc.StackOrchestrator != "" { - s["StackOrchestrator"] = dc.StackOrchestrator - } if dc.AdditionalFields != nil { for k, v := range dc.AdditionalFields { s[k] = v @@ -41,8 +37,6 @@ func (dc *DockerContext) UnmarshalJSON(payload []byte) error { switch k { case "Description": dc.Description = v.(string) - case "StackOrchestrator": - dc.StackOrchestrator = Orchestrator(v.(string)) default: if dc.AdditionalFields == nil { dc.AdditionalFields = make(map[string]interface{}) diff --git a/cli/command/context/create.go b/cli/command/context/create.go index 9f39f7d39c7c..a1a7dd273308 100644 --- a/cli/command/context/create.go +++ b/cli/command/context/create.go @@ -3,7 +3,6 @@ package context import ( "bytes" "fmt" - "github.com/sirupsen/logrus" "text/tabwriter" "github.com/docker/cli/cli" @@ -59,10 +58,12 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command { "default-stack-orchestrator", "", "Default orchestrator for stack operations to use with this context (swarm|kubernetes|all)") flags.SetAnnotation("default-stack-orchestrator", "deprecated", nil) + flags.MarkDeprecated("default-stack-orchestrator", "option will be ignored") flags.StringToStringVar(&opts.Docker, "docker", nil, "set the docker endpoint") flags.StringToStringVar(&opts.Kubernetes, "kubernetes", nil, "set the kubernetes endpoint") flags.SetAnnotation("kubernetes", "kubernetes", nil) flags.SetAnnotation("kubernetes", "deprecated", nil) + flags.MarkDeprecated("kubernetes", "option will be ignored") flags.StringVar(&opts.From, "from", "", "create context from a named context") return cmd } @@ -70,20 +71,17 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command { // RunCreate creates a Docker context func RunCreate(cli command.Cli, o *CreateOptions) error { s := cli.ContextStore() - if err := checkContextNameForCreation(s, o.Name); err != nil { - return err - } - stackOrchestrator, err := command.NormalizeOrchestrator(o.DefaultStackOrchestrator) + err := checkContextNameForCreation(s, o.Name) if err != nil { - return errors.Wrap(err, "unable to parse default-stack-orchestrator") + return err } switch { case o.From == "" && o.Docker == nil && o.Kubernetes == nil: - err = createFromExistingContext(s, cli.CurrentContext(), stackOrchestrator, o) + err = createFromExistingContext(s, cli.CurrentContext(), o) case o.From != "": - err = createFromExistingContext(s, o.From, stackOrchestrator, o) + err = createFromExistingContext(s, o.From, o) default: - err = createNewContext(o, stackOrchestrator, cli, s) + err = createNewContext(o, cli, s) } if err == nil { fmt.Fprintln(cli.Out(), o.Name) @@ -92,11 +90,11 @@ func RunCreate(cli command.Cli, o *CreateOptions) error { return err } -func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator, cli command.Cli, s store.Writer) error { +func createNewContext(o *CreateOptions, cli command.Cli, s store.Writer) error { if o.Docker == nil { return errors.New("docker endpoint configuration is required") } - contextMetadata := newContextMetadata(stackOrchestrator, o) + contextMetadata := newContextMetadata(o) contextTLSData := store.ContextTLSData{ Endpoints: make(map[string]store.EndpointTLSData), } @@ -108,10 +106,7 @@ func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator, if dockerTLS != nil { contextTLSData.Endpoints[docker.DockerEndpoint] = *dockerTLS } - if len(o.Kubernetes) != 0 { - logrus.Warn("kubernetes orchestrator is deprecated") - } - if err := validateEndpointsAndOrchestrator(contextMetadata); err != nil { + if err := validateEndpoints(contextMetadata); err != nil { return err } if err := s.CreateOrUpdate(contextMetadata); err != nil { @@ -136,26 +131,24 @@ func checkContextNameForCreation(s store.Reader, name string) error { return nil } -func createFromExistingContext(s store.ReaderWriter, fromContextName string, stackOrchestrator command.Orchestrator, o *CreateOptions) error { +func createFromExistingContext(s store.ReaderWriter, fromContextName string, o *CreateOptions) error { if len(o.Docker) != 0 || len(o.Kubernetes) != 0 { return errors.New("cannot use --docker or --kubernetes flags when --from is set") } - reader := store.Export(fromContextName, &descriptionAndOrchestratorStoreDecorator{ - Reader: s, - description: o.Description, - orchestrator: stackOrchestrator, + reader := store.Export(fromContextName, &descriptionDecorator{ + Reader: s, + description: o.Description, }) defer reader.Close() return store.Import(o.Name, s, reader) } -type descriptionAndOrchestratorStoreDecorator struct { +type descriptionDecorator struct { store.Reader - description string - orchestrator command.Orchestrator + description string } -func (d *descriptionAndOrchestratorStoreDecorator) GetMetadata(name string) (store.Metadata, error) { +func (d *descriptionDecorator) GetMetadata(name string) (store.Metadata, error) { c, err := d.Reader.GetMetadata(name) if err != nil { return c, err @@ -167,19 +160,15 @@ func (d *descriptionAndOrchestratorStoreDecorator) GetMetadata(name string) (sto if d.description != "" { typedContext.Description = d.description } - if d.orchestrator != command.Orchestrator("") { - typedContext.StackOrchestrator = d.orchestrator - } c.Metadata = typedContext return c, nil } -func newContextMetadata(stackOrchestrator command.Orchestrator, o *CreateOptions) store.Metadata { +func newContextMetadata(o *CreateOptions) store.Metadata { return store.Metadata{ Endpoints: make(map[string]interface{}), Metadata: command.DockerContext{ - Description: o.Description, - StackOrchestrator: stackOrchestrator, + Description: o.Description, }, Name: o.Name, } diff --git a/cli/command/context/create_test.go b/cli/command/context/create_test.go index 9afa5172519f..945ae2368454 100644 --- a/cli/command/context/create_test.go +++ b/cli/command/context/create_test.go @@ -12,7 +12,6 @@ import ( "github.com/docker/cli/cli/context/store" "github.com/docker/cli/internal/test" "gotest.tools/v3/assert" - "gotest.tools/v3/env" ) func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) (*test.FakeCli, func()) { @@ -33,8 +32,7 @@ func makeFakeCli(t *testing.T, opts ...func(*test.FakeCli)) (*test.FakeCli, func }, }, Metadata: command.DockerContext{ - Description: "", - StackOrchestrator: command.OrchestratorSwarm, + Description: "", }, Name: command.DefaultContextName, }, @@ -59,7 +57,7 @@ func withCliConfig(configFile *configfile.ConfigFile) func(*test.FakeCli) { } } -func TestCreateInvalids(t *testing.T) { +func TestCreate(t *testing.T) { cli, cleanup := makeFakeCli(t) defer cleanup() assert.NilError(t, cli.ContextStore().CreateOrUpdate(store.Metadata{Name: "existing-context"})) @@ -102,7 +100,7 @@ func TestCreateInvalids(t *testing.T) { Name: "invalid-orchestrator", DefaultStackOrchestrator: "invalid", }, - expecterErr: `specified orchestrator "invalid" is invalid, please use either kubernetes, swarm or all`, + expecterErr: "", }, { options: CreateOptions{ @@ -158,37 +156,25 @@ func TestCreateOrchestratorEmpty(t *testing.T) { func TestCreateFromContext(t *testing.T) { cases := []struct { - name string - description string - orchestrator string - expectedDescription string - docker map[string]string - kubernetes map[string]string - expectedOrchestrator command.Orchestrator + name string + description string + expectedDescription string + docker map[string]string + kubernetes map[string]string }{ { - name: "no-override", - expectedDescription: "original description", - expectedOrchestrator: command.OrchestratorSwarm, - }, - { - name: "override-description", - description: "new description", - expectedDescription: "new description", - expectedOrchestrator: command.OrchestratorSwarm, + name: "no-override", + expectedDescription: "original description", }, { - name: "override-orchestrator", - orchestrator: "kubernetes", - expectedDescription: "original description", - expectedOrchestrator: command.OrchestratorKubernetes, + name: "override-description", + description: "new description", + expectedDescription: "new description", }, } cli, cleanup := makeFakeCli(t) defer cleanup() - revert := env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig") - defer revert() cli.ResetOutputBuffers() assert.NilError(t, RunCreate(cli, &CreateOptions{ Name: "original", @@ -196,10 +182,6 @@ func TestCreateFromContext(t *testing.T) { Docker: map[string]string{ keyHost: "tcp://42.42.42.42:2375", }, - Kubernetes: map[string]string{ - keyFrom: "default", - }, - DefaultStackOrchestrator: "swarm", })) assertContextCreateLogging(t, cli, "original") @@ -210,10 +192,6 @@ func TestCreateFromContext(t *testing.T) { Docker: map[string]string{ keyHost: "tcp://24.24.24.24:2375", }, - Kubernetes: map[string]string{ - keyFrom: "default", - }, - DefaultStackOrchestrator: "swarm", })) assertContextCreateLogging(t, cli, "dummy") @@ -224,12 +202,10 @@ func TestCreateFromContext(t *testing.T) { t.Run(c.name, func(t *testing.T) { cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ - From: "original", - Name: c.name, - Description: c.description, - DefaultStackOrchestrator: c.orchestrator, - Docker: c.docker, - Kubernetes: c.kubernetes, + From: "original", + Name: c.name, + Description: c.description, + Docker: c.docker, }) assert.NilError(t, err) assertContextCreateLogging(t, cli, c.name) @@ -240,7 +216,6 @@ func TestCreateFromContext(t *testing.T) { dockerEndpoint, err := docker.EndpointFromContext(newContext) assert.NilError(t, err) assert.Equal(t, newContextTyped.Description, c.expectedDescription) - assert.Equal(t, newContextTyped.StackOrchestrator, c.expectedOrchestrator) assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375") }) } @@ -248,29 +223,24 @@ func TestCreateFromContext(t *testing.T) { func TestCreateFromCurrent(t *testing.T) { cases := []struct { - name string - description string - orchestrator string - expectedDescription string - expectedOrchestrator command.Orchestrator + name string + description string + orchestrator string + expectedDescription string }{ { - name: "no-override", - expectedDescription: "original description", - expectedOrchestrator: command.OrchestratorSwarm, + name: "no-override", + expectedDescription: "original description", }, { - name: "override-description", - description: "new description", - expectedDescription: "new description", - expectedOrchestrator: command.OrchestratorSwarm, + name: "override-description", + description: "new description", + expectedDescription: "new description", }, } cli, cleanup := makeFakeCli(t) defer cleanup() - revert := env.Patch(t, "KUBECONFIG", "./testdata/test-kubeconfig") - defer revert() cli.ResetOutputBuffers() assert.NilError(t, RunCreate(cli, &CreateOptions{ Name: "original", @@ -278,10 +248,6 @@ func TestCreateFromCurrent(t *testing.T) { Docker: map[string]string{ keyHost: "tcp://42.42.42.42:2375", }, - Kubernetes: map[string]string{ - keyFrom: "default", - }, - DefaultStackOrchestrator: "swarm", })) assertContextCreateLogging(t, cli, "original") @@ -292,9 +258,8 @@ func TestCreateFromCurrent(t *testing.T) { t.Run(c.name, func(t *testing.T) { cli.ResetOutputBuffers() err := RunCreate(cli, &CreateOptions{ - Name: c.name, - Description: c.description, - DefaultStackOrchestrator: c.orchestrator, + Name: c.name, + Description: c.description, }) assert.NilError(t, err) assertContextCreateLogging(t, cli, c.name) @@ -305,7 +270,6 @@ func TestCreateFromCurrent(t *testing.T) { dockerEndpoint, err := docker.EndpointFromContext(newContext) assert.NilError(t, err) assert.Equal(t, newContextTyped.Description, c.expectedDescription) - assert.Equal(t, newContextTyped.StackOrchestrator, c.expectedOrchestrator) assert.Equal(t, dockerEndpoint.Host, "tcp://42.42.42.42:2375") }) } diff --git a/cli/command/context/list.go b/cli/command/context/list.go index 21799916d775..3bffcd4d0f1b 100644 --- a/cli/command/context/list.go +++ b/cli/command/context/list.go @@ -59,11 +59,10 @@ func runList(dockerCli command.Cli, opts *listOptions) error { meta.Description = "Current DOCKER_HOST based configuration" } desc := formatter.ClientContext{ - Name: rawMeta.Name, - Current: rawMeta.Name == curContext, - Description: meta.Description, - StackOrchestrator: string(meta.StackOrchestrator), - DockerEndpoint: dockerEndpoint.Host, + Name: rawMeta.Name, + Current: rawMeta.Name == curContext, + Description: meta.Description, + DockerEndpoint: dockerEndpoint.Host, } contexts = append(contexts, &desc) } diff --git a/cli/command/context/testdata/inspect.golden b/cli/command/context/testdata/inspect.golden index 0e9bedf092ef..ffc790180d2b 100644 --- a/cli/command/context/testdata/inspect.golden +++ b/cli/command/context/testdata/inspect.golden @@ -2,8 +2,7 @@ { "Name": "current", "Metadata": { - "Description": "description of current", - "StackOrchestrator": "all" + "Description": "description of current" }, "Endpoints": { "docker": { diff --git a/cli/command/context/testdata/list.golden b/cli/command/context/testdata/list.golden index 3c2f28463832..aceb43ec60b1 100644 --- a/cli/command/context/testdata/list.golden +++ b/cli/command/context/testdata/list.golden @@ -1,5 +1,5 @@ -NAME DESCRIPTION DOCKER ENDPOINT ORCHESTRATOR -current * description of current https://someswarmserver.example.com all -default Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm -other description of other https://someswarmserver.example.com all -unset description of unset https://someswarmserver.example.com +NAME DESCRIPTION DOCKER ENDPOINT +current * description of current https://someswarmserver.example.com +default Current DOCKER_HOST based configuration unix:///var/run/docker.sock +other description of other https://someswarmserver.example.com +unset description of unset https://someswarmserver.example.com diff --git a/cli/command/context/update.go b/cli/command/context/update.go index 55f775037d67..96bc4486accc 100644 --- a/cli/command/context/update.go +++ b/cli/command/context/update.go @@ -3,7 +3,6 @@ package context import ( "bytes" "fmt" - "github.com/sirupsen/logrus" "text/tabwriter" "github.com/docker/cli/cli" @@ -58,10 +57,12 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command { "default-stack-orchestrator", "", "Default orchestrator for stack operations to use with this context (swarm|kubernetes|all)") flags.SetAnnotation("default-stack-orchestrator", "deprecated", nil) + flags.MarkDeprecated("default-stack-orchestrator", "option will be ignored") flags.StringToStringVar(&opts.Docker, "docker", nil, "set the docker endpoint") flags.StringToStringVar(&opts.Kubernetes, "kubernetes", nil, "set the kubernetes endpoint") flags.SetAnnotation("kubernetes", "kubernetes", nil) flags.SetAnnotation("kubernetes", "deprecated", nil) + flags.MarkDeprecated("kubernetes", "option will be ignored") return cmd } @@ -79,13 +80,6 @@ func RunUpdate(cli command.Cli, o *UpdateOptions) error { if err != nil { return err } - if o.DefaultStackOrchestrator != "" { - stackOrchestrator, err := command.NormalizeOrchestrator(o.DefaultStackOrchestrator) - if err != nil { - return errors.Wrap(err, "unable to parse default-stack-orchestrator") - } - dockerContext.StackOrchestrator = stackOrchestrator - } if o.Description != "" { dockerContext.Description = o.Description } @@ -102,10 +96,7 @@ func RunUpdate(cli command.Cli, o *UpdateOptions) error { c.Endpoints[docker.DockerEndpoint] = dockerEP tlsDataToReset[docker.DockerEndpoint] = dockerTLS } - if len(o.Kubernetes) != 0 { - logrus.Warn("kubernetes orchestrator is deprecated") - } - if err := validateEndpointsAndOrchestrator(c); err != nil { + if err := validateEndpoints(c); err != nil { return err } if err := s.CreateOrUpdate(c); err != nil { @@ -122,7 +113,7 @@ func RunUpdate(cli command.Cli, o *UpdateOptions) error { return nil } -func validateEndpointsAndOrchestrator(c store.Metadata) error { +func validateEndpoints(c store.Metadata) error { _, err := command.GetDockerContext(c) return err } diff --git a/cli/command/context/update_test.go b/cli/command/context/update_test.go index 3760f558120a..2593fae902ff 100644 --- a/cli/command/context/update_test.go +++ b/cli/command/context/update_test.go @@ -28,7 +28,6 @@ func TestUpdateDescriptionOnly(t *testing.T) { assert.NilError(t, err) dc, err := command.GetDockerContext(c) assert.NilError(t, err) - assert.Equal(t, dc.StackOrchestrator, command.OrchestratorSwarm) assert.Equal(t, dc.Description, "description") assert.Equal(t, "test\n", cli.OutBuffer().String()) @@ -49,7 +48,6 @@ func TestUpdateDockerOnly(t *testing.T) { assert.NilError(t, err) dc, err := command.GetDockerContext(c) assert.NilError(t, err) - assert.Equal(t, dc.StackOrchestrator, command.OrchestratorSwarm) assert.Equal(t, dc.Description, "description of test") assert.Check(t, cmp.Contains(c.Endpoints, docker.DockerEndpoint)) assert.Equal(t, c.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta).Host, "tcp://some-host") diff --git a/cli/command/context_test.go b/cli/command/context_test.go index 28a33463bea7..0f5d9a88d242 100644 --- a/cli/command/context_test.go +++ b/cli/command/context_test.go @@ -9,19 +9,17 @@ import ( func TestDockerContextMetadataKeepAdditionalFields(t *testing.T) { c := DockerContext{ - Description: "test", - StackOrchestrator: OrchestratorSwarm, + Description: "test", AdditionalFields: map[string]interface{}{ "foo": "bar", }, } jsonBytes, err := json.Marshal(c) assert.NilError(t, err) - assert.Equal(t, `{"Description":"test","StackOrchestrator":"swarm","foo":"bar"}`, string(jsonBytes)) + assert.Equal(t, `{"Description":"test","foo":"bar"}`, string(jsonBytes)) var c2 DockerContext assert.NilError(t, json.Unmarshal(jsonBytes, &c2)) assert.Equal(t, c2.AdditionalFields["foo"], "bar") - assert.Equal(t, c2.StackOrchestrator, OrchestratorSwarm) assert.Equal(t, c2.Description, "test") } diff --git a/cli/command/defaultcontextstore.go b/cli/command/defaultcontextstore.go index 3140dc503055..4f8e2ef52360 100644 --- a/cli/command/defaultcontextstore.go +++ b/cli/command/defaultcontextstore.go @@ -41,23 +41,18 @@ type EndpointDefaultResolver interface { // the lack of a default (e.g. because the config file which // would contain it is missing). If there is no default then // returns nil, nil, nil. - ResolveDefault(Orchestrator) (interface{}, *store.EndpointTLSData, error) + ResolveDefault() (interface{}, *store.EndpointTLSData, error) } // ResolveDefaultContext creates a Metadata for the current CLI invocation parameters func ResolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.ConfigFile, storeconfig store.Config, stderr io.Writer) (*DefaultContext, error) { - stackOrchestrator, err := GetStackOrchestrator("", "", config.StackOrchestrator, stderr) - if err != nil { - return nil, err - } contextTLSData := store.ContextTLSData{ Endpoints: make(map[string]store.EndpointTLSData), } contextMetadata := store.Metadata{ Endpoints: make(map[string]interface{}), Metadata: DockerContext{ - Description: "", - StackOrchestrator: stackOrchestrator, + Description: "", }, Name: DefaultContextName, } @@ -77,7 +72,7 @@ func ResolveDefaultContext(opts *cliflags.CommonOptions, config *configfile.Conf } ep := get() if i, ok := ep.(EndpointDefaultResolver); ok { - meta, tls, err := i.ResolveDefault(stackOrchestrator) + meta, tls, err := i.ResolveDefault() if err != nil { return err } diff --git a/cli/command/defaultcontextstore_test.go b/cli/command/defaultcontextstore_test.go index 3c36dc0dcb97..1bed50f60889 100644 --- a/cli/command/defaultcontextstore_test.go +++ b/cli/command/defaultcontextstore_test.go @@ -71,7 +71,6 @@ func TestDefaultContextInitializer(t *testing.T) { }, cli.ConfigFile(), DefaultContextStoreConfig(), cli.Err()) assert.NilError(t, err) assert.Equal(t, "default", ctx.Meta.Name) - assert.Equal(t, OrchestratorSwarm, ctx.Meta.Metadata.(DockerContext).StackOrchestrator) assert.DeepEqual(t, "ssh://someswarmserver", ctx.Meta.Endpoints[docker.DockerEndpoint].(docker.EndpointMeta).Host) golden.Assert(t, string(ctx.TLS.Endpoints[docker.DockerEndpoint].Files["ca.pem"]), "ca.pem") } diff --git a/cli/command/formatter/context.go b/cli/command/formatter/context.go index 215c88f635df..fd8409108c5b 100644 --- a/cli/command/formatter/context.go +++ b/cli/command/formatter/context.go @@ -2,11 +2,10 @@ package formatter const ( // ClientContextTableFormat is the default client context format - ClientContextTableFormat = "table {{.Name}}{{if .Current}} *{{end}}\t{{.Description}}\t{{.DockerEndpoint}}\t{{.StackOrchestrator}}" + ClientContextTableFormat = "table {{.Name}}{{if .Current}} *{{end}}\t{{.Description}}\t{{.DockerEndpoint}}" - dockerEndpointHeader = "DOCKER ENDPOINT" - stackOrchestrastorHeader = "ORCHESTRATOR" - quietContextFormat = "{{.Name}}" + dockerEndpointHeader = "DOCKER ENDPOINT" + quietContextFormat = "{{.Name}}" ) // NewClientContextFormat returns a Format for rendering using a Context @@ -22,11 +21,10 @@ func NewClientContextFormat(source string, quiet bool) Format { // ClientContext is a context for display type ClientContext struct { - Name string - Description string - DockerEndpoint string - StackOrchestrator string - Current bool + Name string + Description string + DockerEndpoint string + Current bool } // ClientContextWrite writes formatted contexts using the Context @@ -50,10 +48,9 @@ type clientContextContext struct { func newClientContextContext() *clientContextContext { ctx := clientContextContext{} ctx.Header = SubHeaderContext{ - "Name": NameHeader, - "Description": DescriptionHeader, - "DockerEndpoint": dockerEndpointHeader, - "StackOrchestrator": stackOrchestrastorHeader, + "Name": NameHeader, + "Description": DescriptionHeader, + "DockerEndpoint": dockerEndpointHeader, } return &ctx } @@ -81,7 +78,3 @@ func (c *clientContextContext) DockerEndpoint() string { func (c *clientContextContext) KubernetesEndpoint() string { return "" } - -func (c *clientContextContext) StackOrchestrator() string { - return c.c.StackOrchestrator -} diff --git a/cli/command/orchestrator.go b/cli/command/orchestrator.go deleted file mode 100644 index 2a23979b3943..000000000000 --- a/cli/command/orchestrator.go +++ /dev/null @@ -1,85 +0,0 @@ -package command - -import ( - "fmt" - "io" - "os" -) - -// Orchestrator type acts as an enum describing supported orchestrators. -type Orchestrator string - -const ( - // OrchestratorKubernetes orchestrator - OrchestratorKubernetes = Orchestrator("kubernetes") - // OrchestratorSwarm orchestrator - OrchestratorSwarm = Orchestrator("swarm") - // OrchestratorAll orchestrator - OrchestratorAll = Orchestrator("all") - orchestratorUnset = Orchestrator("") - - defaultOrchestrator = OrchestratorSwarm - envVarDockerStackOrchestrator = "DOCKER_STACK_ORCHESTRATOR" - envVarDockerOrchestrator = "DOCKER_ORCHESTRATOR" -) - -// HasKubernetes returns true if defined orchestrator has Kubernetes capabilities. -// Deprecated: support for kubernetes as orchestrator was removed. -func (o Orchestrator) HasKubernetes() bool { - return o == OrchestratorKubernetes || o == OrchestratorAll -} - -// HasSwarm returns true if defined orchestrator has Swarm capabilities. -func (o Orchestrator) HasSwarm() bool { - return o == OrchestratorSwarm || o == OrchestratorAll -} - -// HasAll returns true if defined orchestrator has both Swarm and Kubernetes capabilities. -func (o Orchestrator) HasAll() bool { - return o == OrchestratorAll -} - -func normalize(value string) (Orchestrator, error) { - switch value { - case "kubernetes": - return OrchestratorKubernetes, nil - case "swarm": - return OrchestratorSwarm, nil - case "", "unset": // unset is the old value for orchestratorUnset. Keep accepting this for backward compat - return orchestratorUnset, nil - case "all": - return OrchestratorAll, nil - default: - return defaultOrchestrator, fmt.Errorf("specified orchestrator %q is invalid, please use either kubernetes, swarm or all", value) - } -} - -// NormalizeOrchestrator parses an orchestrator value and checks if it is valid -func NormalizeOrchestrator(value string) (Orchestrator, error) { - return normalize(value) -} - -// GetStackOrchestrator checks DOCKER_STACK_ORCHESTRATOR environment variable and configuration file -// orchestrator value and returns user defined Orchestrator. -func GetStackOrchestrator(flagValue, contextValue, globalDefault string, stderr io.Writer) (Orchestrator, error) { - // Check flag - if o, err := normalize(flagValue); o != orchestratorUnset { - return o, err - } - // Check environment variable - env := os.Getenv(envVarDockerStackOrchestrator) - if env == "" && os.Getenv(envVarDockerOrchestrator) != "" { - fmt.Fprintf(stderr, "WARNING: experimental environment variable %s is set. Please use %s instead\n", envVarDockerOrchestrator, envVarDockerStackOrchestrator) - } - if o, err := normalize(env); o != orchestratorUnset { - return o, err - } - if o, err := normalize(contextValue); o != orchestratorUnset { - return o, err - } - if o, err := normalize(globalDefault); o != orchestratorUnset { - return o, err - } - // Nothing set, use default orchestrator - return defaultOrchestrator, nil -} diff --git a/cli/command/orchestrator_test.go b/cli/command/orchestrator_test.go deleted file mode 100644 index 57030c20285a..000000000000 --- a/cli/command/orchestrator_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package command - -import ( - "io/ioutil" - "testing" - - "gotest.tools/v3/assert" - is "gotest.tools/v3/assert/cmp" - "gotest.tools/v3/env" -) - -func TestOrchestratorSwitch(t *testing.T) { - var testcases = []struct { - doc string - globalOrchestrator string - envOrchestrator string - flagOrchestrator string - contextOrchestrator string - expectedOrchestrator string - expectedSwarm bool - }{ - { - doc: "default", - expectedOrchestrator: "swarm", - expectedSwarm: true, - }, - { - doc: "allOrchestratorFlag", - flagOrchestrator: "all", - expectedOrchestrator: "all", - expectedSwarm: true, - }, - { - doc: "contextOverridesConfigFile", - globalOrchestrator: "kubernetes", - contextOrchestrator: "swarm", - expectedOrchestrator: "swarm", - expectedSwarm: true, - }, - { - doc: "envOverridesConfigFile", - globalOrchestrator: "kubernetes", - envOrchestrator: "swarm", - expectedOrchestrator: "swarm", - expectedSwarm: true, - }, - { - doc: "flagOverridesEnv", - envOrchestrator: "kubernetes", - flagOrchestrator: "swarm", - expectedOrchestrator: "swarm", - expectedSwarm: true, - }, - } - - for _, testcase := range testcases { - t.Run(testcase.doc, func(t *testing.T) { - if testcase.envOrchestrator != "" { - defer env.Patch(t, "DOCKER_STACK_ORCHESTRATOR", testcase.envOrchestrator)() - } - orchestrator, err := GetStackOrchestrator(testcase.flagOrchestrator, testcase.contextOrchestrator, testcase.globalOrchestrator, ioutil.Discard) - assert.NilError(t, err) - assert.Check(t, is.Equal(testcase.expectedSwarm, orchestrator.HasSwarm())) - assert.Check(t, is.Equal(testcase.expectedOrchestrator, string(orchestrator))) - }) - } -} diff --git a/cli/command/stack/cmd.go b/cli/command/stack/cmd.go index a434acb15755..4f59b99f4a3d 100644 --- a/cli/command/stack/cmd.go +++ b/cli/command/stack/cmd.go @@ -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 -} diff --git a/cli/command/stack/deploy.go b/cli/command/stack/deploy.go index a25ce0cc68fa..89c121511206 100644 --- a/cli/command/stack/deploy.go +++ b/cli/command/stack/deploy.go @@ -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) } diff --git a/cli/command/stack/deploy_test.go b/cli/command/stack/deploy_test.go index cc27e12f6842..0bffba383a38 100644 --- a/cli/command/stack/deploy_test.go +++ b/cli/command/stack/deploy_test.go @@ -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) diff --git a/cli/command/stack/formatter/formatter.go b/cli/command/stack/formatter/formatter.go index 6bc6bf03f30a..07b322f0616a 100644 --- a/cli/command/stack/formatter/formatter.go +++ b/cli/command/stack/formatter/formatter.go @@ -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 -} diff --git a/cli/command/stack/formatter/formatter_test.go b/cli/command/stack/formatter/formatter_test.go index 3dc439634f88..5c629037cd99 100644 --- a/cli/command/stack/formatter/formatter_test.go +++ b/cli/command/stack/formatter/formatter_test.go @@ -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 diff --git a/cli/command/stack/list.go b/cli/command/stack/list.go index 861ae1be2fb9..17f2e7947b22 100644 --- a/cli/command/stack/list.go +++ b/cli/command/stack/list.go @@ -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) } diff --git a/cli/command/stack/list_test.go b/cli/command/stack/list_test.go index a6983cc3a6a3..371d1e625573 100644 --- a/cli/command/stack/list_test.go +++ b/cli/command/stack/list_test.go @@ -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) } diff --git a/cli/command/stack/ps.go b/cli/command/stack/ps.go index 6d77d9f0065a..3dd8f82cc6b7 100644 --- a/cli/command/stack/ps.go +++ b/cli/command/stack/ps.go @@ -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) } diff --git a/cli/command/stack/ps_test.go b/cli/command/stack/ps_test.go index 58a651252b16..9e62dcc5e5ac 100644 --- a/cli/command/stack/ps_test.go +++ b/cli/command/stack/ps_test.go @@ -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) diff --git a/cli/command/stack/remove.go b/cli/command/stack/remove.go index 4ffe73ec249f..b32620877479 100644 --- a/cli/command/stack/remove.go +++ b/cli/command/stack/remove.go @@ -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) } diff --git a/cli/command/stack/remove_test.go b/cli/command/stack/remove_test.go index 0f10c55b2441..96bf38530f0f 100644 --- a/cli/command/stack/remove_test.go +++ b/cli/command/stack/remove_test.go @@ -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"}) diff --git a/cli/command/stack/services.go b/cli/command/stack/services.go index a1e97b9f2e2c..c955af2785f6 100644 --- a/cli/command/stack/services.go +++ b/cli/command/stack/services.go @@ -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) } diff --git a/cli/command/stack/services_test.go b/cli/command/stack/services_test.go index ef190d22900b..e5467591e7ec 100644 --- a/cli/command/stack/services_test.go +++ b/cli/command/stack/services_test.go @@ -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") diff --git a/cli/command/stack/swarm/list.go b/cli/command/stack/swarm/list.go index 817275e8be85..271cffdd0075 100644 --- a/cli/command/stack/swarm/list.go +++ b/cli/command/stack/swarm/list.go @@ -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++ diff --git a/cli/command/stack/testdata/stack-list-sort-natural.golden b/cli/command/stack/testdata/stack-list-sort-natural.golden index 3dc58234a43d..71eb63fd3b88 100644 --- a/cli/command/stack/testdata/stack-list-sort-natural.golden +++ b/cli/command/stack/testdata/stack-list-sort-natural.golden @@ -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 diff --git a/cli/command/stack/testdata/stack-list-sort.golden b/cli/command/stack/testdata/stack-list-sort.golden index 5d17f73f64a8..e4c250caba9f 100644 --- a/cli/command/stack/testdata/stack-list-sort.golden +++ b/cli/command/stack/testdata/stack-list-sort.golden @@ -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 diff --git a/cli/command/stack/testdata/stack-list-without-format.golden b/cli/command/stack/testdata/stack-list-without-format.golden index f45de3f8b253..915a04d96a65 100644 --- a/cli/command/stack/testdata/stack-list-without-format.golden +++ b/cli/command/stack/testdata/stack-list-without-format.golden @@ -1,2 +1,2 @@ -NAME SERVICES ORCHESTRATOR -service-name-foo 1 Swarm +NAME SERVICES +service-name-foo 1 diff --git a/cli/context/store/tlsstore.go b/cli/context/store/tlsstore.go index 1188ce2df798..9022433ef2d0 100644 --- a/cli/context/store/tlsstore.go +++ b/cli/context/store/tlsstore.go @@ -44,7 +44,7 @@ func (s *tlsStore) getData(contextID contextdir, endpointName, filename string) return data, nil } -func (s *tlsStore) remove(contextID contextdir, endpointName, filename string) error { +func (s *tlsStore) remove(contextID contextdir, endpointName, filename string) error { // nolint:unused err := os.Remove(s.filePath(contextID, endpointName, filename)) if os.IsNotExist(err) { return nil diff --git a/e2e/context/testdata/context-ls-notls.golden b/e2e/context/testdata/context-ls-notls.golden index b9ddd424c93c..2d33df13a4f0 100644 --- a/e2e/context/testdata/context-ls-notls.golden +++ b/e2e/context/testdata/context-ls-notls.golden @@ -1,3 +1,3 @@ -NAME DESCRIPTION DOCKER ENDPOINT ORCHESTRATOR -default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm -remote my remote cluster ssh://someserver kubernetes +NAME DESCRIPTION DOCKER ENDPOINT +default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock +remote my remote cluster ssh://someserver diff --git a/e2e/context/testdata/context-ls-tls.golden b/e2e/context/testdata/context-ls-tls.golden index 0d9a07c28c25..13aed65a881d 100644 --- a/e2e/context/testdata/context-ls-tls.golden +++ b/e2e/context/testdata/context-ls-tls.golden @@ -1,3 +1,3 @@ -NAME DESCRIPTION DOCKER ENDPOINT ORCHESTRATOR -default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm -test unix:///var/run/docker.sock swarm +NAME DESCRIPTION DOCKER ENDPOINT +default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock +test unix:///var/run/docker.sock diff --git a/e2e/context/testdata/context-ls.golden b/e2e/context/testdata/context-ls.golden index b9ddd424c93c..2d33df13a4f0 100644 --- a/e2e/context/testdata/context-ls.golden +++ b/e2e/context/testdata/context-ls.golden @@ -1,3 +1,3 @@ -NAME DESCRIPTION DOCKER ENDPOINT ORCHESTRATOR -default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm -remote my remote cluster ssh://someserver kubernetes +NAME DESCRIPTION DOCKER ENDPOINT +default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock +remote my remote cluster ssh://someserver diff --git a/e2e/stack/deploy_test.go b/e2e/stack/deploy_test.go index 94275c57e7c7..daf7ccc220a3 100644 --- a/e2e/stack/deploy_test.go +++ b/e2e/stack/deploy_test.go @@ -1,7 +1,6 @@ package stack import ( - "fmt" "sort" "strings" "testing" @@ -12,23 +11,16 @@ import ( ) func TestDeployWithNamedResources(t *testing.T) { - t.Run("Swarm", func(t *testing.T) { - testDeployWithNamedResources(t, "swarm") - }) -} - -func testDeployWithNamedResources(t *testing.T, orchestrator string) { - stackname := fmt.Sprintf("test-stack-deploy-with-names-%s", orchestrator) + stackname := "test-stack-deploy-with-names" composefile := golden.Path("stack-with-named-resources.yml") result := icmd.RunCommand("docker", "stack", "deploy", - "-c", composefile, stackname, "--orchestrator", orchestrator) - defer icmd.RunCommand("docker", "stack", "rm", - "--orchestrator", orchestrator, stackname) + "-c", composefile, stackname) + defer icmd.RunCommand("docker", "stack", "rm", stackname) result.Assert(t, icmd.Success) stdout := strings.Split(result.Stdout(), "\n") - expected := strings.Split(string(golden.Get(t, fmt.Sprintf("stack-deploy-with-names-%s.golden", orchestrator))), "\n") + expected := strings.Split(string(golden.Get(t, "stack-deploy-with-names.golden")), "\n") sort.Strings(stdout) sort.Strings(expected) assert.DeepEqual(t, stdout, expected) diff --git a/e2e/stack/help_test.go b/e2e/stack/help_test.go index 1235eef8d1e1..138785ab1be6 100644 --- a/e2e/stack/help_test.go +++ b/e2e/stack/help_test.go @@ -1,7 +1,6 @@ package stack import ( - "fmt" "testing" "gotest.tools/v3/golden" @@ -9,13 +8,7 @@ import ( ) func TestStackDeployHelp(t *testing.T) { - t.Run("Swarm", func(t *testing.T) { - testStackDeployHelp(t, "swarm") - }) -} - -func testStackDeployHelp(t *testing.T, orchestrator string) { - result := icmd.RunCommand("docker", "stack", "deploy", "--orchestrator", orchestrator, "--help") + result := icmd.RunCommand("docker", "stack", "deploy", "--help") result.Assert(t, icmd.Success) - golden.Assert(t, result.Stdout(), fmt.Sprintf("stack-deploy-help-%s.golden", orchestrator)) + golden.Assert(t, result.Stdout(), "stack-deploy-help.golden") } diff --git a/e2e/stack/remove_test.go b/e2e/stack/remove_test.go index 8469786acb5a..329c6ad25418 100644 --- a/e2e/stack/remove_test.go +++ b/e2e/stack/remove_test.go @@ -1,7 +1,6 @@ package stack import ( - "fmt" "strings" "testing" @@ -14,40 +13,32 @@ import ( var pollSettings = environment.DefaultPollSettings func TestRemove(t *testing.T) { - t.Run("Swarm", func(t *testing.T) { - testRemove(t, "swarm") - }) -} - -func testRemove(t *testing.T, orchestrator string) { - stackname := "test-stack-remove-" + orchestrator - deployFullStack(t, orchestrator, stackname) - defer cleanupFullStack(t, orchestrator, stackname) - result := icmd.RunCommand("docker", "stack", "rm", - stackname, "--orchestrator", orchestrator) + stackname := "test-stack-remove" + deployFullStack(t, stackname) + defer cleanupFullStack(t, stackname) + result := icmd.RunCommand("docker", "stack", "rm", stackname) result.Assert(t, icmd.Expected{Err: icmd.None}) - golden.Assert(t, result.Stdout(), - fmt.Sprintf("stack-remove-%s-success.golden", orchestrator)) + golden.Assert(t, result.Stdout(), "stack-remove-success.golden") } -func deployFullStack(t *testing.T, orchestrator, stackname string) { +func deployFullStack(t *testing.T, stackname string) { // TODO: this stack should have full options not minimal options result := icmd.RunCommand("docker", "stack", "deploy", - "--compose-file=./testdata/full-stack.yml", stackname, "--orchestrator", orchestrator) + "--compose-file=./testdata/full-stack.yml", stackname) result.Assert(t, icmd.Success) - poll.WaitOn(t, taskCount(orchestrator, stackname, 2), pollSettings) + poll.WaitOn(t, taskCount(stackname, 2), pollSettings) } -func cleanupFullStack(t *testing.T, orchestrator, stackname string) { +func cleanupFullStack(t *testing.T, stackname string) { // FIXME(vdemeester) we shouldn't have to do that. it is hiding a race on docker stack rm - poll.WaitOn(t, stackRm(orchestrator, stackname), pollSettings) - poll.WaitOn(t, taskCount(orchestrator, stackname, 0), pollSettings) + poll.WaitOn(t, stackRm(stackname), pollSettings) + poll.WaitOn(t, taskCount(stackname, 0), pollSettings) } -func stackRm(orchestrator, stackname string) func(t poll.LogT) poll.Result { +func stackRm(stackname string) func(t poll.LogT) poll.Result { return func(poll.LogT) poll.Result { - result := icmd.RunCommand("docker", "stack", "rm", stackname, "--orchestrator", orchestrator) + result := icmd.RunCommand("docker", "stack", "rm", stackname) if result.Error != nil { if strings.Contains(result.Stderr(), "not found") { return poll.Success() @@ -58,14 +49,9 @@ func stackRm(orchestrator, stackname string) func(t poll.LogT) poll.Result { } } -func taskCount(orchestrator, stackname string, expected int) func(t poll.LogT) poll.Result { +func taskCount(stackname string, expected int) func(t poll.LogT) poll.Result { return func(poll.LogT) poll.Result { - args := []string{"stack", "ps", stackname, "--orchestrator", orchestrator} - // FIXME(chris-crone): remove when we support filtering by desired-state on kubernetes - if orchestrator == "swarm" { - args = append(args, "-f=desired-state=running") - } - result := icmd.RunCommand("docker", args...) + result := icmd.RunCommand("docker", "stack", "ps", stackname, "-f=desired-state=running") count := lines(result.Stdout()) - 1 if count == expected { return poll.Success() diff --git a/e2e/stack/testdata/stack-deploy-help-swarm.golden b/e2e/stack/testdata/stack-deploy-help.golden similarity index 91% rename from e2e/stack/testdata/stack-deploy-help-swarm.golden rename to e2e/stack/testdata/stack-deploy-help.golden index 5f8ed3de7b29..fd8baec1af73 100644 --- a/e2e/stack/testdata/stack-deploy-help-swarm.golden +++ b/e2e/stack/testdata/stack-deploy-help.golden @@ -9,7 +9,6 @@ Aliases: Options: -c, --compose-file strings Path to a Compose file, or "-" to read from stdin - --orchestrator string Orchestrator to use (swarm|all) --prune Prune services that are no longer referenced --resolve-image string Query the registry to resolve image digest and supported platforms diff --git a/e2e/stack/testdata/stack-deploy-with-names-swarm.golden b/e2e/stack/testdata/stack-deploy-with-names-swarm.golden deleted file mode 100644 index c7f421ba9ce1..000000000000 --- a/e2e/stack/testdata/stack-deploy-with-names-swarm.golden +++ /dev/null @@ -1,7 +0,0 @@ -Creating network test-stack-deploy-with-names-swarm_network2 -Creating network named-network -Creating secret named-secret -Creating secret test-stack-deploy-with-names-swarm_secret2 -Creating config test-stack-deploy-with-names-swarm_config2 -Creating config named-config -Creating service test-stack-deploy-with-names-swarm_web diff --git a/e2e/stack/testdata/stack-remove-swarm-success.golden b/e2e/stack/testdata/stack-remove-success.golden similarity index 100% rename from e2e/stack/testdata/stack-remove-swarm-success.golden rename to e2e/stack/testdata/stack-remove-success.golden diff --git a/internal/test/cli.go b/internal/test/cli.go index f3844142f793..fb1397f397a7 100644 --- a/internal/test/cli.go +++ b/internal/test/cli.go @@ -55,7 +55,8 @@ func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli { in: streams.NewIn(ioutil.NopCloser(strings.NewReader(""))), // Use an empty string for filename so that tests don't create configfiles // Set cli.ConfigFile().Filename to a tempfile to support Save. - configfile: configfile.New(""), + configfile: configfile.New(""), + currentContext: command.DefaultContextName, } for _, opt := range opts { opt(c) @@ -214,24 +215,3 @@ func (c *FakeCli) ContentTrustEnabled() bool { func EnableContentTrust(c *FakeCli) { c.contentTrust = true } - -// StackOrchestrator return the selected stack orchestrator -func (c *FakeCli) StackOrchestrator(flagValue string) (command.Orchestrator, error) { - configOrchestrator := "" - if c.configfile != nil { - configOrchestrator = c.configfile.StackOrchestrator - } - ctxOrchestrator := "" - if c.currentContext != "" && c.contextStore != nil { - meta, err := c.contextStore.GetMetadata(c.currentContext) - if err != nil { - return "", err - } - context, err := command.GetDockerContext(meta) - if err != nil { - return "", err - } - ctxOrchestrator = string(context.StackOrchestrator) - } - return command.GetStackOrchestrator(flagValue, ctxOrchestrator, configOrchestrator, c.err) -}