Improve error handling of commands run against unsupported daemon

The current error-handling only checked for version annotations
on the subcommand itself, but did not check the top-level command.

This patch always traverses the command path (parents), and
prints an error if the command is not supported.

Before this change:

    $ docker service
    Usage:	docker service COMMAND

    Manage services

    Options:
          --help   Print usage

    Commands:
      create      Create a new service
      inspect     Display detailed information on one or more services
      ls          List services
      ps          List the tasks of one or more services
      rm          Remove one or more services
      scale       Scale one or multiple replicated services
      update      Update a service

    Run 'docker service COMMAND --help' for more information on a command.

    $ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE

After this change:

    $ DOCKER_API_VERSION=1.12 docker service
    docker service requires API version 1.24, but the Docker daemon API version is 1.12

    $ DOCKER_API_VERSION=1.12 docker service ls
    docker service ls requires API version 1.24, but the Docker daemon API version is 1.12

    $ DOCKER_API_VERSION=1.24 docker plugin --help
    docker plugin requires API version 1.25, but the Docker daemon API version is 1.24

    $ DOCKER_API_VERSION=1.25 docker plugin upgrade --help
    docker plugin upgrade requires API version 1.26, but the Docker daemon API version is 1.25

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2017-03-03 13:58:50 +01:00
parent e398a78466
commit 998950a9f4
1 changed files with 7 additions and 10 deletions

View File

@ -229,19 +229,16 @@ func hideUnsupportedFeatures(cmd *cobra.Command, clientVersion, osType string, h
} }
func isSupported(cmd *cobra.Command, clientVersion, osType string, hasExperimental bool) error { func isSupported(cmd *cobra.Command, clientVersion, osType string, hasExperimental bool) error {
// We check recursively so that, e.g., `docker stack ls` will return the same output as `docker stack` // Check recursively so that, e.g., `docker stack ls` returns the same output as `docker stack`
if !hasExperimental {
for curr := cmd; curr != nil; curr = curr.Parent() { for curr := cmd; curr != nil; curr = curr.Parent() {
if _, ok := curr.Tags["experimental"]; ok { if cmdVersion, ok := curr.Tags["version"]; ok && versions.LessThan(clientVersion, cmdVersion) {
return errors.New("only supported on a Docker daemon with experimental features enabled") return fmt.Errorf("%s requires API version %s, but the Docker daemon API version is %s", cmd.CommandPath(), cmdVersion, clientVersion)
} }
if _, ok := curr.Tags["experimental"]; ok && !hasExperimental {
return fmt.Errorf("%s is only supported on a Docker daemon with experimental features enabled", cmd.CommandPath())
} }
} }
if cmdVersion, ok := cmd.Tags["version"]; ok && versions.LessThan(clientVersion, cmdVersion) {
return fmt.Errorf("requires API version %s, but the Docker daemon API version is %s", cmdVersion, clientVersion)
}
errs := []string{} errs := []string{}
cmd.Flags().VisitAll(func(f *pflag.Flag) { cmd.Flags().VisitAll(func(f *pflag.Flag) {