This function was parsing the same URL twice; first to detect the
scheme, then again (through ssh.ParseURL) to construct a ssh.Spec.
Change the function to use the URL that's parsed, and use ssh.NewSpec
instead.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Cobra's shell completion has specific rules to decide whether a flag can
be accepted multiple times. If a flag does not meet that rule, it only
completes the flag name once; some of those rules depend on the "type"
of the option to end with "Array" or "Slice", which most of our options
don't.
Starting with Cobra 1.9, it also checks whether an option implements
the [cobra.SliceValue] interface (see [spf13/cobra 2210]).
This patch implements the [cobra.SliceValue] interface on ListOpts, so
that these options can be completed multiple times.
In a follow-up, we can update our code to replace our uses of `GetAll()`,
which is identical with the `GetSlice()` method, and potentially deprecate
the old method.
Before this patch, ListOpts would only be completed once when completing
flag names. For example, the following would show the `--label` flag the
first time, but omit it if a `--label` flag was already set;
docker run--l<TAB>
--label (Set meta data on a container) --link-local-ip (Container IPv4/IPv6 link-local addresses)
--label-file (Read in a line delimited file of labels) --log-driver (Logging driver for the container)
--link (Add link to another container) --log-opt (Log driver options)
docker run --label hello --l<TAB>
--label-file (Read in a line delimited file of labels) --link-local-ip (Container IPv4/IPv6 link-local addresses) --log-opt (Log driver options)
--link (Add link to another container) --log-driver (Logging driver for the container)
With this patch, the completion script correctly identifies the `--label`
flag to be accepted multiple times, and also completes it when already
set;
docker run --label hello --l<TAB>
--label (Set meta data on a container) --link-local-ip (Container IPv4/IPv6 link-local addresses)
--label-file (Read in a line delimited file of labels) --log-driver (Logging driver for the container)
--link (Add link to another container) --log-opt (Log driver options)
[cobra.SliceValue]: https://pkg.go.dev/github.com/spf13/cobra@v1.9.1#SliceValue
[spf13/cobra 2210]: https://github.com/spf13/cobra/pull/2210
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, `docker stack deploy` would not validate the image
reference on the client side, depending on the daemon to return an error,
which was not always easy to interpret;
docker stack deploy -c docker-compose.yaml mystack
Creating service mystack_myservice
failed to create service mystack_myservice: Error response from daemon: rpc error: code = InvalidArgument desc = ContainerSpec: image reference must be provided
IMAGE_NAME=FOOBAR docker stack deploy -c docker-compose.yaml mystack
Creating service mystack_myservice
failed to create service mystack_myservice: Error response from daemon: rpc error: code = InvalidArgument desc = ContainerSpec: "FOOBAR" is not a valid repository/tag
With this patch, the CLI validates the image-reference for each service,
producing an error if the reference is empty or invalid.
docker stack config -c docker-compose.yaml
invalid service myservice: no image specified
IMAGE_NAME=FOOBAR ~/Projects/cli/build/docker stack deploy -c docker-compose.yaml mystack
invalid image reference for service myservice: invalid reference format: repository name (library/FOOBAR) must be lowercase
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Aligning with where we put this in moby, and contrib is a slightly
more suitable location for this.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- use designated example domains as example value
- swap "expected" and "actual" values in assertions
- add doc / name for each test
- add test-cases for remote commands
- also test the Spec that's produced, not just the args
- merge two test-cases that could be combined
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before this patch, a valid, but empty set of credentials would still
write a config-file to the container and set `DOCKER_CONFIG`:
mkdir -p tmpConfig
export DOCKER_CONFIG=$PWD/tmpConfig
echo '{}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {}
}
echo '{"auths": {}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {}
}
echo '{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
With this patch, the `DOCKER_CONFIG` env-var and config-file are only created
if we have credentials to set;
mkdir -p tmpConfig
export DOCKER_CONFIG=$PWD/tmpConfig
echo '{}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
cat: can't open '/run/secrets/docker/config.json': No such file or directory
echo '{"auths": {}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
cat: can't open '/run/secrets/docker/config.json': No such file or directory
echo '{"auths": {"https://index.docker.io/v1/": {"auth": "am9lam9lOmhlbGxv"}}}' > "${DOCKER_CONFIG}/config.json"
docker run --rm --use-api-socket alpine cat /run/secrets/docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "am9lam9lOmhlbGxv"
}
}
}
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Go maintainers started to unconditionally update the minimum go version
for golang.org/x/ dependencies to go1.23, which means that we'll no longer
be able to support any version below that when updating those dependencies;
> all: upgrade go directive to at least 1.23.0 [generated]
>
> By now Go 1.24.0 has been released, and Go 1.22 is no longer supported
> per the Go Release Policy (https://go.dev/doc/devel/release#policy).
>
> For golang/go#69095.
This updates our minimum version to go1.23, as we won't be able to maintain
compatibility with older versions because of the above.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
For now, these are not exported and included in the cli/commands/contexts
package; a copy of this also lives in cmd/docker, but we need to find a
good place for these completions, as some of them bring in additional
dependencies.
Commands that accept multiple arguments provide completion, but removing
duplicates:
docker context inspect<TAB>
default desktop-linux (current) production tcd
docker context inspec default<TAB>
desktop-linux (current) production tcd
docker context inspect default tcd<TAB>
desktop-linux (current) production
For "context export", we provide completion for the first argument, after
which file-completion is provided:
# provides context names completion for the first argument
docker context export production<TAB>
default desktop-linux (current) production tcd
# then provides completion for filenames
docker context export desktop-linux<TAB>
build/ man/ TESTING.md
cli/ docker.Makefile go.mod
...
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Using `--platform=linux` or `--platform=windows` is not commonly
used (or recommended). Let's remove these from the list of suggested
platforms.
We should tweak this completion further, and sort the list based
on the daemon's platform (putting linux first for a Linux daemon,
and windows first on a Windows daemon), possibly with the correct
architecture (and os-version) included, but we don't yet provide
that information in `/_ping`.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Adds a flag to the create and run command, `--use-api-socket`, that can
be used to start a container with the correctly configured parameters to
ensure that accessing the docker socket will work with out managing bind
mounts and authentication injection.
The implementation in this PR resolves the tokens for the current
credential set in the client and then copies it into a container at the
well know location of /run/secrets/docker/config.json, setting
DOCKER_CONFIG to ensure it is resolved by existing tooling. We use a
compose-compatible secret location with the hope that the CLI and
compose can work together seamlessly.
The bind mount for the socket is resolved from the current context,
erroring out if the flag is set and the provided socket is not a unix
socket.
There are a few drawbacks to this approach but it resolves a long
standing pain point. We'll continue to develop this as we understand
more use cases but it is marked as experimental for now.
Signed-off-by: Stephen Day <stephen.day@docker.com>