瀏覽代碼

Merge pull request #218 from docker/context_rm_default

Context rm default does not allow removing current context, except if -f
Guillaume Tardif 5 年之前
父節點
當前提交
028750e7d2
共有 3 個文件被更改,包括 54 次插入11 次删除
  1. 38 9
      cli/cmd/context/rm.go
  2. 1 2
      local/e2e/backend_test.go
  3. 15 0
      tests/e2e/e2e_test.go

+ 38 - 9
cli/cmd/context/rm.go

@@ -29,35 +29,64 @@ package context
 
 import (
 	"context"
+	"errors"
 	"fmt"
 
-	"github.com/spf13/cobra"
-
+	apicontext "github.com/docker/api/context"
 	"github.com/docker/api/context/store"
 	"github.com/docker/api/multierror"
+	"github.com/spf13/cobra"
 )
 
+type removeOpts struct {
+	force bool
+}
+
 func removeCommand() *cobra.Command {
-	return &cobra.Command{
+	var opts removeOpts
+	cmd := &cobra.Command{
 		Use:     "rm CONTEXT [CONTEXT...]",
 		Short:   "Remove one or more contexts",
 		Aliases: []string{"remove"},
 		Args:    cobra.MinimumNArgs(1),
 		RunE: func(cmd *cobra.Command, args []string) error {
-			return runRemove(cmd.Context(), args)
+			return runRemove(cmd.Context(), args, opts.force)
 		},
 	}
+	cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "force removing current context")
+
+	return cmd
 }
 
-func runRemove(ctx context.Context, args []string) error {
+func runRemove(ctx context.Context, args []string, force bool) error {
+	currentContext := apicontext.CurrentContext(ctx)
 	s := store.ContextStore(ctx)
+
 	var errs *multierror.Error
-	for _, n := range args {
-		if err := s.Remove(n); err != nil {
-			errs = multierror.Append(errs, err)
+	for _, contextName := range args {
+		if currentContext == contextName {
+			if force {
+				err := runUse(ctx, "default")
+				if err != nil {
+					errs = multierror.Append(errs, errors.New("cannot delete current context"))
+				} else {
+					errs = removeContext(s, contextName, errs)
+				}
+			} else {
+				errs = multierror.Append(errs, errors.New("cannot delete current context"))
+			}
 		} else {
-			fmt.Println(n)
+			errs = removeContext(s, contextName, errs)
 		}
 	}
 	return errs.ErrorOrNil()
 }
+
+func removeContext(s store.Store, n string, errs *multierror.Error) *multierror.Error {
+	if err := s.Remove(n); err != nil {
+		errs = multierror.Append(errs, err)
+	} else {
+		fmt.Println(n)
+	}
+	return errs
+}

+ 1 - 2
local/e2e/backend_test.go

@@ -21,8 +21,7 @@ func (m *LocalBackendTestSuite) BeforeTest(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()
+	m.NewDockerCommand("context", "rm", "-f", "test-context").ExecOrDie()
 }
 
 func (m *LocalBackendTestSuite) TestPs() {

+ 15 - 0
tests/e2e/e2e_test.go

@@ -79,6 +79,21 @@ func (s *E2eSuite) TestContextCreateParseErrorDoesNotDelegateToLegacy() {
 	})
 }
 
+func (s *E2eSuite) TestCannotRemoveCurrentContext() {
+	s.NewDockerCommand("context", "create", "test-context-rm", "--from", "default").ExecOrDie()
+	s.NewDockerCommand("context", "use", "test-context-rm").ExecOrDie()
+	_, err := s.NewDockerCommand("context", "rm", "test-context-rm").Exec()
+	Expect(err.Error()).To(ContainSubstring("cannot delete current context"))
+}
+
+func (s *E2eSuite) TestCanForceRemoveCurrentContext() {
+	s.NewDockerCommand("context", "create", "test-context-rmf", "--from", "default").ExecOrDie()
+	s.NewDockerCommand("context", "use", "test-context-rmf").ExecOrDie()
+	s.NewDockerCommand("context", "rm", "-f", "test-context-rmf").ExecOrDie()
+	out := s.NewDockerCommand("context", "ls").ExecOrDie()
+	Expect(out).To(ContainSubstring("default *"))
+}
+
 func (s *E2eSuite) TestClassicLoginWithparameters() {
 	output, err := s.NewDockerCommand("login", "-u", "nouser", "-p", "wrongpasword").Exec()
 	Expect(output).To(ContainSubstring("Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password"))