Merge pull request #234 from docker/inspect_no_args

Do not restrict `docker inspect` to 1 arg
This commit is contained in:
Guillaume Tardif 2020-06-18 10:08:52 +02:00 committed by GitHub
commit 96bddb392d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 37 deletions

View File

@ -37,10 +37,12 @@ func inspectCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "inspect",
Short: "Display detailed information on one or more contexts",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return mobycli.ExecCmd(cmd)
},
}
// flags matching delegated command in moby cli
flags := cmd.Flags()
flags.StringP("format", "f", "", "Format the output using the given Go template")
return cmd
}

View File

@ -101,7 +101,7 @@ func main() {
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if !isOwnCommand(cmd) {
mobycli.Exec(cmd.Context())
mobycli.ExecIfDefaultCtxType(cmd.Context())
}
return nil
},
@ -127,7 +127,7 @@ func main() {
helpFunc := root.HelpFunc()
root.SetHelpFunc(func(cmd *cobra.Command, args []string) {
if !isOwnCommand(cmd) {
mobycli.Exec(cmd.Context())
mobycli.ExecIfDefaultCtxType(cmd.Context())
}
helpFunc(cmd, args)
})
@ -168,7 +168,7 @@ func main() {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
mobycli.Exec(ctx)
mobycli.ExecIfDefaultCtxType(ctx)
checkIfUnknownCommandExistInDefaultContext(err, currentContext)
fmt.Fprintln(os.Stderr, err)

View File

@ -16,33 +16,38 @@ import (
// ComDockerCli name of the classic cli binary
const ComDockerCli = "com.docker.cli"
// Exec delegates to com.docker.cli
func Exec(ctx context.Context) {
// ExecIfDefaultCtxType delegates to com.docker.cli if on moby context
func ExecIfDefaultCtxType(ctx context.Context) {
currentContext := apicontext.CurrentContext(ctx)
s := store.ContextStore(ctx)
_, err := s.Get(currentContext)
currentCtx, err := s.Get(currentContext)
// Only run original docker command if the current context is not
// ours.
if err != nil {
cmd := exec.CommandContext(ctx, ComDockerCli, os.Args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
os.Exit(exiterr.ExitCode())
}
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(0)
if err != nil || currentCtx.Type() == store.DefaultContextType {
shellOut(ctx)
}
}
func shellOut(ctx context.Context) {
cmd := exec.CommandContext(ctx, ComDockerCli, os.Args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
os.Exit(exiterr.ExitCode())
}
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(0)
}
// ExecCmd delegates the cli command to com.docker.cli. The error is never returned (process will exit with docker classic exit code), the return type is to make it easier to use with cobra commands
func ExecCmd(command *cobra.Command) error {
Exec(command.Context())
shellOut(command.Context())
return nil
}

View File

@ -12,7 +12,7 @@ type DockerContext struct {
// Type the context type
func (m *DockerContext) Type() string {
if m.Metadata.Type == "" {
return defaultContextType
return DefaultContextType
}
return m.Metadata.Type
}

View File

@ -45,6 +45,17 @@ import (
const (
// DefaultContextName is an automatically generated local context
DefaultContextName = "default"
// DefaultContextType is the type for all moby contexts (not associated with cli backend)
DefaultContextType = "moby"
// AciContextType is the endpoint key in the context endpoints for an ACI
// backend
AciContextType = "aci"
// 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"
)
const (
@ -92,18 +103,6 @@ type Endpoint struct {
DefaultNamespace string `json:",omitempty"`
}
const (
// AciContextType is the endpoint key in the context endpoints for an ACI
// backend
AciContextType = "aci"
// 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"
)
type store struct {
root string
}

View File

@ -8,8 +8,6 @@ import (
"github.com/pkg/errors"
)
const defaultContextType = "moby"
// Represents a context as created by the docker cli
type defaultContext struct {
Metadata ContextMetadata
@ -67,7 +65,7 @@ func dockerDefaultContext() (*DockerContext, error) {
},
},
Metadata: ContextMetadata{
Type: defaultContextType,
Type: DefaultContextType,
Description: "Current DOCKER_HOST based configuration",
StackOrchestrator: defaultCtx.Metadata.StackOrchestrator,
},

View File

@ -79,6 +79,18 @@ func (s *E2eSuite) TestInspectDefaultContext() {
Expect(output).To(ContainSubstring(`"Name": "default"`))
}
func (s *E2eSuite) TestInspectContextNoArgs() {
output := s.NewDockerCommand("context", "inspect").ExecOrDie()
Expect(output).To(ContainSubstring(`"Name": "default"`))
}
func (s *E2eSuite) TestInspectContextRegardlessCurrentContext() {
s.NewDockerCommand("context", "create", "local", "localCtx").ExecOrDie()
s.NewDockerCommand("context", "use", "localCtx").ExecOrDie()
output := s.NewDockerCommand("context", "inspect").ExecOrDie()
Expect(output).To(ContainSubstring(`"Name": "localCtx"`))
}
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()
@ -108,6 +120,14 @@ func (s *E2eSuite) TestClassicLoginWithparameters() {
Expect(err).NotTo(BeNil())
}
func (s *E2eSuite) TestClassicLoginRegardlessCurrentContext() {
s.NewDockerCommand("context", "create", "local", "localCtx").ExecOrDie()
s.NewDockerCommand("context", "use", "localCtx").ExecOrDie()
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"))
Expect(err).NotTo(BeNil())
}
func (s *E2eSuite) TestClassicLogin() {
output, err := s.NewDockerCommand("login", "someregistry.docker.io").Exec()
Expect(output).To(ContainSubstring("Cannot perform an interactive login from a non TTY device"))
@ -149,6 +169,13 @@ func (s *E2eSuite) TestLegacy() {
output := s.NewDockerCommand("run", "--rm", "hello-world").WithTimeout(time.NewTimer(20 * time.Second).C).ExecOrDie()
Expect(output).To(ContainSubstring("Hello from Docker!"))
})
It("should execute legacy commands in other moby contexts", func() {
s.NewDockerCommand("context", "create", "mobyCtx", "--from=default").ExecOrDie()
s.NewDockerCommand("context", "use", "mobyCtx").ExecOrDie()
output, _ := s.NewDockerCommand("swarm", "join").Exec()
Expect(output).To(ContainSubstring("\"docker swarm join\" requires exactly 1 argument."))
})
}
func (s *E2eSuite) TestLeaveLegacyErrorMessagesUnchanged() {