As pointed out in #1459, docker cli fails to detect that the input is a tarball,
in case it is generated by `git archive --format=tgz`.
This happens because `git archive` adds some metadata to the initial tar header,
and so it is more than 1 block (of 512 bytes) long, while we only provide 1 block
to archive/tar.Next() and it fails.
To fix, give it 2 blocks :)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This adds validation to `docker container run` / `docker container create`;
Validation of labels provided through flags was removed in 31dc5c0a9a,
after the validation was changed to fix labels without values, and to prevent
labels from being expanded with environment variables in 2b17f4c8a8
However, now empty label names from _files_ (`--label-file`) followed different
validation rules than labels passed through `--label`.
This patch adds back minimal validation for labels passed through the command-line
Before this patch:
```bash
docker container create \
--name label \
--label==with-leading-equal-sign \
--label=without-value \
--label=somelabel=somevalue \
--label " = " \
--label=with-quotes-in-value='{"foo"}' \
--label='with"quotes"in-key=test' \
busybox
docker container inspect --format '{{json .Config.Labels}}' label
```
```json
{
"": "with-leading-equal-sign",
" ": " ",
"somelabel": "somevalue",
"with\"quotes\"in-key": "test",
"with-quotes-in-value": "{\"foo\"}",
"without-value": ""
}
```
After this patch:
```bash
docker container create \
--name label \
--label==with-leading-equal-sign \
--label=without-value \
--label=somelabel=somevalue \
--label " = " \
--label=with-quotes-in-value='{"foo"}' \
--label='with"quotes"in-key=test' \
busybox
invalid argument "=with-leading-equal-sign" for "-l, --label" flag: invalid label format: "=with-leading-equal-sign"
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This patch fixes a bug where labels use the same behavior as `--env`, resulting
in a value to be copied from environment variables with the same name as the
label if no value is set (i.e. a simple key, no `=` sign, no value).
An earlier pull request addressed similar cases for `docker run`;
2b17f4c8a8, but this did not address the
same situation for (e.g.) `docker service create`.
Digging in history for this bug, I found that use of the `ValidateEnv`
function for labels was added in the original implementation of the labels feature in
abb5e9a077 (diff-ae476143d40e21ac0918630f7365ed3cR34)
However, the design never intended it to expand environment variables,
and use of this function was either due to either a "copy/paste" of the
equivalent `--env` flags, or a misunderstanding (the name `ValidateEnv` does
not communicate that it also expands environment variables), and the existing
`ValidateLabel` was designed for _engine_ labels (which required a value to
be set).
Following the initial implementation, other parts of the code followed
the same (incorrect) approach, therefore leading the bug to be introduced
in services as well.
This patch:
- updates the `ValidateLabel` to match the expected validation
rules (this function is no longer used since 31dc5c0a9a),
and the daemon has its own implementation)
- corrects various locations in the code where `ValidateEnv` was used instead of `ValidateLabel`.
Before this patch:
```bash
export SOME_ENV_VAR=I_AM_SOME_ENV_VAR
docker service create --label SOME_ENV_VAR --tty --name test busybox
docker service inspect --format '{{json .Spec.Labels}}' test
{"SOME_ENV_VAR":"I_AM_SOME_ENV_VAR"}
```
After this patch:
```bash
export SOME_ENV_VAR=I_AM_SOME_ENV_VAR
docker service create --label SOME_ENV_VAR --tty --name test busybox
docker container inspect --format '{{json .Config.Labels}}' test
{"SOME_ENV_VAR":""}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This maps the `--template-driver` flag on secret and config creation.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The warning, printed before running `docker system prune` was printing the
filters in JSON format.
This patch attempts to make the output human readable;
- updating the code, and template to print filters individually
- reducing the indentation (which was quite deep)
Before this patch was applied;
```
docker system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- label={"label":{"bar=baz":true,"hello-world":true},"label!":{"foo=bar":true},"until":{"24h":true}}
Are you sure you want to continue? [y/N]
```
With this patch applied;
```
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Items to be pruned will be filtered with:
- label!=foo=bar
- label!=never=remove-me
- label=bar=baz
- label=hello-world
- label=remove=me
- until=24h
Are you sure you want to continue? [y/N]
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The warning, printed before runing docker system prune was missing any filter
that was set in the configuration file. In addition, the warning prefixes the
filters with `label=`, which is no longer accurate, now that the prune command
also supports "until" as a filter.
Before this change, only the filters set on the command-line were shown,
and any filter set in the configuration file was missing;
```
mkdir -p ./test-config
echo '{"pruneFilters": ["label!=never=remove-me", "label=remove=me"]}' > test-config/config.json
docker --config=./test-config system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- label={"label":{"bar=baz":true,"hello-world":true},"label!":{"foo=bar":true},"until":{"24h":true}}
Are you sure you want to continue? [y/N]
```
With this patch applied, both options from the commandline and options set
in the configuration file are shown;
```
mkdir -p ./test-config
echo '{"pruneFilters": ["label!=never=remove-me", "label=remove=me"]}' > test-config/config.json
docker --config=./test-config system prune --filter until=24h --filter label=hello-world --filter label!=foo=bar --filter label=bar=baz
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
- Elements to be pruned will be filtered with:
- filter={"label":{"bar=baz":true,"hello-world":true,"remove=me":true},"label!":{"foo=bar":true,"never=remove-me":true},"until":{"24h":true}}
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
- when using "--context default" parameter
- when printing the list of contexts
- when exporting the default context to a tarball
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
(+1 squashed commit)
Squashed commits:
[20670495] Fix CLI initialization for the `docker stack deploy --help` command and ensure that the dockerCli.CurrentContext() always returns a non empty context name (default as a fallback)
Remove now obsolete code handling empty string context name
Minor code cleanup
Signed-off-by: Jean-Christophe Sirot <jean-christophe.sirot@docker.com>
This makes things more idempotent, rather than relying on undoing the
interspersed settings.
Note that the underlying `Flag`s remain shared, it's just the `FlagSet` which
is duplicated.
Signed-off-by: Ian Campbell <ijc@docker.com>
The issue with plugin options clashing with globals is that when cobra is
parsing the command line and it comes across an argument which doesn't start
with a `-` it (in the absence of plugins) distinguishes between "argument to
current command" and "new subcommand" based on the list of registered sub
commands.
Plugins breaks that model. When presented with `docker -D plugin -c foo` cobra
parses up to the `plugin`, sees it isn't a registered sub-command of the
top-level docker (because it isn't, it's a plugin) so it accumulates it as an
argument to the top-level `docker` command. Then it sees the `-c`, and thinks
it is the global `-c` (for AKA `--context`) option and tries to treat it as
that, which fails.
In the specific case of the top-level `docker` subcommand we know that it has
no arguments which aren't `--flags` (or `-f` short flags) and so anything which
doesn't start with a `-` must either be a (known) subcommand or an attempt to
execute a plugin.
We could simply scan for and register all installed plugins at start of day, so
that cobra can do the right thing, but we want to avoid that since it would
involve executing each plugin to fetch the metadata, even if the command wasn't
going to end up hitting a plugin.
Instead we can parse the initial set of global arguments separately before
hitting the main cobra `Execute` path, which works here exactly because we know
that the top-level has no non-flag arguments.
One slight wrinkle is that the top-level `PersistentPreRunE` is no longer
called on the plugins path (since it no longer goes via `Execute`), so we
arrange for the initialisation done there (which has to be done after global
flags are parsed to handle e.g. `--config`) to happen explictly after the
global flags are parsed. Rather than make `newDockerCommand` return the
complicated set of results needed to make this happen, instead return a closure
which achieves this.
The new functionality is introduced via a common `TopLevelCommand` abstraction
which lets us adjust the plugin entrypoint to use the same strategy for parsing
the global arguments. This isn't strictly required (in this case the stuff in
cobra's `Execute` works fine) but doing it this way avoids the possibility of
subtle differences in behaviour.
Fixes#1699, and also, as a side-effect, the first item in #1661.
Signed-off-by: Ian Campbell <ijc@docker.com>
This happens on Windows when dialing a named pipe (a path which is used by CLI
plugins), in that case some debugging shows:
DEBU[0000] conn is a *winio.win32MessageBytePipe
DEBU[0000] conn is a halfReadCloser: false
DEBU[0000] conn is a halfWriteCloser: true
the raw stream connection does not implement halfCloser
In such cases we can simply wrap with a nop function since closing for read
isn't too critical.
Signed-off-by: Ian Campbell <ijc@docker.com>
After switching to Go 1.12, the format-string causes an error;
```
=== Errors
cli/config/config_test.go:154:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
cli/config/config_test.go:217:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
cli/config/config_test.go:253:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
cli/config/config_test.go:288:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
cli/config/config_test.go:435:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
cli/config/config_test.go:448:3: Fatalf format %q has arg config of wrong type *github.com/docker/cli/cli/config/configfile.ConfigFile
DONE 1115 tests, 2 skipped, 6 errors in 215.984s
make: *** [Makefile:22: test-coverage] Error 2
Exited with code 2
```
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `conn` here is `*winio.win32MessageBytePipe` which does not have a
`CloseRead` method (it does have `CloseWrite`) resulting in:
docker@WIN-NUC0 C:\Users\docker>.\docker-windows-amd64.exe system dial-stdio
the raw stream connection does not implement halfCloser
Also disable the path which uses this for cli-plugins on Windows.
Signed-off-by: Ian Campbell <ijc@docker.com>
Plugins are expected to be management commands ("docker <object> <verb>").
This patch modified the usage output to shown plugins in the "Management commands"
section.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>