diff --git a/Makefile b/Makefile index 2d862375..569c96f4 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ cli: ## Compile the cli --output ./bin e2e-local: ## Run End to end local tests - go test -v ./tests/e2e ./tests/skip-win-ci-e2e ./moby/e2e + go test -v ./tests/e2e ./tests/skip-win-ci-e2e ./local/e2e e2e-win-ci: ## Run End to end local tests on windows CI, no docker for linux containers available ATM go test -v ./tests/e2e diff --git a/cli/cmd/context/create.go b/cli/cmd/context/create.go index 121d25a2..bfbfea1a 100644 --- a/cli/cmd/context/create.go +++ b/cli/cmd/context/create.go @@ -29,75 +29,118 @@ package context import ( "context" - "fmt" - "github.com/pkg/errors" "github.com/spf13/cobra" - "github.com/docker/api/client" + "github.com/docker/api/cli/dockerclassic" "github.com/docker/api/context/store" ) -// AciCreateOpts Options for ACI context create -type AciCreateOpts struct { - description string - aciLocation string - aciSubscriptionID string - aciResourceGroup string +type descriptionCreateOpts struct { + description string } func createCommand() *cobra.Command { - var opts AciCreateOpts + const longHelp = `Create a new context + +Create docker engine context: +$ docker context create CONTEXT [flags] + +Create Azure Container Instances context: +$ docker context create aci CONTEXT [flags] +(see docker context create aci --help) + +Docker endpoint config: + +NAME DESCRIPTION +from Copy named context's Docker endpoint configuration +host Docker endpoint on which to connect +ca Trust certs signed only by this CA +cert Path to TLS certificate file +key Path to TLS key file +skip-tls-verify Skip TLS certificate validation + +Kubernetes endpoint config: + +NAME DESCRIPTION +from Copy named context's Kubernetes endpoint configuration +config-file Path to a Kubernetes config file +context-override Overrides the context set in the kubernetes config file +namespace-override Overrides the namespace set in the kubernetes config file + +Example: + +$ docker context create my-context --description "some description" --docker "host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file"` + cmd := &cobra.Command{ - Use: "create CONTEXT BACKEND [OPTIONS]", - Short: "Create a context", - Args: cobra.ExactArgs(2), + Use: "create CONTEXT", + Short: "Create new context", RunE: func(cmd *cobra.Command, args []string) error { - return runCreate(cmd.Context(), opts, args[0], args[1]) + return dockerclassic.ExecCmd(cmd) }, + Long: longHelp, } - cmd.Flags().StringVar(&opts.description, "description", "", "Description of the context") - cmd.Flags().StringVar(&opts.aciLocation, "aci-location", "eastus", "Location") - cmd.Flags().StringVar(&opts.aciSubscriptionID, "aci-subscription-id", "", "Location") - cmd.Flags().StringVar(&opts.aciResourceGroup, "aci-resource-group", "", "Resource group") + cmd.AddCommand( + createAciCommand(), + createLocalCommand(), + createExampleCommand(), + ) + + flags := cmd.Flags() + flags.String("description", "", "Description of the context") + flags.String( + "default-stack-orchestrator", "", + "Default orchestrator for stack operations to use with this context (swarm|kubernetes|all)") + flags.StringToString("docker", nil, "set the docker endpoint") + flags.StringToString("kubernetes", nil, "set the kubernetes endpoint") + flags.String("from", "", "create context from a named context") return cmd } -func runCreate(ctx context.Context, opts AciCreateOpts, name string, contextType string) error { - contextData, description, err := getContextData(ctx, contextType, opts) - if err != nil { - return nil +func createLocalCommand() *cobra.Command { + var opts descriptionCreateOpts + cmd := &cobra.Command{ + Use: "local CONTEXT", + Short: "Create a context for accessing local engine", + Args: cobra.ExactArgs(1), + Hidden: true, + RunE: func(cmd *cobra.Command, args []string) error { + return createDockerContext(cmd.Context(), args[0], store.LocalContextType, opts.description, store.LocalContext{}) + }, } + addDescriptionFlag(cmd, &opts.description) + return cmd +} + +func createExampleCommand() *cobra.Command { + var opts descriptionCreateOpts + cmd := &cobra.Command{ + Use: "example CONTEXT", + Short: "Create a test context returning fixed output", + Args: cobra.ExactArgs(1), + Hidden: true, + RunE: func(cmd *cobra.Command, args []string) error { + return createDockerContext(cmd.Context(), args[0], store.ExampleContextType, opts.description, store.ExampleContext{}) + }, + } + + addDescriptionFlag(cmd, &opts.description) + return cmd +} + +func createDockerContext(ctx context.Context, name string, contextType string, description string, data interface{}) error { s := store.ContextStore(ctx) - return s.Create( + result := s.Create( name, contextType, description, - contextData, + data, ) + return result } -func getContextData(ctx context.Context, contextType string, opts AciCreateOpts) (interface{}, string, error) { - switch contextType { - case "aci": - cs, err := client.GetCloudService(ctx, "aci") - if err != nil { - return nil, "", errors.Wrap(err, "cannot connect to ACI backend") - } - params := map[string]string{ - "aciSubscriptionId": opts.aciSubscriptionID, - "aciResourceGroup": opts.aciResourceGroup, - "aciLocation": opts.aciLocation, - "description": opts.description, - } - return cs.CreateContextData(ctx, params) - case "moby": - return store.MobyContext{}, opts.description, nil - case "example": - return store.ExampleContext{}, opts.description, nil - default: - return nil, "", errors.New(fmt.Sprintf("incorrect context type %s, must be one of (aci | moby | docker)", contextType)) - } +func addDescriptionFlag(cmd *cobra.Command, descriptionOpt *string) { + cmd.Flags().StringVar(descriptionOpt, "description", "", "Description of the context") } diff --git a/cli/cmd/context/create_test.go b/cli/cmd/context/create_test.go deleted file mode 100644 index 620d2981..00000000 --- a/cli/cmd/context/create_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package context - -import ( - "context" - "testing" - - "github.com/docker/api/context/store" - - . "github.com/onsi/gomega" - "github.com/stretchr/testify/suite" - - _ "github.com/docker/api/example" - "github.com/docker/api/tests/framework" -) - -type PsSuite struct { - framework.CliSuite -} - -func (sut *PsSuite) TestCreateContextDataMoby() { - data, description, err := getContextData(context.TODO(), "moby", AciCreateOpts{}) - Expect(err).To(BeNil()) - Expect(data).To(Equal(store.MobyContext{})) - Expect(description).To(Equal("")) -} - -func (sut *PsSuite) TestErrorOnUnknownContextType() { - _, _, err := getContextData(context.TODO(), "foo", AciCreateOpts{}) - Expect(err).To(MatchError("incorrect context type foo, must be one of (aci | moby | docker)")) -} - -func TestPs(t *testing.T) { - RegisterTestingT(t) - suite.Run(t, new(PsSuite)) -} diff --git a/cli/cmd/context/createaci.go b/cli/cmd/context/createaci.go new file mode 100644 index 00000000..ca69f2e9 --- /dev/null +++ b/cli/cmd/context/createaci.go @@ -0,0 +1,85 @@ +/* + Copyright (c) 2020 Docker Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH + THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +package context + +import ( + "context" + + "github.com/pkg/errors" + "github.com/spf13/cobra" + + "github.com/docker/api/client" + "github.com/docker/api/context/store" +) + +type aciCreateOpts struct { + description string + location string + subscriptionID string + resourceGroup string +} + +func createAciCommand() *cobra.Command { + var opts aciCreateOpts + cmd := &cobra.Command{ + Use: "aci CONTEXT [flags]", + Short: "Create a context for Azure Container Instances", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + contextData, description, err := getAciContextData(cmd.Context(), opts) + if err != nil { + return nil + } + return createDockerContext(cmd.Context(), args[0], store.AciContextType, description, contextData) + }, + } + + addDescriptionFlag(cmd, &opts.description) + cmd.Flags().StringVar(&opts.location, "location", "eastus", "Location") + cmd.Flags().StringVar(&opts.subscriptionID, "subscription-id", "", "Location") + cmd.Flags().StringVar(&opts.resourceGroup, "resource-group", "", "Resource group") + + return cmd +} + +func getAciContextData(ctx context.Context, opts aciCreateOpts) (interface{}, string, error) { + cs, err := client.GetCloudService(ctx, store.AciContextType) + if err != nil { + return nil, "", errors.Wrap(err, "cannot connect to ACI backend") + } + return cs.CreateContextData(ctx, convertAciOpts(opts)) +} + +func convertAciOpts(opts aciCreateOpts) map[string]string { + return map[string]string{ + "aciSubscriptionId": opts.subscriptionID, + "aciResourceGroup": opts.resourceGroup, + "aciLocation": opts.location, + "description": opts.description, + } +} diff --git a/cli/cmd/context/ls.go b/cli/cmd/context/ls.go index 7ee38fc0..9d409296 100644 --- a/cli/cmd/context/ls.go +++ b/cli/cmd/context/ls.go @@ -94,7 +94,7 @@ func getEndpoint(name string, meta map[string]interface{}) string { if !ok { return "" } - data, ok := endpoints.(store.Endpoint) + data, ok := endpoints.(*store.Endpoint) if !ok { return "" } diff --git a/cli/main.go b/cli/main.go index c097aaba..540c56fe 100644 --- a/cli/main.go +++ b/cli/main.go @@ -45,7 +45,7 @@ import ( // Backend registrations _ "github.com/docker/api/azure" _ "github.com/docker/api/example" - _ "github.com/docker/api/moby" + _ "github.com/docker/api/local" "github.com/docker/api/cli/cmd" "github.com/docker/api/cli/cmd/compose" diff --git a/config/config_test.go b/config/config_test.go index a0d8ac21..5f94639e 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -39,7 +39,7 @@ import ( var sampleConfig = []byte(`{ "otherField": "value", - "currentContext": "moby" + "currentContext": "local" }`) type ConfigTestSuite struct { @@ -66,14 +66,14 @@ func (s *ConfigTestSuite) TestLoadFile() { writeSampleConfig(s.T(), s.configDir) f, err := LoadFile(s.configDir) require.NoError(s.T(), err) - require.Equal(s.T(), "moby", f.CurrentContext) + require.Equal(s.T(), "local", f.CurrentContext) } func (s *ConfigTestSuite) TestOverWriteCurrentContext() { writeSampleConfig(s.T(), s.configDir) f, err := LoadFile(s.configDir) require.NoError(s.T(), err) - require.Equal(s.T(), "moby", f.CurrentContext) + require.Equal(s.T(), "local", f.CurrentContext) err = WriteCurrentContext(s.configDir, "overwrite") require.NoError(s.T(), err) diff --git a/context/store/contextmetadata.go b/context/store/contextmetadata.go index a6ab560d..a9987dfd 100644 --- a/context/store/contextmetadata.go +++ b/context/store/contextmetadata.go @@ -33,8 +33,8 @@ type AciContext struct { ResourceGroup string `json:",omitempty"` } -// MobyContext is the context for the moby backend -type MobyContext struct{} +// LocalContext is the context for the local backend +type LocalContext struct{} // ExampleContext is the context for the example backend type ExampleContext struct{} diff --git a/context/store/store.go b/context/store/store.go index 5844fcbd..25c604dd 100644 --- a/context/store/store.go +++ b/context/store/store.go @@ -96,9 +96,9 @@ const ( // AciContextType is the endpoint key in the context endpoints for an ACI // backend AciContextType = "aci" - // MobyContextType is the endpoint key in the context endpoints for a moby - // backend - MobyContextType = "moby" + // LocalContextType is the endpoint key in the context endpoints for a new + // local backend + LocalContextType = "local" // ExampleContextType is the endpoint key in the context endpoints for an // example backend ExampleContextType = "example" @@ -211,12 +211,14 @@ func toTypedEndpoints(endpoints map[string]interface{}) (map[string]interface{}, return nil, err } typeGetters := getters() - if _, ok := typeGetters[k]; !ok { - result[k] = v - continue + typeGetter, ok := typeGetters[k] + if !ok { + typeGetter = func() interface{} { + return &Endpoint{} + } } - val := typeGetters[k]() + val := typeGetter() err = json.Unmarshal(bytes, &val) if err != nil { return nil, err @@ -333,8 +335,8 @@ func getters() map[string]func() interface{} { "aci": func() interface{} { return &AciContext{} }, - "moby": func() interface{} { - return &MobyContext{} + "local": func() interface{} { + return &LocalContext{} }, "example": func() interface{} { return &ExampleContext{} diff --git a/context/store/storedefault.go b/context/store/storedefault.go index 141d4178..b3e66337 100644 --- a/context/store/storedefault.go +++ b/context/store/storedefault.go @@ -8,7 +8,7 @@ import ( "github.com/pkg/errors" ) -const defaultContextType = "docker" +const defaultContextType = "moby" // Represents a context as created by the docker cli type defaultContext struct { @@ -58,10 +58,10 @@ func dockerDefaultContext() (*DockerContext, error) { meta := DockerContext{ Name: "default", Endpoints: map[string]interface{}{ - "docker": Endpoint{ + "docker": &Endpoint{ Host: defaultCtx.Endpoints.Docker.Host, }, - "kubernetes": Endpoint{ + "kubernetes": &Endpoint{ Host: defaultCtx.Endpoints.Kubernetes.Host, DefaultNamespace: defaultCtx.Endpoints.Kubernetes.DefaultNamespace, }, diff --git a/docs/cli/overview-of-the-cli.md b/docs/cli/overview-of-the-cli.md index b7bb66ca..b2c043db 100644 --- a/docs/cli/overview-of-the-cli.md +++ b/docs/cli/overview-of-the-cli.md @@ -26,7 +26,7 @@ Insert a really small tutorial or links here. We have made some changes to the syntax of a few commands to make them easier to understand. Where we still support the old forms, the command line will tell you the new form, but will still work correctly. In cases where we remove the old form you will get help text. If we remove a verb, for example "docker stack" we will display a message saying that the command -is only available with the Moby backend. For example +is only available with the Local backend. For example ``` > docker context create my-context --description "some description" --docker "host=tcp://myserver:2376" diff --git a/moby/backend.go b/local/backend.go similarity index 85% rename from moby/backend.go rename to local/backend.go index 92796a58..abefd57a 100644 --- a/moby/backend.go +++ b/local/backend.go @@ -1,4 +1,4 @@ -package moby +package local import ( "bufio" @@ -24,12 +24,12 @@ import ( "github.com/docker/api/errdefs" ) -type mobyService struct { +type local struct { apiClient *client.Client } func init() { - backend.Register("moby", "moby", service, cloud.NotImplementedCloudService) + backend.Register("local", "local", service, cloud.NotImplementedCloudService) } func service(ctx context.Context) (backend.Service, error) { @@ -38,20 +38,20 @@ func service(ctx context.Context) (backend.Service, error) { return nil, err } - return &mobyService{ + return &local{ apiClient, }, nil } -func (ms *mobyService) ContainerService() containers.Service { +func (ms *local) ContainerService() containers.Service { return ms } -func (ms *mobyService) ComposeService() compose.Service { +func (ms *local) ComposeService() compose.Service { return nil } -func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Container, error) { +func (ms *local) List(ctx context.Context, all bool) ([]containers.Container, error) { css, err := ms.apiClient.ContainerList(ctx, types.ContainerListOptions{ All: all, }) @@ -78,7 +78,7 @@ func (ms *mobyService) List(ctx context.Context, all bool) ([]containers.Contain return result, nil } -func (ms *mobyService) Run(ctx context.Context, r containers.ContainerConfig) error { +func (ms *local) Run(ctx context.Context, r containers.ContainerConfig) error { exposedPorts, hostBindings, err := fromPorts(r.Ports) if err != nil { return err @@ -125,7 +125,7 @@ func (ms *mobyService) Run(ctx context.Context, r containers.ContainerConfig) er return ms.apiClient.ContainerStart(ctx, created.ID, types.ContainerStartOptions{}) } -func (ms *mobyService) Stop(ctx context.Context, containerID string, timeout *uint32) error { +func (ms *local) Stop(ctx context.Context, containerID string, timeout *uint32) error { var t *time.Duration if timeout != nil { timeoutValue := time.Duration(*timeout) * time.Second @@ -134,7 +134,7 @@ func (ms *mobyService) Stop(ctx context.Context, containerID string, timeout *ui return ms.apiClient.ContainerStop(ctx, containerID, t) } -func (ms *mobyService) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error { +func (ms *local) Exec(ctx context.Context, name string, command string, reader io.Reader, writer io.Writer) error { cec, err := ms.apiClient.ContainerExecCreate(ctx, name, types.ExecConfig{ Cmd: []string{command}, Tty: true, @@ -176,7 +176,7 @@ func (ms *mobyService) Exec(ctx context.Context, name string, command string, re } } -func (ms *mobyService) Logs(ctx context.Context, containerName string, request containers.LogsRequest) error { +func (ms *local) Logs(ctx context.Context, containerName string, request containers.LogsRequest) error { c, err := ms.apiClient.ContainerInspect(ctx, containerName) if err != nil { return err @@ -204,7 +204,7 @@ func (ms *mobyService) Logs(ctx context.Context, containerName string, request c return err } -func (ms *mobyService) Delete(ctx context.Context, containerID string, force bool) error { +func (ms *local) Delete(ctx context.Context, containerID string, force bool) error { err := ms.apiClient.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{ Force: force, }) diff --git a/moby/e2e/backend_test.go b/local/e2e/backend_test.go similarity index 70% rename from moby/e2e/backend_test.go rename to local/e2e/backend_test.go index 90b72c86..c719060a 100644 --- a/moby/e2e/backend_test.go +++ b/local/e2e/backend_test.go @@ -11,26 +11,26 @@ import ( "github.com/docker/api/tests/framework" ) -type MobyBackendTestSuite struct { +type LocalBackendTestSuite struct { framework.Suite } -func (m *MobyBackendTestSuite) BeforeTest(suiteName string, testName string) { - m.NewDockerCommand("context", "create", "test-context", "moby").ExecOrDie() +func (m *LocalBackendTestSuite) BeforeTest(suiteName string, testName string) { + m.NewDockerCommand("context", "create", "local", "test-context").ExecOrDie() m.NewDockerCommand("context", "use", "test-context").ExecOrDie() } -func (m *MobyBackendTestSuite) AfterTest(suiteName string, testName string) { +func (m *LocalBackendTestSuite) AfterTest(suiteName string, testName string) { m.NewDockerCommand("context", "rm", "test-context").ExecOrDie() m.NewDockerCommand("context", "use", "default").ExecOrDie() } -func (m *MobyBackendTestSuite) TestPs() { +func (m *LocalBackendTestSuite) TestPs() { out := m.NewDockerCommand("ps").ExecOrDie() require.Equal(m.T(), "CONTAINER ID IMAGE COMMAND STATUS PORTS\n", out) } -func (m *MobyBackendTestSuite) TestRun() { +func (m *LocalBackendTestSuite) TestRun() { _, err := m.NewDockerCommand("run", "--name", "nginx", "nginx").Exec() require.Nil(m.T(), err) out := m.NewDockerCommand("ps").ExecOrDie() @@ -41,7 +41,7 @@ func (m *MobyBackendTestSuite) TestRun() { assert.Equal(m.T(), 3, len(lines)) } -func (m *MobyBackendTestSuite) TestRunWithPorts() { +func (m *LocalBackendTestSuite) TestRunWithPorts() { _, err := m.NewDockerCommand("run", "--name", "nginx", "-p", "8080:80", "nginx").Exec() require.Nil(m.T(), err) out := m.NewDockerCommand("ps").ExecOrDie() @@ -51,6 +51,6 @@ func (m *MobyBackendTestSuite) TestRunWithPorts() { assert.Contains(m.T(), out, "8080") } -func TestMobyBackendTestSuite(t *testing.T) { - suite.Run(t, new(MobyBackendTestSuite)) +func TestLocalBackendTestSuite(t *testing.T) { + suite.Run(t, new(LocalBackendTestSuite)) } diff --git a/tests/aci-e2e/e2e-aci_test.go b/tests/aci-e2e/e2e-aci_test.go index f396d389..67a64b4c 100644 --- a/tests/aci-e2e/e2e-aci_test.go +++ b/tests/aci-e2e/e2e-aci_test.go @@ -38,16 +38,6 @@ type E2eACISuite struct { Suite } -func (s *E2eACISuite) TestContextHelp() { - It("ensures context command includes azure-login and aci-create", func() { - output := s.NewDockerCommand("context", "create", "--help").ExecOrDie() - Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]")) - Expect(output).To(ContainSubstring("--aci-location")) - Expect(output).To(ContainSubstring("--aci-subscription-id")) - Expect(output).To(ContainSubstring("--aci-resource-group")) - }) -} - func (s *E2eACISuite) TestContextDefault() { It("should be initialized with default context", func() { _, err := s.NewCommand("docker", "context", "rm", "-f", contextName).Exec() @@ -70,7 +60,7 @@ func (s *E2eACISuite) TestACIBackend() { Expect(err).To(BeNil()) subscriptionID = *models[0].SubscriptionID - s.NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie() + s.NewDockerCommand("context", "create", "aci", contextName, "--subscription-id", subscriptionID, "--resource-group", resourceGroupName, "--location", location).ExecOrDie() // Expect(output).To(ContainSubstring("ACI context acitest created")) }) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 249e7df5..2344e37b 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -46,36 +46,36 @@ type E2eSuite struct { } func (s *E2eSuite) TestContextHelp() { - It("ensures context command includes azure-login and aci-create", func() { - output := s.NewDockerCommand("context", "create", "--help").ExecOrDie() - Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]")) - Expect(output).To(ContainSubstring("--aci-location")) - Expect(output).To(ContainSubstring("--aci-subscription-id")) - Expect(output).To(ContainSubstring("--aci-resource-group")) - }) + output := s.NewDockerCommand("context", "create", "aci", "--help").ExecOrDie() + Expect(output).To(ContainSubstring("docker context create aci CONTEXT [flags]")) + Expect(output).To(ContainSubstring("--location")) + Expect(output).To(ContainSubstring("--subscription-id")) + Expect(output).To(ContainSubstring("--resource-group")) } -func (s *E2eSuite) TestContextDefault() { - It("should be initialized with default context", func() { - output := s.NewDockerCommand("context", "show").ExecOrDie() - Expect(output).To(ContainSubstring("default")) - output = s.NewCommand("docker", "context", "ls").ExecOrDie() - golden.Assert(s.T(), output, GoldenFile("ls-out-default")) - }) +func (s *E2eSuite) TestListAndShowDefaultContext() { + output := s.NewDockerCommand("context", "show").ExecOrDie() + Expect(output).To(ContainSubstring("default")) + output = s.NewCommand("docker", "context", "ls").ExecOrDie() + golden.Assert(s.T(), output, GoldenFile("ls-out-default")) } -func (s *E2eSuite) TestContextLegacy() { - It("should inspect default", func() { - output := s.NewDockerCommand("context", "inspect", "default").ExecOrDie() - Expect(output).To(ContainSubstring(`"Name": "default"`)) - }) +func (s *E2eSuite) TestCreateDockerContextAndListIt() { + s.NewDockerCommand("context", "create", "test-docker", "--from", "default").ExecOrDie() + output := s.NewCommand("docker", "context", "ls").ExecOrDie() + golden.Assert(s.T(), output, GoldenFile("ls-out-test-docker")) +} + +func (s *E2eSuite) TestInspectDefaultContext() { + output := s.NewDockerCommand("context", "inspect", "default").ExecOrDie() + Expect(output).To(ContainSubstring(`"Name": "default"`)) } func (s *E2eSuite) TestContextCreateParseErrorDoesNotDelegateToLegacy() { It("should dispay new cli error when parsing context create flags", func() { - _, err := s.NewDockerCommand("context", "create", "--aci-subscription-id", "titi").Exec() + _, err := s.NewDockerCommand("context", "create", "aci", "--subscription-id", "titi").Exec() Expect(err.Error()).NotTo(ContainSubstring("unknown flag")) - Expect(err.Error()).To(ContainSubstring("accepts 2 arg(s), received 0")) + Expect(err.Error()).To(ContainSubstring("accepts 1 arg(s), received 0")) }) } @@ -135,7 +135,7 @@ func (s *E2eSuite) TestLeaveLegacyErrorMessagesUnchanged() { } func (s *E2eSuite) TestDisplayFriendlyErrorMessageForLegacyCommands() { - s.NewDockerCommand("context", "create", "test-example", "example").ExecOrDie() + s.NewDockerCommand("context", "create", "example", "test-example").ExecOrDie() output, err := s.NewDockerCommand("--context", "test-example", "images").Exec() Expect(output).To(Equal("Command \"images\" not available in current context (test-example), you can use the \"default\" context to run this command\n")) Expect(err).NotTo(BeNil()) @@ -149,7 +149,7 @@ func (s *E2eSuite) TestDisplaysAdditionalLineInDockerVersion() { func (s *E2eSuite) TestMockBackend() { It("creates a new test context to hardcoded example backend", func() { - s.NewDockerCommand("context", "create", "test-example", "example").ExecOrDie() + s.NewDockerCommand("context", "create", "example", "test-example").ExecOrDie() // Expect(output).To(ContainSubstring("test-example context acitest created")) }) diff --git a/tests/e2e/testdata/ls-out-default-windows.golden b/tests/e2e/testdata/ls-out-default-windows.golden index 19ebe37d..c01e0659 100644 --- a/tests/e2e/testdata/ls-out-default-windows.golden +++ b/tests/e2e/testdata/ls-out-default-windows.golden @@ -1,2 +1,2 @@ NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR -default * docker Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm +default * moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm diff --git a/tests/e2e/testdata/ls-out-default.golden b/tests/e2e/testdata/ls-out-default.golden index 9e361fa7..838fc003 100644 --- a/tests/e2e/testdata/ls-out-default.golden +++ b/tests/e2e/testdata/ls-out-default.golden @@ -1,2 +1,2 @@ NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR -default * docker Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm +default * moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm diff --git a/tests/e2e/testdata/ls-out-test-docker-windows.golden b/tests/e2e/testdata/ls-out-test-docker-windows.golden new file mode 100644 index 00000000..5074d412 --- /dev/null +++ b/tests/e2e/testdata/ls-out-test-docker-windows.golden @@ -0,0 +1,3 @@ +NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR +default * moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm +test-docker moby npipe:////./pipe/docker_engine swarm diff --git a/tests/e2e/testdata/ls-out-test-docker.golden b/tests/e2e/testdata/ls-out-test-docker.golden new file mode 100644 index 00000000..b0c8e97a --- /dev/null +++ b/tests/e2e/testdata/ls-out-test-docker.golden @@ -0,0 +1,3 @@ +NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR +default * moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm +test-docker moby unix:///var/run/docker.sock swarm diff --git a/tests/e2e/testdata/ls-out-test-example-windows.golden b/tests/e2e/testdata/ls-out-test-example-windows.golden index 1df1196f..95878b1a 100644 --- a/tests/e2e/testdata/ls-out-test-example-windows.golden +++ b/tests/e2e/testdata/ls-out-test-example-windows.golden @@ -1,3 +1,3 @@ NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR -default docker Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm +default moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine swarm test-example * example diff --git a/tests/e2e/testdata/ls-out-test-example.golden b/tests/e2e/testdata/ls-out-test-example.golden index 2508cb89..efdb5180 100644 --- a/tests/e2e/testdata/ls-out-test-example.golden +++ b/tests/e2e/testdata/ls-out-test-example.golden @@ -1,3 +1,3 @@ NAME TYPE DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR -default docker Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm +default moby Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm test-example * example