Commit Graph

38 Commits

Author SHA1 Message Date
Sebastiaan van Stijn 416c061000 linting: fmt.Errorf can be replaced with errors.New (perfsprint)
internal/test/cli.go:175:14: fmt.Errorf can be replaced with errors.New (perfsprint)
        return nil, fmt.Errorf("no notary client available unless defined")
                    ^
    cli/command/cli.go:318:29: fmt.Errorf can be replaced with errors.New (perfsprint)
            return docker.Endpoint{}, fmt.Errorf("no context store initialized")
                                      ^
    cli/command/container/attach.go:161:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                return fmt.Errorf(result.Error.Message)
                       ^
    cli/command/container/opts.go:577:16: fmt.Errorf can be replaced with errors.New (perfsprint)
                return nil, fmt.Errorf("--health-start-period cannot be negative")
                            ^
    cli/command/container/opts.go:580:16: fmt.Errorf can be replaced with errors.New (perfsprint)
                return nil, fmt.Errorf("--health-start-interval cannot be negative")
                            ^
    cli/command/container/stats.go:221:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                return fmt.Errorf("filtering is not supported when specifying a list of containers")
                       ^
    cli/command/container/attach_test.go:82:17: fmt.Errorf can be replaced with errors.New (perfsprint)
            expectedErr = fmt.Errorf("unexpected error")
                          ^
    cli/command/container/create_test.go:234:40: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image")
                                                       ^
    cli/command/container/list_test.go:150:17: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return nil, fmt.Errorf("error listing containers")
                                ^
    cli/command/container/rm_test.go:40:31: fmt.Errorf can be replaced with errors.New (perfsprint)
                            return errdefs.NotFound(fmt.Errorf("Error: no such container: " + container))
                                                    ^
    cli/command/container/run_test.go:138:40: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return container.CreateResponse{}, fmt.Errorf("shouldn't try to pull image")
                                                       ^
    cli/command/image/pull_test.go:115:49: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return io.NopCloser(strings.NewReader("")), fmt.Errorf("shouldn't try to pull image")
                                                                ^
    cli/command/network/connect.go:88:16: fmt.Errorf can be replaced with errors.New (perfsprint)
                return nil, fmt.Errorf("invalid key/value pair format in driver options")
                            ^
    cli/command/plugin/create_test.go:96:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                return fmt.Errorf("Error creating plugin")
                       ^
    cli/command/plugin/disable_test.go:32:12: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return fmt.Errorf("Error disabling plugin")
                           ^
    cli/command/plugin/enable_test.go:32:12: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return fmt.Errorf("failed to enable plugin")
                           ^
    cli/command/plugin/inspect_test.go:55:22: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return nil, nil, fmt.Errorf("error inspecting plugin")
                                     ^
    cli/command/plugin/install_test.go:43:17: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return nil, fmt.Errorf("Error installing plugin")
                                ^
    cli/command/plugin/install_test.go:51:17: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return nil, fmt.Errorf("(image) when fetching")
                                ^
    cli/command/plugin/install_test.go:95:17: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return nil, fmt.Errorf("should not try to install plugin")
                                ^
    cli/command/plugin/list_test.go:35:41: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return types.PluginsListResponse{}, fmt.Errorf("error listing plugins")
                                                        ^
    cli/command/plugin/remove_test.go:27:12: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return fmt.Errorf("Error removing plugin")
                           ^
    cli/command/registry/login_test.go:36:46: fmt.Errorf can be replaced with errors.New (perfsprint)
            return registrytypes.AuthenticateOKBody{}, fmt.Errorf("Invalid Username or Password")
                                                       ^
    cli/command/registry/login_test.go:44:46: fmt.Errorf can be replaced with errors.New (perfsprint)
            return registrytypes.AuthenticateOKBody{}, fmt.Errorf(errUnknownUser)
                                                       ^
    cli/command/system/info.go:190:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("errors pretty printing info")
                   ^
    cli/command/system/prune.go:77:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf(`ERROR: The "until" filter is not supported with "--volumes"`)
                   ^
    cli/command/system/version_test.go:19:28: fmt.Errorf can be replaced with errors.New (perfsprint)
                return types.Version{}, fmt.Errorf("no server")
                                        ^
    cli/command/trust/key_load.go:112:22: fmt.Errorf can be replaced with errors.New (perfsprint)
                    return []byte{}, fmt.Errorf("could not decrypt key")
                                     ^
    cli/command/trust/revoke.go:44:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("cannot use a digest reference for IMAGE:TAG")
                   ^
    cli/command/trust/revoke.go:105:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("no signed tags to remove")
                   ^
    cli/command/trust/signer_add.go:56:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("releases is a reserved keyword, please use a different signer name")
                   ^
    cli/command/trust/signer_add.go:60:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("path to a public key must be provided using the `--key` flag")
                   ^
    opts/config.go:71:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("source is required")
                   ^
    opts/mount.go:168:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("type is required")
                   ^
    opts/mount.go:172:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("target is required")
                   ^
    opts/network.go:90:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                return fmt.Errorf("network name/id is not specified")
                       ^
    opts/network.go:129:18: fmt.Errorf can be replaced with errors.New (perfsprint)
            return "", "", fmt.Errorf("invalid key value pair format in driver options")
                           ^
    opts/opts.go:404:13: fmt.Errorf can be replaced with errors.New (perfsprint)
            return 0, fmt.Errorf("value is too precise")
                      ^
    opts/opts.go:412:18: fmt.Errorf can be replaced with errors.New (perfsprint)
            return "", "", fmt.Errorf("empty string specified for links")
                           ^
    opts/parse.go:84:37: fmt.Errorf can be replaced with errors.New (perfsprint)
            return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: no policy provided before colon")
                                              ^
    opts/parse.go:89:38: fmt.Errorf can be replaced with errors.New (perfsprint)
                return container.RestartPolicy{}, fmt.Errorf("invalid restart policy format: maximum retry count must be an integer")
                                                  ^
    opts/port.go:105:13: fmt.Errorf can be replaced with errors.New (perfsprint)
                        return fmt.Errorf("hostip is not supported")
                               ^
    opts/secret.go:70:10: fmt.Errorf can be replaced with errors.New (perfsprint)
            return fmt.Errorf("source is required")
                   ^
    opts/env_test.go:57:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                err:   fmt.Errorf("invalid environment variable: =a"),
                       ^
    opts/env_test.go:93:11: fmt.Errorf can be replaced with errors.New (perfsprint)
                err:   fmt.Errorf("invalid environment variable: ="),
                       ^
    cli-plugins/manager/error_test.go:16:11: fmt.Errorf can be replaced with errors.New (perfsprint)
        inner := fmt.Errorf("testing")
                 ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit dfec976e84)
Signed-off-by: Cory Snider <csnider@mirantis.com>
2024-09-03 19:35:23 -04:00
Sebastiaan van Stijn 6f353c8000
cli-plugins/manager: fix deprecation comment of Metadata.Experimental
This field was marked deprecated in 977d3ae046,
which is part of v20.10 and up, but the comment was missing a newline before
the deprecation message, which may be picked up by IDEs, but is not matching
the correct format, so may not be picked up by linters.

This patch fixes the format, to make sure linters pick up that the field is
deprecated.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 72e3813ab9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-05-09 22:21:46 +02:00
Kevin Alvarez c7cdab58d2
improve plugins listing performance
We can slightly improve plugins listing by spawning a
goroutine for each iteration.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 89583b92b7)

# Conflicts:
#	vendor.mod
#	vendor/modules.txt
2023-04-01 16:34:51 +02:00
Kevin Alvarez d93d78588d
load plugin command stubs when required
We are currently loading plugin command stubs for every
invocation which still has a significant performance hit.
With this change we are doing this operation only if cobra
completion arg request is found.

- 20.10.23: `docker --version` takes ~15ms
- 23.0.1: `docker --version` takes ~93ms

With this change `docker --version` takes ~9ms

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit c39c711a18)
2023-03-31 16:38:01 +02:00
Sebastiaan van Stijn 5aba4860de
cli-plugins/manager: TestPluginError: don't use yaml.Marshal
The test used  `gopkg.in/yaml.v2` to verify the TextMarshaller implementation,
which was implemented to allow printing the errors in JSON formatted output;

> This exists primarily to implement encoding.TextMarshaller such that
> rendering a plugin as JSON (e.g. for `docker info -f '{{json .CLIPlugins}}'`)
> renders the Err field as a useful string and not just `{}`.

Given that both yaml.Marshal and json.Marshal use this, we may as well use
Go's stdlib.

While updating, also changed some of the assertions to checks, so that we don't
fail the test early.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-17 13:17:51 +01:00
Sebastiaan van Stijn 616124525e
format go with gofumpt (with -lang=1.19)
Looks like the linter uses an explicit -lang, which (for go1.19)
results in some additional formatting for octal values.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-30 19:14:36 +02:00
Sebastiaan van Stijn 1da95ff6aa
format code with gofumpt
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-30 11:59:11 +02:00
Sebastiaan van Stijn 90f1238fb2
cli-plugins/manager: add IsPluginCommand(() utility
This makes it more convenient to check if a command is a plugin-stub

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-30 02:24:23 +02:00
Sebastiaan van Stijn 491407b541
linting: remove unused nolint comments (nolintlint)
cli/context/store/tlsstore.go:46:88: directive `//nolint:unused` is unused for linter "unused" (nolintlint)
    func (s *tlsStore) remove(contextID contextdir, endpointName, filename string) error { //nolint:unused
                                                                                           ^
    cli-plugins/manager/plugin.go:37:1: directive `//nolint:gocyclo` is unused for linter "gocyclo" (nolintlint)
    //nolint:gocyclo
    ^
    cli/command/image/formatter_history_test.go:189:2: directive `//nolint:lll` is unused for linter "lll" (nolintlint)
        //nolint:lll
        ^
    cli/command/service/list.go:113:1: directive `//nolint:gocyclo` is unused for linter "gocyclo" (nolintlint)
    //nolint:gocyclo
    ^
    cli/command/stack/swarm/deploy_composefile.go:178:1: directive `//nolint:gocyclo` is unused for linter "gocyclo" (nolintlint)
    //nolint:gocyclo
    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-09-03 21:25:34 +02:00
Sebastiaan van Stijn 82427d1a07
format (GoDoc) comments with Go 1.19 to prepare for go updates
Older versions of Go do not format these comments, so we can already
reformat them ahead of time to prevent gofmt linting failing once
we update to Go 1.19 or up.

Result of:

    gofmt -s -w $(find . -type f -name '*.go' | grep -v "/vendor/")

With some manual adjusting.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-07-19 19:10:16 +02:00
Nicolas De Loof cbec75e2f3
Adopt Cobra completion v2 to support completion by CLI plugins
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-05-12 12:59:10 +02:00
Sebastiaan van Stijn a0f0578299
gofmt with go1.17
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-26 20:21:00 +01:00
Sebastiaan van Stijn 6c06950cdf
cli-plugins/manager: remove uses of deprecated io/ioutil
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-02-25 16:01:20 +01:00
CrazyMax 6fef143dbc
Set buildx as default builder
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-03 10:38:05 +01:00
Tibor Vass 8d199d5bba Use golang.org/x/sys/execabs
On Windows, the os/exec.{Command,CommandContext,LookPath} functions
resolve command names that have neither path separators nor file extension
(e.g., "git") by first looking in the current working directory before
looking in the PATH environment variable.
Go maintainers intended to match cmd.exe's historical behavior.

However, this is pretty much never the intended behavior and as an abundance of precaution
this patch prevents that when executing commands.
Example of commands that docker.exe may execute: `git`, `docker-buildx` (or other cli plugin), `docker-credential-wincred`, `docker`.

Note that this was prompted by the [Go 1.15.7 security fixes](https://blog.golang.org/path-security), but unlike in `go.exe`,
the windows path lookups in docker are not in a code path allowing remote code execution, thus there is no security impact on docker.

Signed-off-by: Tibor Vass <tibor@docker.com>
2021-01-26 17:18:04 +00:00
Sebastiaan van Stijn 977d3ae046
Always enable experimental features
The CLI disabled experimental features by default, requiring users
to set a configuration option to enable them.

Disabling experimental features was a request from Enterprise users
that did not want experimental features to be accessible.

We are changing this policy, and now enable experimental features
by default. Experimental features may still change and/or removed,
and will be highlighted in the documentation and "usage" output.

For example, the `docker manifest inspect --help` output now shows:

    EXPERIMENTAL:
      docker manifest inspect is an experimental feature.

      Experimental features provide early access to product functionality. These features
      may change between releases without warning or can be removed entirely from a future
      release. Learn more about experimental features: https://docs.docker.com/go/experimental/

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-02 15:59:42 +02:00
Sebastiaan van Stijn 6703919c71
Replace vbom.ml/util with fvbommel/sortorder
The vanity domain is down, and the project has moved
to a new location.

vendor check started failing because of this:

    Collecting initial packages
    Download dependencies
    unrecognized import path "vbom.ml/util" (https fetch: Get https://vbom.ml/util?go-get=1: dial tcp: lookup vbom.ml on 169.254.169.254:53: no such host)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-28 15:35:42 +02:00
Silvin Lubecki 459c6082f8 Removing CLI plugins API documentation from official documentation as it is now deprecated.
Adding depreciation notice.

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2020-05-19 10:37:35 +02:00
Sebastiaan van Stijn bb7ef2cb3a
Update some uses of errors.Cause() to errors.Is()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-05-10 19:56:35 +02:00
Sebastiaan van Stijn 2c0e93063b
bump gotest.tools v3.0.1 for compatibility with Go 1.14
full diff: https://github.com/gotestyourself/gotest.tools/compare/v2.3.0...v3.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-02-23 00:28:55 +01:00
Sebastiaan van Stijn 54ba28f402
docker info: list CLI plugins alphabetically
Before this change, plugins were listed in a random order:

    Client:
     Debug Mode: false
     Plugins:
      doodle: Docker Doodles  all around! 🐳 🎃 (thaJeztah, v0.0.1)
      shell: Open a browser shell on the Docker Host. (thaJeztah, v0.0.1)
      app: Docker Application (Docker Inc., v0.8.0)
      buildx: Build with BuildKit (Docker Inc., v0.3.1-tp-docker)

With this change, plugins are listed alphabetically:

    Client:
     Debug Mode: false
     Plugins:
      app: Docker Application (Docker Inc., v0.8.0)
      buildx: Build with BuildKit (Docker Inc., v0.3.1-tp-docker)
      doodle: Docker Doodles  all around! 🐳 🎃 (thaJeztah, v0.0.1)
      shell: Open a browser shell on the Docker Host. (thaJeztah, v0.0.1)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-12-31 14:33:07 +01:00
Tibor Vass bb8e89bb2e cli-plugins: add test names for easier debugging
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-22 15:35:34 +00:00
Tibor Vass 6ca8783730 cli-plugins: add concept of experimental plugin, only enabled in experimental mode
To test, add $(pwd)/build/plugins-linux-amd64 to "cliPluginsExtraDirs" config and run:
make plugins
make binary
HELLO_EXPERIMENTAL=1 docker helloworld

To show it enabled:
HELLO_EXPERIMENTAL=1 DOCKER_CLI_EXPERIMENTAL=enabled docker helloworld

Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-22 15:35:34 +00:00
Tibor Vass 1ed02c40fe cli-plugins: alias an existing allowed command (only builder for now)
With this patch it is possible to alias an existing allowed command.
At the moment only builder allows an alias.

This also properly puts the build command under builder, instead of image
where it was for historical reasons.

Signed-off-by: Tibor Vass <tibor@docker.com>
2019-04-19 01:26:45 +00:00
Stefan Scherer 4d3a76d71e
Search Windows CLI plugins also in ProgramFiles
Signed-off-by: Stefan Scherer <stefan.scherer@docker.com>
2019-03-20 11:45:03 -07:00
Nick Adcock ff51b0d77d harden config.Path() to disallow directory traversal
Signed-off-by: Nick Adcock <nick.adcock@docker.com>
2019-03-07 14:40:53 +00:00
Silvin Lubecki 11985c6250
Merge pull request #1675 from ulyssessouza/format-plugin-vendor-version-help
Reformat plugin's vendor position and add version on --help
2019-02-25 11:47:09 +01:00
Ulysses Souza 92013600f9 Refactor plugins' vendor location on --help
- The placement of the vendor is now in the end of the line.
- A '*' is now added as suffix of plugins' top level commands.

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-02-21 17:54:11 +01:00
Ian Campbell 891b3d953e cli-plugins: use `docker system dial-stdio` to call the daemon
This means that plugins can use whatever methods the monolithic CLI supports,
which is good for consistency.

This relies on `os.Args[0]` being something which can be executed again to
reach the same binary, since it is propagated (via an envvar) to the plugin for
this purpose. This essentially requires that the current working directory and
path are not modified by the monolithic CLI before it launches the plugin nor
by the plugin before it initializes the client. This should be the case.

Previously the fake apiclient used by `TestExperimentalCLI` was not being used,
since `cli.Initialize` was unconditionally overwriting it with a real one
(talking to a real daemon during unit testing, it seems). This wasn't expected
nor desirable and no longer happens with the new arrangements, exposing the
fact that no `pingFunc` is provided, leading to a panic. Add a `pingFunc` to
the fake client to avoid this.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-02-18 11:53:37 +00:00
Ian Campbell baabf6e8ad Ensure that plugins are only listed once in help outputs.
They were listed twice in `docker --help` (but not `docker help`), since the
stubs were added in both `tryRunPluginHelp` and the `setHelpFunc` closure.

Calling `AddPluginStubCommands` earlier in `setHelpFunc` before the call to
`tryRunPluginHelp` is sufficient. Also it is no longer necessary to add just
valid plugins (`tryRunPluginHelp` handles invalid plugins correctly) so remove
that logic (which was in any case broken for e.g. `docker --help`).

Update the e2e test to check for duplicate entries and also to test `docker
--help` which was previously missed.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:55:42 +00:00
Ian Campbell 0a89eb554b Ensure plugins default search path obeys `--config`
A static global initialiser happens before the arguments are parsed, so we need
to calculate the path later.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:45:26 +00:00
Ian Campbell 1337895751 Check for `.exe` case insensitively
On Windows `foo.exe`, `foo.eXe` and `foo.EXE` are equally executable.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:45:26 +00:00
Ian Campbell 63f3ad181b Refactor code which deals with Windows' `.exe` suffix
Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:45:26 +00:00
Ian Campbell 609dcb9152 Documentation on writing a plugin
Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:45:26 +00:00
Ian Campbell 1c576e9043 Integrate CLI plugins into `docker info`
Fairly straight forward. It became necessary to wrap `Plugin.Err` with a type
which implements `encoding.MarshalText` in order to have that field rendered
properly in the `docker info -f '{{json}}'` output.

Since I changed the type somewhat I also added a unit test for `formatInfo`.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:45:26 +00:00
Ian Campbell f912b55bd1 Integrate CLI plugins into `docker help` output.
To do this we add a stub `cobra.Command` for each installed plugin (only when
invoking `help`, not for normal running).

This requires a function to list all available plugins so that is added here.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:44:06 +00:00
Ian Campbell f1f31abbe5 Add support for running a CLI plugin
Also includes the  scaffolding for finding a validating plugin candidates.

Argument validation is moved to RunE to support this, so `noArgs` is removed.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-30 13:44:04 +00:00
Ian Campbell e96240427f Add basic framework for writing a CLI plugin
That is, the helper to be used from the plugin's `main`.

Also add a `helloworld` plugin example and build integration.

Signed-off-by: Ian Campbell <ijc@docker.com>
2019-01-29 11:26:40 +00:00