Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit 028750e

Browse files
authored
Merge pull request #218 from docker/context_rm_default
Context rm default does not allow removing current context, except if -f
2 parents 3566c72 + eb505ec commit 028750e

File tree

3 files changed

+54
-11
lines changed

3 files changed

+54
-11
lines changed

cli/cmd/context/rm.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,64 @@ package context
2929

3030
import (
3131
"context"
32+
"errors"
3233
"fmt"
3334

34-
"github.com/spf13/cobra"
35-
35+
apicontext "github.com/docker/api/context"
3636
"github.com/docker/api/context/store"
3737
"github.com/docker/api/multierror"
38+
"github.com/spf13/cobra"
3839
)
3940

41+
type removeOpts struct {
42+
force bool
43+
}
44+
4045
func removeCommand() *cobra.Command {
41-
return &cobra.Command{
46+
var opts removeOpts
47+
cmd := &cobra.Command{
4248
Use: "rm CONTEXT [CONTEXT...]",
4349
Short: "Remove one or more contexts",
4450
Aliases: []string{"remove"},
4551
Args: cobra.MinimumNArgs(1),
4652
RunE: func(cmd *cobra.Command, args []string) error {
47-
return runRemove(cmd.Context(), args)
53+
return runRemove(cmd.Context(), args, opts.force)
4854
},
4955
}
56+
cmd.Flags().BoolVarP(&opts.force, "force", "f", false, "force removing current context")
57+
58+
return cmd
5059
}
5160

52-
func runRemove(ctx context.Context, args []string) error {
61+
func runRemove(ctx context.Context, args []string, force bool) error {
62+
currentContext := apicontext.CurrentContext(ctx)
5363
s := store.ContextStore(ctx)
64+
5465
var errs *multierror.Error
55-
for _, n := range args {
56-
if err := s.Remove(n); err != nil {
57-
errs = multierror.Append(errs, err)
66+
for _, contextName := range args {
67+
if currentContext == contextName {
68+
if force {
69+
err := runUse(ctx, "default")
70+
if err != nil {
71+
errs = multierror.Append(errs, errors.New("cannot delete current context"))
72+
} else {
73+
errs = removeContext(s, contextName, errs)
74+
}
75+
} else {
76+
errs = multierror.Append(errs, errors.New("cannot delete current context"))
77+
}
5878
} else {
59-
fmt.Println(n)
79+
errs = removeContext(s, contextName, errs)
6080
}
6181
}
6282
return errs.ErrorOrNil()
6383
}
84+
85+
func removeContext(s store.Store, n string, errs *multierror.Error) *multierror.Error {
86+
if err := s.Remove(n); err != nil {
87+
errs = multierror.Append(errs, err)
88+
} else {
89+
fmt.Println(n)
90+
}
91+
return errs
92+
}

local/e2e/backend_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ func (m *LocalBackendTestSuite) BeforeTest(suiteName string, testName string) {
2121
}
2222

2323
func (m *LocalBackendTestSuite) AfterTest(suiteName string, testName string) {
24-
m.NewDockerCommand("context", "rm", "test-context").ExecOrDie()
25-
m.NewDockerCommand("context", "use", "default").ExecOrDie()
24+
m.NewDockerCommand("context", "rm", "-f", "test-context").ExecOrDie()
2625
}
2726

2827
func (m *LocalBackendTestSuite) TestPs() {

tests/e2e/e2e_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,21 @@ func (s *E2eSuite) TestContextCreateParseErrorDoesNotDelegateToLegacy() {
7979
})
8080
}
8181

82+
func (s *E2eSuite) TestCannotRemoveCurrentContext() {
83+
s.NewDockerCommand("context", "create", "test-context-rm", "--from", "default").ExecOrDie()
84+
s.NewDockerCommand("context", "use", "test-context-rm").ExecOrDie()
85+
_, err := s.NewDockerCommand("context", "rm", "test-context-rm").Exec()
86+
Expect(err.Error()).To(ContainSubstring("cannot delete current context"))
87+
}
88+
89+
func (s *E2eSuite) TestCanForceRemoveCurrentContext() {
90+
s.NewDockerCommand("context", "create", "test-context-rmf", "--from", "default").ExecOrDie()
91+
s.NewDockerCommand("context", "use", "test-context-rmf").ExecOrDie()
92+
s.NewDockerCommand("context", "rm", "-f", "test-context-rmf").ExecOrDie()
93+
out := s.NewDockerCommand("context", "ls").ExecOrDie()
94+
Expect(out).To(ContainSubstring("default *"))
95+
}
96+
8297
func (s *E2eSuite) TestClassicLoginWithparameters() {
8398
output, err := s.NewDockerCommand("login", "-u", "nouser", "-p", "wrongpasword").Exec()
8499
Expect(output).To(ContainSubstring("Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password"))

0 commit comments

Comments
 (0)