Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 38 additions & 9 deletions cli/cmd/context/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 1 addition & 2 deletions local/e2e/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
15 changes: 15 additions & 0 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down