Compare commits

...

458 Commits

Author SHA1 Message Date
f9cde631a2 Merge pull request #347 from seemethere/cherry_pick_packaging_70
[17.12] Pass VERSION to engine static builds
2017-12-11 16:20:25 -08:00
264ab31364 Pass VERSION to engine static builds
VERSION file does not exist anymore for moby/moby so we need to
compensate

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit c411321b8870101c227b03e64930260984c862fd)
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2017-12-12 00:17:04 +00:00
5d7e8f3778 Merge pull request #345 from jose-bigio/17.12_bump
[17.12] Bump version to 17.12.0-ce-rc2
2017-12-11 13:34:57 -08:00
74e076ab06 Merge pull request #346 from jose-bigio/17.12_changelog
[17.12] update changelog for 17.12.0 rc2
2017-12-11 13:34:26 -08:00
184c27d785 Merge pull request #342 from thaJeztah/17.12-backport-vendor-archive
[17.12] vendor: update archive/tar
2017-12-11 13:32:05 -08:00
33d771ed94 Update to 17.12 changelog for rc2
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2017-12-11 11:27:18 -08:00
50e759c017 Bump version to 17.12.0-ce-rc2
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2017-12-11 10:34:24 -08:00
bde1eb8281 Merge pull request #340 from seemethere/cherry_pick_version_packaging
[17.12] Defaults Makefile VERSION variable to 0.0.0-dev
2017-12-11 10:08:35 -08:00
fb8384a555 Merge pull request #343 from thaJeztah/17.12-backport-update-api-changelog
[17.12] Update API version-history for 1.35
2017-12-08 20:46:27 -08:00
86127edfd5 Merge pull request #341 from seemethere/cherry_pick_fix_f27
[17.12] Do not terminate on missing build-ids
2017-12-08 20:15:20 -08:00
d2b3575a03 Merge pull request #344 from andrewhsu/tt
[17.12] skip DockerTrustSuite tests for 17.12
2017-12-08 18:00:29 -08:00
d256539bf4 update integration-cli tests for stderr output
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
(cherry picked from commit 250b84ee88)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2017-12-08 16:49:02 -08:00
fbfecebc0a Blacklist tests, will be rewritten later on
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit 4e81e4fa4e)
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
(cherry picked from commit ec6b0a1a4a)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2017-12-08 16:49:01 -08:00
f73a0ff35c Update API version-history for 1.35
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 8a9d926b553345be530ddc51374c9817fcbea784)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-12-07 16:21:40 -08:00
5f5c42593a vendor: update archive/tar
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 13954b0a6282d919c91626a23967377c19ee7aa2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2017-12-07 16:20:52 -08:00
fcde1eb2b7 Do not terminate on missing build-ids
Relates to an upgrade in `rpm` to `14.4.0`, where missing build-ids now
cause builds to self-terminate. May be needed in other distros if/when
the `rpm` package is updated in those repos.

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit dcd681da54f2c2b2286cc09d053dd6cb865d3f98)
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2017-12-08 00:11:46 +00:00
b52085fc2e Defaults Makefile VERSION variable to 0.0.0-dev (#67)
When building we should default to a dummy version unless otherwise
specified so we don't get ourselves confused over what is official and
what is not.

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit ffcd040b5c3bd4f81e1d1f11c32f9bb81e235ed1)

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2017-12-07 22:58:01 +00:00
ee2f9437b6 Merge pull request #337 from andrewhsu/v12
[17.12] bump version to 17.12.0-ce-rc1
2017-12-06 23:33:02 -08:00
8e51e59c8a bump version to 17.12.0-ce-rc1
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2017-12-06 23:29:37 -08:00
a4b9862912 Merge pull request #335 from vieux/CHANGELOG-17.12
[17.12] add changelog for 17.12.0-ce-rc1
2017-12-06 22:50:06 -08:00
718cc1a071 changelog for 17.12.0-ce-rc1
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2017-12-06 22:48:27 -08:00
704b884e52 Merge component 'engine' from git@github.com:moby/moby master 2017-12-07 02:18:48 +00:00
521d1c4f0b Merge component 'cli' from git@github.com:docker/cli master 2017-12-07 01:55:54 +00:00
9b5e4afbf7 Merge pull request #35698 from anshulpundir/vndr
Vendor swarmkit to 4429c763
Upstream-commit: a023a599913439f0a08adffc3f242ce187fd8bdd
Component: engine
2017-12-06 17:53:46 -08:00
c6d5cb9ce0 Merge pull request #35589 from keloyang/close-fd
Close pipe in chrootarchive.invokeUnpack when cmd.Start()/json.NewEncoder failed
Upstream-commit: cefb33700cf0931a6e3f9ea2cb0a122148d10e49
Component: engine
2017-12-06 17:48:02 -08:00
d7a82cda3b Merge pull request #736 from tiborvass/platform-version
Add platform and its components to docker version output
Upstream-commit: ace5417954
Component: cli
2017-12-06 17:31:05 -08:00
b8234e6bfc Sort component details in template
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 7138d6e301
Component: cli
2017-12-07 02:04:10 +01:00
aa9a4c4bff Add platform and its components to docker version output
The Server section of version output is now composed of an Engine
component and potentially more, based on what the /version endpoint
returns.

Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: 5f4c5f8bb6
Component: cli
2017-12-07 02:04:10 +01:00
29d0c2b494 vendor moby api to get new version types
Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: fe3941af7d
Component: cli
2017-12-07 02:04:10 +01:00
96784302eb Merge pull request #35705 from tiborvass/platform-version
api: generalize version information to any platform component
Upstream-commit: a1be987ea9e03e5ebdb1b415a7acdd8d6f0aaa08
Component: engine
2017-12-06 16:43:38 -08:00
6046d5cbe8 Merge pull request #35677 from fcrisciani/netdb-debug-tool
Netdb debug tool
Upstream-commit: 58dec54d1ffef1ac989399acf3b8e107aa55c2a2
Component: engine
2017-12-06 16:30:11 -08:00
c3ea8d4b44 Merge pull request #726 from albers/completion-log-opt-line-only
Add bash completion for `--log-opt line-only`
Upstream-commit: 8053cf67e0
Component: cli
2017-12-06 16:04:26 -08:00
499d1359a4 Merge pull request #730 from BretFisher/729-fix-zsh-node-and-stack-names
Fixing zsh column finding in nodes and stacks.
Upstream-commit: 143f9f0336
Component: cli
2017-12-06 16:03:20 -08:00
00a55a319d Fix windows
Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: cb8283a6e95f33a93fab0044ca4306cf468faf8c
Component: engine
2017-12-06 23:23:55 +01:00
947ed56f66 Adjust swagger definitions
Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: 87ebfa11f66d2109054ad3024217a5101b45aa8c
Component: engine
2017-12-06 23:23:55 +01:00
3916dafe17 api: generalize version information to any platform component
This change adds a Platform struct with a Name field and a general
Components field to the Version API type. This will allow API
consumers to show version information for the whole platform and
it will allow API providers to set the versions for the various
components of the platform.

All changes here are backwards compatible.

Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: 9152e63290e4a4e586b811cce39082efc649b912
Component: engine
2017-12-06 23:23:55 +01:00
e8e8613267 Merge pull request #35514 from thaJeztah/disable-overlay-without-d_type
Remove support for overlay/overlay2 without d_type
Upstream-commit: bd8a9c25ee257384ca24cf32e61b6b0ef71f521d
Component: engine
2017-12-06 14:13:58 -08:00
9d2c3018e2 Merge pull request #733 from thaJeztah/sync-runc
Bump runc to b2567b37d7b75eb4cf325b77297b140ea686ce8f
Upstream-commit: ddec67c34e
Component: cli
2017-12-06 16:46:33 -05:00
7661258841 Merge pull request #35721 from dnephin/fix-swagger-spec-errors
Fix codegen problems in swagger spec
Upstream-commit: 7f4cf43637067d27a1035d4ff412710ead82bbab
Component: engine
2017-12-06 13:36:52 -08:00
dced91d6f0 Merge pull request #734 from shin-/schema_35_build_shm_size
Add shm_size property to build configuration in Compose schema
Upstream-commit: 4a4db7f20c
Component: cli
2017-12-06 13:35:14 -08:00
02ebcae82d Merge pull request #35146 from masaeedu/27919-removemultitypes
Change multi-type parameters to single type
Upstream-commit: 7db57f7fcac33583403d1d4ccf52b1c27f7e0ad1
Component: engine
2017-12-06 16:22:17 -05:00
da56fc4967 Vendoring netlink library
Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: 2e75d329773920713e63049ad1a00dfb64abf3c0
Component: engine
2017-12-06 13:19:57 -08:00
8afbe15ccf Vendoring of libnetwork
Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: c1e1fb6fa5204bb7014ca9ebab9fe1804c1eb957
Component: engine
2017-12-06 13:19:56 -08:00
4d38282082 Add option to enable networkDB debug
Add a new configuration option to allow the enabling
of the networkDB debug. The option is only parsed using the
reload event. This will protect the daemon on start or restart
if the option is left behind in the config file

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: a97e45794ea8318a08daf763a5b63b04184a886b
Component: engine
2017-12-06 13:19:47 -08:00
f0f2c2b953 Add missing additionalProperties marker on mount definitions
Signed-off-by: Joffrey F <joffrey@docker.com>
Upstream-commit: 88bbaca294
Component: cli
2017-12-06 12:37:38 -08:00
31d8edcd80 Add shm_size property to build configuration in Compose schema
Signed-off-by: Joffrey F <joffrey@docker.com>
Upstream-commit: e49f14cf36
Component: cli
2017-12-06 12:34:12 -08:00
a505f09c7f Validate/sanitize swarmkit spec name.
Signed-off-by: Anshul Pundir <anshul.pundir@docker.com>
Upstream-commit: 739c4cc6b2bab5c3e27656e0a95d858901ecf6b4
Component: engine
2017-12-06 11:55:04 -08:00
c9781de504 Bump runc to b2567b37d7b75eb4cf325b77297b140ea686ce8f
To match what's used in Moby

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 669b8507be
Component: cli
2017-12-06 11:09:36 -08:00
0aafcdcf36 Merge pull request #732 from ndeloof/8917
closes #8917 introduce `—workdir` option for docker exec
Upstream-commit: 86653f4d57
Component: cli
2017-12-06 10:51:33 -08:00
8f42e63aa7 Merge pull request #711 from dnephin/compose-add-name-to-network
Support network.name in the compose schema
Upstream-commit: 30755cf340
Component: cli
2017-12-06 10:44:03 -08:00
3ef7b79d93 Fix codegen problems in swagger spec
Code generation does't support multiple types

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 3648d883556e59392e3e5a05ef5de1b56b68c6fc
Component: engine
2017-12-06 13:38:45 -05:00
7b947af7df update docker/docker for ExecConfig WorkingDir support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 798ec76223
Component: cli
2017-12-06 19:04:42 +01:00
8f8bda1238 Merge pull request #35708 from schomatis/fix-set-up-dev-env-link
Fix link in Contributing doc
Upstream-commit: d9dbca2e19bde080f9485dc8973e9e6d571e2ee3
Component: engine
2017-12-06 10:04:01 -08:00
378c0c6887 Merge component 'engine' from git@github.com:moby/moby master 2017-12-06 17:04:14 +00:00
4a137d3ed6 Annotate worker option for 1.35 API
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 8dc88ea7b5
Component: cli
2017-12-06 17:24:01 +01:00
d02e9392a1 Because the option takes an argument, a special treatment is required in the preceding case
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: da6b8cb5de
Component: cli
2017-12-06 17:24:01 +01:00
5deca4bbe1 introduce —workdir option for docker exec
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 591a1273fd
Component: cli
2017-12-06 17:24:01 +01:00
c898dfbd95 Support network.name in the compose schema.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: d0b8aa7701
Component: cli
2017-12-06 10:05:24 -05:00
928454da48 Merge pull request #35714 from jhhwang4195/master
fixed typo (reliablity -> reliability)
Upstream-commit: 040033b89a201c8bb28fb847db994481d4a7f401
Component: engine
2017-12-06 06:00:54 -06:00
41a5926818 Merge pull request #35661 from ndeloof/8917
introduce `workingdir` option for docker exec
Upstream-commit: 5e5fadb3c0201553929d4a6ea8dc8f9d8a1e56fe
Component: engine
2017-12-06 12:40:25 +01:00
1ffad27f0c Merge pull request #35376 from KingEmet/master
Permit a broader range of errors from mirror endpoints when determining whether to fall back
Upstream-commit: 4055bfb3d3031de7077406ddf0f7e529c47852a9
Component: engine
2017-12-06 01:23:00 -08:00
2990f42efe test case to check « exec » works as expected
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 39d5ace6e1c8f3f7a008fcdf328592bfa799a243
Component: engine
2017-12-06 07:42:57 +01:00
8d97955cea Merge pull request #35603 from ericsoderstrom/master
Update docs to reflect working directory name change.
Upstream-commit: a235469f456d6eb869b98c6ede19f2a0763d5580
Component: engine
2017-12-06 10:15:16 +09:00
0ec86524ed fixed typo (reliablity -> reliability)
Signed-off-by: Jihyun Hwang <jhhwang@telcoware.com>
Upstream-commit: 518c50c9b21225ee991d5147cccb687ea8640afc
Component: engine
2017-12-06 09:51:53 +09:00
70c95e6ecb Change TestSwarmServiceTTY to only verify running containers since with swarmkit#b187b24 service deletions/scale-downs don't directly remove the container.
Signed-off-by: Anshul Pundir <anshul.pundir@docker.com>
Upstream-commit: c5c779adc8c207cfb77a9115450f3e4f1783b26e
Component: engine
2017-12-05 14:51:14 -08:00
e96b772de5 Swarmkit vendoring.
Signed-off-by: Anshul Pundir <anshul.pundir@docker.com>
Upstream-commit: 9fdbb32fcee24410c64c7897c0d9667202aa7e4f
Component: engine
2017-12-05 14:27:49 -08:00
52db2af288 Merge component 'engine' from git@github.com:moby/moby master 2017-12-05 22:20:02 +00:00
8024cf3175 Merge pull request #35695 from boucher/upgrade-criu
Update CRIU version in the shell Dockerfile
Upstream-commit: c7dd58ffbf268680653b2905f6cd08a1eaf4d9c8
Component: engine
2017-12-05 15:49:02 -06:00
dfe161a946 Merge pull request #35707 from crosbymichael/ctd-1.0
Update to containerd v1.0.0
Upstream-commit: 7a14e267d6496b4843aca6170876e7cf53d71f58
Component: engine
2017-12-05 14:02:23 -06:00
cf5224adb2 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2017-12-05 19:13:46 +00:00
8ca0b6eb11 Merge component 'engine' from git@github.com:moby/moby master 2017-12-05 19:13:41 +00:00
9ece0a8dbe Merge pull request #35700 from cpuguy83/plugin_store_rm_test
Add test to check for plugin mounts on remove
Upstream-commit: 27506b353002a2263e753f267e130f133b12c0fc
Component: engine
2017-12-05 10:54:04 -08:00
a394769cf9 Merge component 'cli' from git@github.com:docker/cli master 2017-12-05 18:48:42 +00:00
a369ceccde Merge pull request #724 from dungeonmaster18/723-auto-complete-command
Added auto complete command for fluentd-sub-second-precision.
Upstream-commit: ea854237aa
Component: cli
2017-12-05 10:29:39 -08:00
4d1f5d1e42 Merge pull request #35529 from dungeonmaster18/subsecond-precision-config
Added SubSecondPrecision to config option.
Upstream-commit: 3461289bf0e9147afc88cd829acc0bb8b64e1053
Component: engine
2017-12-05 10:14:14 -08:00
abf2603ea4 Fix link in Contributing doc
Signed-off-by: Lucas Molas <lmolas@fundacionsadosky.org.ar>
Upstream-commit: 1f0572fd1a28d2b5b4566156fa449bb709362b38
Component: engine
2017-12-05 12:31:02 -03:00
d27e345310 Fix event filters
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: a27abc619cc18ead61fa89f652871fac1b318658
Component: engine
2017-12-05 09:55:33 -05:00
e1f6e66d66 Update containerd to v1.0.0
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 18a53d03740220aa72e454929ad1d1d6b695888e
Component: engine
2017-12-05 09:44:42 -05:00
12e67ce519 Added SubSecondPrecision flag in fluentd logger
Signed-off-by: dungeonmaster18 <umesh4257@gmail.com>
Upstream-commit: a1ebda09bab5bf22d96a15e71618c4a0ac08bb55
Component: engine
2017-12-05 17:21:57 +05:30
a5a325a05f Fixing zsh column finding in nodes and stacks.
Signed-off-by: Bret Fisher <bret@bretfisher.com>
Upstream-commit: 8b6d6fa974
Component: cli
2017-12-05 01:03:25 -05:00
dfd519caff Add test to check for plugin mounts on remove
Ensures that when a plugin is removed that it doesn't interfere with
other plugins mounts and also ensures its own mounts are cleaned up.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 5017b5bef55c31db4c04c8058ef7db8597b11341
Component: engine
2017-12-04 22:01:14 -05:00
0c8a47d019 Allow existing setups to continue using d_type
Even though it's highly discouraged, there are existing
installs that are running overlay/overlay2 on filesystems
without d_type support.

This patch allows the daemon to start in such cases, instead of
refusing to start without an option to override.

For fresh installs, backing filesystems without d_type support
will still cause the overlay/overlay2 drivers to be marked as
"unsupported", and skipped during the automatic selection.

This feature is only to keep backward compatibility, but
will be removed at some point.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 0a4e793a3da9ba6d20bccfb83f7c48e20a76d895
Component: engine
2017-12-04 18:41:25 -08:00
327b80ad82 Merge pull request #35537 from sargun/vfs-use-copy_file_range
Have VFS graphdriver use accelerated in-kernel copy
Upstream-commit: 4047cede65862aa0ea5616297d7c0f3b12526ad4
Component: engine
2017-12-04 19:34:56 -06:00
e4dde67875 Remove support for overlay/overlay2 without d_type
Support for running overlay/overlay2 on a backing filesystem
without d_type support (most likely: xfs, as ext4 supports
this by default), was deprecated for some time.

Running without d_type support is problematic, and can
lead to difficult to debug issues ("invalid argument" errors,
or unable to remove files from the container's filesystem).

This patch turns the warning that was previously printed
into an "unsupported" error, so that the overlay/overlay2
drivers are not automatically selected when detecting supported
storage drivers.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 0abb8dec3f730f3ad2cc9a161c97968a6bfd0631
Component: engine
2017-12-04 17:10:20 -08:00
403fcf5047 Perform fsmagic detection on driver's home-dir if it exists
The fsmagic check was always performed on "data-root" (`/var/lib/docker`),
not on the storage-driver's home directory (e.g. `/var/lib/docker/<somedriver>`).

This caused detection to be done on the wrong filesystem in situations
where `/var/lib/docker/<somedriver>` was a mount, and a different
filesystem than `/var/lib/docker` itself.

This patch checks if the storage-driver's home directory exists, and only
falls back to `/var/lib/docker` if it doesn't exist.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: f9c8fa305e1501d8056f8744cb193a720aab0e13
Component: engine
2017-12-04 17:10:07 -08:00
8a469be8e0 fix golint errors
Signed-off-by: Jake Sanders <jsand@google.com>
Upstream-commit: e04375fb8c2f08da158cce21c1591d39d2e68242
Component: engine
2017-12-04 16:44:03 -08:00
cf1d97228e Merge pull request #65 from seemethere/fix_debian_jessie_aarch64
Adds libudev-dev to jessie aarch64 build
Upstream-commit: 6e901d8febcb7c308035952baa760779ab097806
Component: packaging
2017-12-04 16:33:41 -08:00
6ada520445 Update CRIU github repository
Signed-off-by: Ross Boucher <rboucher@gmail.com>
Upstream-commit: f01d2029bbee7327b324ee501a97100ad5506fbf
Component: engine
2017-12-04 18:51:08 -05:00
57c8d64422 Adds libudev-dev to jessie aarch64 build
Failed out otherwise:

```
---> Making bundle: dynbinary (in bundles/dynbinary)
Building: bundles/dynbinary-daemon/dockerd-17.09.0-dev
Package libudev was not found in the pkg-config search path.
```

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 4d8e8855d1008f4705ea6db17e5cd5bc90bd2d81
Component: packaging
2017-12-04 23:36:16 +00:00
2ee063b98e CRIU needs a newer version to work with the updates pulled in by containerd 1.0
Signed-off-by: Ross Boucher <rboucher@gmail.com>
Upstream-commit: 7ffae3d51a452a63c49f8544953a8b0f9781a5e0
Component: engine
2017-12-04 17:45:04 -05:00
7287b1b196 Merge pull request #64 from seemethere/jenkinsfile_label
Change label to one that actually exists
Upstream-commit: 1991b032cb64827c595ad652e6b94b2e49402527
Component: packaging
2017-12-04 13:49:36 -08:00
f28070bdef Merge pull request #35693 from crosbymichael/ctd-rc0
Update containerd to rc0 +
Upstream-commit: 20a42b1f5616b07df524965383528711d24cf6ea
Component: engine
2017-12-04 16:49:29 -05:00
a9ea77004e Change label to one that actually exists
Seems `docker-edge` was removed as label on jenkins.dockerproject.org.

This removes that label and just puts the x86_64 label

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 6765382587e31a93b1e65d2d169b00a42d183ee2
Component: packaging
2017-12-04 21:48:42 +00:00
8d18b0cfab Merge pull request #704 from albers/completion--platform
Add bash completion for `--platform`
Upstream-commit: 83cdc0f1bd
Component: cli
2017-12-04 13:19:37 -08:00
d76f409f13 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2017-12-04 21:07:48 +00:00
f70de4cf86 Merge component 'engine' from git@github.com:moby/moby master 2017-12-04 21:07:45 +00:00
8f588eed28 Add aarch64 support (#35)
* add aarch64 support

* use go 1.9 for arm64 support

* fixtypo

* add backports on jessie

* fix path

* delet yakkety

* rm golang-go

* use arm64v8/ images

* fix error made in merge

* remove double architecture

* use arm64v8/

* use go 1.8.5

* Update aarch64 builds to 1.9.2

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 03eac425534002445e666ce0352f1c666151dc89
Component: packaging
2017-12-04 11:53:11 -08:00
8b1197a568 Fix nonewmountns for containerd options
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 97b0a9d5f195c7daf16cf9dcfb6c4d62044163fe
Component: engine
2017-12-04 14:17:30 -05:00
08c25433ac Bump containerd to cc969fb42f427a68a8cc6870ef47f17
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: ad2b34f2056ca7d6edab17967a797fb19bf4ed5a
Component: engine
2017-12-04 14:14:42 -05:00
cbec60ecae Merge pull request #35687 from tiborvass/add-derek-bot
project: try alexellis/derek bot to manage PRs and issues
Upstream-commit: d94164867c2df977ceb8d9df3d90364d0a682d05
Component: engine
2017-12-04 09:54:02 -08:00
d47afe4a42 project: try alexellis/derek bot to manage PRs and issues
Signed-off-by: Tibor Vass <tibor@docker.com>
Upstream-commit: 123cb9590739a517caa6821a92d9becb2f723547
Component: engine
2017-12-04 16:11:41 +01:00
14e1e40a4e Add bash completion for --log-opt line-only
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 0798d71f38
Component: cli
2017-12-04 10:05:37 +01:00
c4fbbf057e Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2017-12-04 06:57:03 +00:00
47fdbea6d3 Merge component 'engine' from git@github.com:moby/moby master 2017-12-04 06:57:00 +00:00
bf78150b9b Merge pull request #35600 from nictuku/go_option
Set a go_package on api/types/swarm/runtime to make it Bazel compatible
Upstream-commit: 7ef9266ba090a3230355c39352dddf41aeb5b726
Component: engine
2017-12-01 17:30:12 -08:00
31daed866f Merge pull request #62 from andrewhsu/al
no need to detect arch for alpine image
Upstream-commit: 33ee027e04a43651f953bbc080eb020b84fd53cc
Component: packaging
2017-12-01 15:42:51 -08:00
b2d74e0a1a Merge pull request #63 from andrewhsu/j
set VERSION when building packages
Upstream-commit: d467fd1d6abc13be714896f89218a8e6ca047162
Component: packaging
2017-12-01 15:42:33 -08:00
395b31b896 no need to detect alpine image
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
Upstream-commit: 1b5ac32b06cb05ee61ea1b72e2147e983194ea73
Component: packaging
2017-12-01 15:39:00 -08:00
7534a636c1 Merge pull request #60 from andrewhsu/192
use golang 1.9.2
Upstream-commit: ca48d4109ee2326ed16bbcedfdd8691747b252ab
Component: packaging
2017-12-01 15:35:18 -08:00
469adac6a0 set VERSION when building packages
Setting to something that will not be confused with a version number
that will ever be released. Also, this is required for the deb packages
to build properly

Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
Upstream-commit: 0de78bd1251958a9d8916c3944b8f51d0ffb49b7
Component: packaging
2017-12-01 15:19:41 -08:00
9b80ff5665 use pre-compiled golang arm64 toolset
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
Upstream-commit: 30c250b285e758b295e010eee64b726cdac0e7be
Component: packaging
2017-12-01 14:56:19 -08:00
5016fee3dc Merge pull request #35578 from thaJeztah/fix-portbindings-swagger
Fix PortBindings definition in Swagger
Upstream-commit: ac68411f85a1c4540c0d4f5b7db86b0b0422f025
Component: engine
2017-12-01 17:46:38 -05:00
9a7838eb22 Merge pull request #35422 from pradipd/lbfix
Move load balancer sandbox creation/deletion into libnetwork
Upstream-commit: 4bb2c2402df88f0e3e8c47499fc2de5182719e00
Component: engine
2017-12-01 14:08:48 -08:00
29875cbb85 use golang 1.9.2
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
Upstream-commit: 0c04ba6701d462b173ed63bdcd9a55c0e95d8ce1
Component: packaging
2017-12-01 13:59:10 -08:00
f1232b72bc Merge pull request #61 from seemethere/fix_jenkinsfile
Make Jenkinsfile actually function
Upstream-commit: b53c9642495f3c09e2c95791ab6108fe8733fe2b
Component: packaging
2017-12-01 13:58:39 -08:00
3cd9275696 Make directory references absolute
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: bca63242a9c166a944619019da6e0b50f03b4233
Component: packaging
2017-12-01 21:52:00 +00:00
b63d8b8465 Remove fancy github context notifiers
They don't function correctly and they're not worth it

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 3f5a6f288ad7e134abb4ac99e56cbbca17bfae88
Component: packaging
2017-12-01 21:47:49 +00:00
e57d9082bb Merge pull request #57 from seemethere/add_tests
Adds initial Jenkinsfile
Upstream-commit: 20ac959f7f135b20c45b56d8dd50353a0e3a5e52
Component: packaging
2017-12-01 13:17:46 -08:00
5b5e980ec3 Adds initial Jenkinsfile.
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 31a08611f6b87f71d673ab254471826eed225858
Component: packaging
2017-12-01 21:16:46 +00:00
20a2865e53 Fix setting mtimes on directories
Previously, the code would set the mtime on the directories before
creating files in the directory itself. This was problematic
because it resulted in the mtimes on the directories being
incorrectly set. This change makes it so that the mtime is
set only _after_ all of the files have been created.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: 77a2bc3e5bbc9be3fe166ed8321b7cd04e7bd097
Component: engine
2017-12-01 09:12:43 -08:00
f62beecbb7 Added auto complete command for fluentd-sub-second-precision
Signed-off-by: dungeonmaster18 <umesh4257@gmail.com>
Upstream-commit: d5271568a2
Component: cli
2017-12-01 18:39:41 +05:30
148bfd3114 introduce workingdir option for docker exec
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 19f2749d3906707717aeec9da27c499bcdc07da8
Component: engine
2017-12-01 09:06:07 +01:00
6a8cf843af Merge component 'engine' from git@github.com:moby/moby master 2017-12-01 04:12:05 +00:00
559fcde9d4 Disambiguate mirror -> other endpoint fallbacks from V2 -> V1
Signed-off-by: Jake Sanders <jsand@google.com>
Upstream-commit: 305801f58f22c9a26bc05eaa800e399afb212fe3
Component: engine
2017-11-30 20:01:03 -08:00
5f26edda74 Merge component 'cli' from git@github.com:docker/cli master 2017-12-01 03:52:40 +00:00
b611814dc6 Merge pull request #35628 from ikarpovich/35626-le-line-only-legacy
Logentries line-only logopt fix to maintain backwards compatibility
Upstream-commit: 3a9ab941adcc7a39c3ea8c52e3c215cdddb2fe67
Component: engine
2017-11-30 15:48:56 -08:00
f67476ad43 Merge pull request #35645 from crosbymichael/ctd-10
Update containerd to pre-1.0 rc commit
Upstream-commit: 3eb7314519714e0392a4863d6cd4beb3a4b206e8
Component: engine
2017-11-30 15:22:01 -08:00
b8226cb988 Adding test for creating service multiple times.
Signed-off-by: Pradip Dhara <pradipd@microsoft.com>
Upstream-commit: 791d88b8538b4949153d346ec738139aa6d15280
Component: engine
2017-11-30 13:03:44 -08:00
19fca6eb66 docker changes corresponding to libnetwork changes.
Signed-off-by: Pradip Dhara <pradipd@microsoft.com>
Upstream-commit: 41071d6648fe5b4649354e806543b9520af45383
Component: engine
2017-11-30 13:03:30 -08:00
553ad48935 vndr libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7
Signed-off-by: Pradip Dhara <pradipd@microsoft.com>
Upstream-commit: 7de313ac4ec2084aca6c91efc3124b9dbffc5f1a
Component: engine
2017-11-30 13:02:56 -08:00
a8cf119f39 Merge pull request #35516 from mlaventure/reduce-race-on-exit
Add missing lock in ProcessEvent
Upstream-commit: 9d00efb533d3561220d169a86ca9ff965f9a6b2c
Component: engine
2017-11-30 11:30:51 -08:00
4d4ec05575 Merge pull request #35533 from AliyunContainerService/supress-warning-healthcheck-none
Suppress warning when NONE was set for healthcheck
Upstream-commit: 29d6aef3930bf2ba815e27f4507f035a7fb5ba6c
Component: engine
2017-11-30 11:06:05 -08:00
a620b9f6fd Merge pull request #35496 from cpuguy83/add_timeouts_to_splunk_post
Set timeout on splunk batch send
Upstream-commit: 88e36dcc76c08d13fd83f91fa7dbe4a6ff4c83b8
Component: engine
2017-11-30 09:47:48 -08:00
4a8c6447a6 Merge pull request #719 from vdemeester/test-secret-config-indempotence
Add unit tests on config/secret indempotence in stack deploy
Upstream-commit: 6b63d7b96a
Component: cli
2017-11-30 08:39:56 -08:00
87f648cd90 Merge pull request #35618 from kolyshkin/mkdir-all
Fix MkdirAll* and its usage
Upstream-commit: 72e45fd54e13256c813fdb39b18e26a0de980733
Component: engine
2017-11-30 11:19:29 -05:00
9d718a77b7 Merge pull request #35614 from mlaventure/remove-exec-bypid
Remove ByPid from ExecCommands
Upstream-commit: edbf7d8ed41a88d34dd9ad249ac94f095e0d3385
Component: engine
2017-11-30 11:17:42 -05:00
d99ad61b69 Update containerd to 6bff39c643886dfa3d546e83a90a5
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: c2cb302d1701e0de35930671f61e5d267fcb3e01
Component: engine
2017-11-30 11:16:25 -05:00
ad76847e4b Update daemon code for containerd API changes
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: aa3ce07c41e0da9331f0659f28fed7f35846556c
Component: engine
2017-11-30 09:55:03 -05:00
c4cb5e12ad Logentries line-only logopt fix to maintain backwards compatibility
Changed logic to ignore empty value

Fixes #35626

Signed-off-by: Igor Karpovich <igor@karpovich.me>
Upstream-commit: 27a5b878c149fd70ca1e0beebda58edcc19abc73
Component: engine
2017-11-30 13:03:16 +00:00
9818aadf77 Add unit tests on config/secret indempotence in stack deploy
Related PR : https://github.com/docker/cli/pull/509

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 5ed399e588
Component: cli
2017-11-30 09:45:32 +01:00
617fb8ceb7 Merge pull request #702 from albers/completion-log--until
Add bash completion for `logs --until`
Upstream-commit: b45a49c83f
Component: cli
2017-11-30 09:40:08 +01:00
3c7ba9bf1b Add bash completion for --platform
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 15f78417b9
Component: cli
2017-11-30 09:29:15 +01:00
a88b24bfeb Merge pull request #35483 from thaJeztah/disallow-nfs-backing-for-overlay
Disallow overlay/overlay2 on top of NFS
Upstream-commit: bdd9668b489c65eb1ef7272d38ad877ffda2041c
Component: engine
2017-11-29 19:24:58 -08:00
1072fa08f7 Merge pull request #35634 from fcrisciani/fix-net-not-found
Restore error type in FindNetwork
Upstream-commit: e0b3ddd4377b9539e6112e57777f4c7b1d0bfc08
Component: engine
2017-11-29 16:26:26 -08:00
d9f34cfcb3 Update containerd to 59bd1967112885c4d49e510e55701
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 5bd902b5cfbb360915b02fc2a787ae9e1c183405
Component: engine
2017-11-29 19:15:14 -05:00
3e4063cddb Merge pull request #35501 from cpuguy83/lock_while_stopping_healthcheck
Fix some issues with locking on the container
Upstream-commit: 3d80a692d146e10282bacc0dd2698ffd32dcdaae
Component: engine
2017-11-30 09:01:31 +09:00
006ed302fe Merge pull request #35527 from thaJeztah/feature-detect-overlay2
Detect overlay2 support on pre-4.0 kernels
Upstream-commit: 11e07e7da6023b872788b1e05f83e147f0984fb2
Component: engine
2017-11-29 13:51:26 -08:00
02055337d8 Merge pull request #694 from riyazdf/trust-inspect
docker trust inspect
Upstream-commit: d921d5cc39
Component: cli
2017-11-29 11:33:53 -08:00
ea17d4a2f5 Restore error type in FindNetwork
The error type libnetwork.ErrNoSuchNetwork is used in the controller
to retry the network creation as a managed network though the manager.
The change of the type was breaking the logic causing the network to
not being created anymore so that no new container on that network
was able to be launched
Added unit test

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: 51cea0a53c2fd36832277402e9faac81bfb4abd4
Component: engine
2017-11-29 11:22:57 -08:00
f8c7f6621d Use default inspect formatting, remove omitempty, update docs
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Upstream-commit: a9428285f0
Component: cli
2017-11-29 10:52:35 -08:00
b1e7ee7a82 support multiple arguments to trust inspect
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Upstream-commit: 1eb87cc096
Component: cli
2017-11-29 10:52:34 -08:00
7e9b53fd42 add docker trust inspect command for JSON viewing
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Upstream-commit: cd38d39d0d
Component: cli
2017-11-29 10:52:34 -08:00
9b7953e812 Merge pull request #718 from dnephin/fix-e2e-docker-build
Fix e2e build test
Upstream-commit: 1b4f2d3b73
Component: cli
2017-11-29 10:30:31 -08:00
a79583a886 Merge pull request #677 from albers/completion-log-opts
Add new log driver options to bash completion
Upstream-commit: 4f009541cb
Component: cli
2017-11-29 10:01:19 -08:00
fe41a825e2 Merge pull request #678 from albers/completion-build--stream
Add bash completion for experimental `build --stream`
Upstream-commit: c428561b63
Component: cli
2017-11-29 10:00:23 -08:00
264f9d5a4f Merge pull request #701 from albers/completion-trust-sign--local
Add bash completion for `trust sign --local`
Upstream-commit: e5d49c0199
Component: cli
2017-11-29 09:44:53 -08:00
40b8aa0152 Merge pull request #467 from estesp/chown-flag-docs
Add docs for Dockerfile ADD/COPY --chown flag
Upstream-commit: 12765c318f
Component: cli
2017-11-29 09:28:30 -08:00
29f2890225 Fix e2e build test
The build output changed in 17.11

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 16cd84024c
Component: cli
2017-11-29 11:02:40 -05:00
cbde088d23 Merge pull request #716 from vdemeester/bump-go
Bump Go to 1.9.2
Upstream-commit: 8abb266043
Component: cli
2017-11-29 09:42:58 -05:00
1433c3b1eb Bump Go to 1.9.2
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 6859a7387b
Component: cli
2017-11-29 09:16:03 +01:00
5a1411dbf0 Merge pull request #35606 from cbirajdar/master
added more awesome and notable women to names-generator.go
Upstream-commit: c8441b186e8bc5d7994a922782cc3b6e2c462893
Component: engine
2017-11-28 21:37:17 -08:00
1901e3d893 Merge pull request #35619 from Microsoft/jjh/testrunservicingcontainer
Disable TestRunServicingContainer on RS4+ builds
Upstream-commit: 99e4eb103d67422ff10809079e2b810cd3dfce99
Component: engine
2017-11-28 21:34:15 -08:00
856222b133 Merge pull request #35620 from fcrisciani/libnetwork-vendoring
Libnetwork vendoring
Upstream-commit: 235c10573612d856300ffeb5c05ac0ca343609a6
Component: engine
2017-11-28 21:11:14 -08:00
bac9dc2670 Merge pull request #35631 from Microsoft/jjh/heightwidth
Windows: Fix width/height swap
Upstream-commit: 29708da9077fc37554bac10b17fe0446bed07af9
Component: engine
2017-11-28 21:02:46 -08:00
87cfb875f7 Merge pull request #34948 from euank/public-mounts
Fix EBUSY errors under overlayfs and v4.13+ kernels
Upstream-commit: 09eb7bcc3624f5bd70135d6d24021b40c1095b46
Component: engine
2017-11-29 12:48:39 +09:00
a0c42a8dee Merge pull request #35622 from asottile/update_integration_cli_docs
Change references from test-integration-cli to test-integration
Upstream-commit: debc1fbee8d86948deed5939bb73f2a175151fb1
Component: engine
2017-11-29 12:47:52 +09:00
7f2221039e Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2017-11-28 18:03:52 -08:00
6be246bf8b Merge component 'engine' from git@github.com:moby/moby master 2017-11-28 18:03:40 -08:00
67203bb69e Merge pull request #429 from RenaudWasTaken/generic-resource
Integrated Generic resource in service create
Upstream-commit: 97b148b440
Component: cli
2017-11-28 18:01:42 -08:00
99c53b25ef Merge component 'cli' from git@github.com:docker/cli master 2017-11-28 17:01:27 -08:00
6d8eeeb431 Merge pull request #35586 from ndeloof/patch-1
`memory` is an int64 (long)
Upstream-commit: 9243c28ba541281eaba43e51658f8dd032679ebc
Component: engine
2017-11-28 16:32:04 -08:00
0569c43fe3 Merge pull request #35632 from anusha-ragunathan/fix-panic
Fix potential panic during plugin set.
Upstream-commit: f943df7d4824424bd648d7a165e89be8a65a952e
Component: engine
2017-11-28 15:50:12 -08:00
877f5d0f1f Fix bug, where copy_file_range was still calling legacy copy
There was a small issue here, where it copied the data using
traditional mechanisms, even when copy_file_range was successful.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: 0eac562281782257e6f69d58bcbc13fa889f1759
Component: engine
2017-11-28 14:59:56 -08:00
608a03b9d5 Have VFS graphdriver use accelerated in-kernel copy
This change makes the VFS graphdriver use the kernel-accelerated
(copy_file_range) mechanism of copying files, which is able to
leverage reflinks.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: d2b71b26604370620630d8d3f35aba75ae474f3f
Component: engine
2017-11-28 14:59:56 -08:00
85f5db8154 Fix copying hardlinks in graphdriver/copy
Previously, graphdriver/copy would improperly copy hardlinks as just regular
files. This patch changes that behaviour, and instead the code now keeps
track of inode numbers, and if it sees the same inode number again
during the copy loop, it hardlinks it, instead of copying it.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: b467f8b2ef21dc2239dcd136a29283ea6c3a0aee
Component: engine
2017-11-28 14:59:56 -08:00
efd7b774aa Detect overlay2 support on pre-4.0 kernels
The overlay2 storage-driver requires multiple lower dir
support for overlayFs. Support for this feature was added
in kernel 4.x, but some distros (RHEL 7.4, CentOS 7.4) ship with
an older kernel with this feature backported.

This patch adds feature-detection for multiple lower dirs,
and will perform this feature-detection on pre-4.x kernels
with overlayFS support.

With this patch applied, daemons running on a kernel
with multiple lower dir support will now select "overlay2"
as storage-driver, instead of falling back to "overlay".

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 955c1f881ac94af19c99f0f7d5635e6a574789f2
Component: engine
2017-11-28 13:55:33 -08:00
b7dabb480c Fix potential panic during plugin set.
Plugin config can have Mounts without a 'Source' field. In such cases,
performing a 'plugin set' on the mount source will panic the daemon. Its
the same case for device paths as well. This detects the case and
returns error.

Signed-off-by: Anusha Ragunathan <anusha.ragunathan@docker.com>
Upstream-commit: 6572e27df7f3483cfed7a8294c1f6d9cf157809a
Component: engine
2017-11-28 13:06:24 -08:00
2598a6cd6a Added support of Generic resources in compose file
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 1ff73f867d
Component: cli
2017-11-28 21:52:09 +01:00
6025db4712 Windows: Fix width/height swap
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: f11f351ae77e4090f0d80e9cccfd77287b1f6b17
Component: engine
2017-11-28 12:19:46 -08:00
00e6357d85 Disable TestRunServicingContainer on RS4+ builds
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 1293303bda56f9f6f5a0d99921a5368e0e527509
Component: engine
2017-11-28 10:29:43 -08:00
405736f2fc Merge pull request #714 from doncicuto/patch-1
Update Flocker plugin link
Upstream-commit: e004dc01d4
Component: cli
2017-11-28 10:20:10 -08:00
77a39cce80 Added support for generic resource update
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 20a6ff32ee
Component: cli
2017-11-28 18:03:10 +01:00
025793bb76 Added docs for service create
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 4a6da88f7a
Component: cli
2017-11-28 18:03:10 +01:00
4ba8859964 Added docs for dockerd
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: fe07ca70d6
Component: cli
2017-11-28 18:03:10 +01:00
2eb0bb6fa6 Added Generic Resource tests
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 51c7cd91cf
Component: cli
2017-11-28 18:03:10 +01:00
6c65651aa2 Updated GenericResource CLI
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 7ddd5f3434
Component: cli
2017-11-28 18:03:10 +01:00
f62d716bb0 Revendored swarmkit
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 7843aec98c
Component: cli
2017-11-28 18:03:10 +01:00
a94e4ed04a Merge pull request #35572 from arm64b/big-image-imp-test-aarch64
image: skip the import test on AArch64
Upstream-commit: c307e0ce49d63d1b1f479560955dca3956f005ec
Component: engine
2017-11-28 13:51:15 +01:00
0637acf0b1 Update Flocker plugin link
ClusterHQ shutted down at the end of 2016. It seems that ScatterHQ is a group of ClusterHQ former employees that have forked Flocker. It seems that no code has been commited in the last months but if somebody comes to this Docker page it should be referenced to ScatterHQ.

Signed-off-by: Miguel Angel Alvarez Cabrerizo <doncicuto@gmail.com>
Upstream-commit: 3e6e54a90f
Component: cli
2017-11-28 13:51:08 +01:00
94ae8f10c7 Change references from test-integration-cli to test-integration
Signed-off-by: Anthony Sottile <asottile@umich.edu>
Upstream-commit: b6eed3dca2e57705cb75895cad0b5337c79686d9
Component: engine
2017-11-27 19:01:14 -08:00
016b82fbf3 image: skip the import test on AArch64
The commit '0a13f827a10d3bf61744d9b3f7165c5885a39c5d' introduces an
import test for CVE-2017-14992, it uses a 8GB image to make sure we
don't revert CVE-2017-14992, but unfortunately this test can't finish
in 5-min on AArch64, as a fact, in most cases we have to crate a very
big image to make the test effective on AArch64, but this will result
in a test panic, so now we skip it order to avoid termination of others
tests followed.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 6395b8b3dcc43be6750e0d90d9bab0a83e4eb20b
Component: engine
2017-11-28 01:48:49 +00:00
2ddb9ceeba Merge pull request #35528 from thaJeztah/ignore-empty-graphdirs
Skip empty directories on prior graphdriver detection
Upstream-commit: 9ae697167c8b90b40d5248e99a8f0a0fc304637e
Component: engine
2017-11-27 17:37:39 -08:00
bc89af9929 Simplify/fix MkdirAll usage
This subtle bug keeps lurking in because error checking for `Mkdir()`
and `MkdirAll()` is slightly different wrt to `EEXIST`/`IsExist`:

 - for `Mkdir()`, `IsExist` error should (usually) be ignored
   (unless you want to make sure directory was not there before)
   as it means "the destination directory was already there"

 - for `MkdirAll()`, `IsExist` error should NEVER be ignored.

Mostly, this commit just removes ignoring the IsExist error, as it
should not be ignored.

Also, there are a couple of cases then IsExist is handled as
"directory already exist" which is wrong. As a result, some code
that never worked as intended is now removed.

NOTE that `idtools.MkdirAndChown()` behaves like `os.MkdirAll()`
rather than `os.Mkdir()` -- so its description is amended accordingly,
and its usage is handled as such (i.e. IsExist error is not ignored).

For more details, a quote from my runc commit 6f82d4b (July 2015):

    TL;DR: check for IsExist(err) after a failed MkdirAll() is both
    redundant and wrong -- so two reasons to remove it.

    Quoting MkdirAll documentation:

    > MkdirAll creates a directory named path, along with any necessary
    > parents, and returns nil, or else returns an error. If path
    > is already a directory, MkdirAll does nothing and returns nil.

    This means two things:

    1. If a directory to be created already exists, no error is
    returned.

    2. If the error returned is IsExist (EEXIST), it means there exists
    a non-directory with the same name as MkdirAll need to use for
    directory. Example: we want to MkdirAll("a/b"), but file "a"
    (or "a/b") already exists, so MkdirAll fails.

    The above is a theory, based on quoted documentation and my UNIX
    knowledge.

    3. In practice, though, current MkdirAll implementation [1] returns
    ENOTDIR in most of cases described in #2, with the exception when
    there is a race between MkdirAll and someone else creating the
    last component of MkdirAll argument as a file. In this very case
    MkdirAll() will indeed return EEXIST.

    Because of #1, IsExist check after MkdirAll is not needed.

    Because of #2 and #3, ignoring IsExist error is just plain wrong,
    as directory we require is not created. It's cleaner to report
    the error now.

    Note this error is all over the tree, I guess due to copy-paste,
    or trying to follow the same usage pattern as for Mkdir(),
    or some not quite correct examples on the Internet.

    [1] https://github.com/golang/go/blob/f9ed2f75/src/os/path.go

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 516010e92d56cfcd6d1e343bdc02b6f04bc43039
Component: engine
2017-11-27 17:32:12 -08:00
ccb264e334 Libnetwork vendoring
- removed support for Solaris
- networkdb fixed race on node management

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: 2e5d5c1d325662ac56de4772e4e1fe3a9c7a2d19
Component: engine
2017-11-27 14:57:45 -08:00
dcbc5aef35 Merge pull request #35612 from ikarpovich/35610-le-line-only
Logentries driver line-only=true []byte output fix
Upstream-commit: c75c45b18858cf34669b43e8cec25f70bd5803ea
Component: engine
2017-11-27 14:33:02 -08:00
44cd9b0708 Remove ByPid from ExecCommands
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
Upstream-commit: 6f3e86e906a8955d3dc3ddc2a6be51b17e7a097f
Component: engine
2017-11-27 14:27:40 -08:00
03d850d672 idtools.MkdirAs*: error out if dir exists as file
Standard golang's `os.MkdirAll()` function returns "not a directory" error
in case a directory to be created already exists but is not a directory
(e.g. a file). Our own `idtools.MkdirAs*()` functions do not replicate
the behavior.

This is a bug since all `Mkdir()`-like functions are expected to ensure
the required directory exists and is indeed a directory, and return an
error otherwise.

As the code is using our in-house `system.Stat()` call returning a type
which is incompatible with that of golang's `os.Stat()`, I had to amend
the `system` package with `IsDir()`.

A test case is also provided.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 2aa13f86f0c9cf3ed58a648a7b1506d4b06f3589
Component: engine
2017-11-27 13:25:44 -08:00
5c33ebfbc1 Merge pull request #33892 from thaJeztah/bump-golang-19
Bump Go to 1.9.2
Upstream-commit: c672fbd69cb2b375011867860b3f46220655d3fe
Component: engine
2017-11-27 11:44:06 -08:00
9a7fb33c58 Merge pull request #35579 from dnephin/fix-layer-dne
Fix layer DNE with duplicate layers
Upstream-commit: 9fe48f081dafbff467643ce1119c7963f57d9ee8
Component: engine
2017-11-27 09:40:54 -08:00
c3f989d26b This fixes casting of log message []byte into string with --log-opt line-only=true
Signed-off-by: Igor Karpovich <igor@karpovich.me>
Upstream-commit: 440e50b6c702b5e13fff9424ef656b6bb6a259f0
Component: engine
2017-11-27 14:26:53 +00:00
249ba5d150 added more awesome and notable women to names-generator.go
Signed-off-by: Chetan Birajdar <birajdar.chetan@gmail.com>
Upstream-commit: 7c50d394808da05ebe40966246ae3c03a443fb1a
Component: engine
2017-11-26 21:40:02 -08:00
6b9bdea9e7 Update docs to reflect working directory name change.
Signed-off-by: Eric Soderstrom <ericsoderstrom@gmail.com>
Upstream-commit: f72ece01866ffc1df7c9b33a89ed243c42468bd4
Component: engine
2017-11-26 13:12:16 -08:00
59e5477bf3 Set a go_package on api/types/swarm/runtime to make it Bazel compatible
Signed-off-by: Yves Junqueira <yves.junqueira@gmail.com>
Upstream-commit: 44f61e0f860447e198ca044f1cbdac73c5aa2bbf
Component: engine
2017-11-25 04:26:16 -08:00
52ebdfbe5d Close pipe in chrootarchive.invokeUnpack when cmd.Start()/json.NewEncoder failed.
Signed-off-by: y00316549 <yangshukui@huawei.com>
Upstream-commit: f5f8f008608e579e9164647910ef6f976e91e297
Component: engine
2017-11-24 13:41:08 +08:00
c7f0d04c5e Merge pull request #33731 from runcom/rt-fix-update
container: update real-time resources
Upstream-commit: dfe2c023a34de3e1731e789f4344ef4d85070bc6
Component: engine
2017-11-23 18:30:22 -08:00
b02966efb1 Merge pull request #35563 from soccerGB/driveroptionpersist
Added support for persisting Windows network driver specific options …
Upstream-commit: 1f3f111b4577b29613b0ffef8f001679c2a62d6f
Component: engine
2017-11-23 16:31:46 -08:00
a737bf6704 Fix layer DNE with duplicate layers.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 936ef0c4c97737066ae1e028f04b5188022a91b8
Component: engine
2017-11-23 15:41:59 -05:00
8a8ecdb59d Merge pull request #709 from dnephin/e2e-docker-build
Add e2e test for docker build
Upstream-commit: 6476524c74
Component: cli
2017-11-23 13:54:41 -05:00
c34d673f0c Merge pull request #689 from thaJeztah/remove-daemon-subcommand
Remove deprecated "daemon" subcommand
Upstream-commit: 227dfea9e1
Component: cli
2017-11-23 11:10:50 -05:00
12aa8ed3d8 memory is an int64 (long)
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 5ad85b1d4d69806754d1814f019b03b57e40d6da
Component: engine
2017-11-23 14:24:43 +01:00
dd75028635 Merge pull request #35576 from tophj-ibm/add-main-to-image-tests
[integration] add main_test for image test
Upstream-commit: fe8aac6f5ae413a967adb0adad0b54abdfb825c4
Component: engine
2017-11-22 14:42:56 -08:00
7830091c4b graphdriver/overlay{,2}: remove 'merged' on umount
This removes and recreates the merged dir with each umount/mount
respectively.
This is done to make the impact of leaking mountpoints have less
user-visible impact.

It's fairly easy to accidentally leak mountpoints (even if moby doesn't,
other tools on linux like 'unshare' are quite able to incidentally do
so).

As of recently, overlayfs reacts to these mounts being leaked (see

One trick to force an unmount is to remove the mounted directory and
recreate it. Devicemapper now does this, overlay can follow suit.

Signed-off-by: Euan Kemp <euan.kemp@coreos.com>
Upstream-commit: af0d589623eff9f8cefced8b527dbd7cf221ce61
Component: engine
2017-11-22 14:32:30 -08:00
cb2dc1cb0b graphdriver/overlay: minor doc comment cleanup
Signed-off-by: Euan Kemp <euan.kemp@coreos.com>
Upstream-commit: 1e214c09524c0cf32c3e8005631bbcf3e1afa506
Component: engine
2017-11-22 14:17:08 -08:00
b88ff8a5c2 container: update real-time resources
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
Upstream-commit: dca82b9e5c53e96d1e34bec03e78e17feb8d6fdb
Component: engine
2017-11-22 22:21:40 +01:00
db4f5614fc Merge pull request #668 from ilyasotkov/667-secret-config-names
Add "name" field to secrets and configs to allow interpolation in Compose files
Upstream-commit: 8d41ba082b
Component: cli
2017-11-22 13:33:59 -05:00
3ceb534c1b Fix PortBindings definition in Swagger
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a50cf8aa44f2a5abb5900d39008d075d2e8c2850
Component: engine
2017-11-22 17:55:37 +01:00
9f84ce63a5 [integration] add main_test for image test
Adds a main_test for the image integration test, so we can download
frozen images, and clean up after the image test is ran

Signed-off-by: Christopher Jones <tophj@linux.vnet.ibm.com>
Upstream-commit: be83f42612e3be42fcd60726d48d7346befc9449
Component: engine
2017-11-22 11:13:32 -05:00
34cc3d6434 Remove duplication for secrets / configs, combine 3.5 loader tests, remove extraneous error call, regenerate schema correctly
Signed-off-by: Ilya Sotkov <ilya@sotkov.com>
Upstream-commit: ec47003ecb
Component: cli
2017-11-22 13:41:16 +02:00
3d2eab6bf0 Add tests for secret.name in compose files.
Signed-off-by: Ilya Sotkov <ilya@sotkov.com>
Upstream-commit: 1f10b31017
Component: cli
2017-11-22 13:18:05 +02:00
2dae51fa3d Add secret.name and config.name in compose.
Signed-off-by: Ilya Sotkov <ilya@sotkov.com>
Upstream-commit: 4f7f3d2f61
Component: cli
2017-11-22 13:18:05 +02:00
26b47c13d1 Merge pull request #35467 from kolyshkin/dup-mnt
Fix "duplicate mount point" when --tmpfs /dev/shm is used
Upstream-commit: d032264e1365a1cea621b7105e1ca521cb4218ef
Component: engine
2017-11-22 12:13:06 +01:00
4a5f32be3b Merge pull request #35541 from thaJeztah/remove-deprecated-mkdirallas
Remove uses of deprecated MkdirAllAs(), MkdirAs()
Upstream-commit: 84b1f813a4ada3c19eea84f9e98c56c0768d9da2
Component: engine
2017-11-22 17:49:37 +09:00
e6fc3af770 Added support for persisting Windows network driver specific options over reboot or service restart
Signed-off-by: Cheng-mean Liu <soccerl@microsoft.com>
Upstream-commit: cef1578ac46e02d05c86621505631b3be7ca9d72
Component: engine
2017-11-21 14:11:12 -08:00
86481c358f Merge pull request #35559 from thaJeztah/remove-testutil
Remove unused "testutil" package
Upstream-commit: ce452fb72ffcdb7605ce98bde9302238f47c63c5
Component: engine
2017-11-21 21:00:04 +01:00
605885e518 Bump Go to 1.9.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d6e1cc32d309ee237342975388e729570343a974
Component: engine
2017-11-21 20:57:02 +01:00
7ed4a89d21 Merge pull request #35554 from darrenstahlmsft/RevendorHcsshim
Update hcsshim to v0.6.7 for go1.9 support
Upstream-commit: fb89afb6898fc830b8f660931f54145f85b971c7
Component: engine
2017-11-21 20:55:40 +01:00
6a9797ecaa Add e2e test for docker build
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 7adb4c4b1e
Component: cli
2017-11-21 13:24:37 -05:00
b26b223eb7 Fix some issues with locking on the container
- Fix OOM event updating healthchecks and persisting container state
without locks
- Fix healthchecks being updated without locks on container stop

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 972cb4978795029131697bd3b3746e321eec5c13
Component: engine
2017-11-21 12:41:43 -05:00
c9b8719b0b Merge pull request #59 from seemethere/add_f27
Adds packaging for Fedora 27
Upstream-commit: 3519a3532cf9da379db073452a3f55c7d894961a
Component: packaging
2017-11-21 09:39:51 -06:00
a653d42fdb Skip empty directories on prior graphdriver detection
When starting the daemon, the `/var/lib/docker` directory
is scanned for existing directories, so that the previously
selected graphdriver will automatically be used.

In some situations, empty directories are present (those
directories can be created during feature detection of
graph-drivers), in which case the daemon refuses to start.

This patch improves detection, and skips empty directories,
so that leftover directories don't cause the daemon to
fail.

Before this change:

    $ mkdir /var/lib/docker /var/lib/docker/aufs /var/lib/docker/overlay2
    $ dockerd
    ...
    Error starting daemon: error initializing graphdriver: /var/lib/docker contains several valid graphdrivers: overlay2, aufs; Please cleanup or explicitly choose storage driver (-s <DRIVER>)

With this patch applied:

    $ mkdir /var/lib/docker /var/lib/docker/aufs /var/lib/docker/overlay2
    $ dockerd
    ...
    INFO[2017-11-16T17:26:43.207739140Z] Docker daemon                                 commit=ab90bc296 graphdriver(s)=overlay2 version=dev
    INFO[2017-11-16T17:26:43.208033095Z] Daemon has completed initialization

And on restart (prior graphdriver is still picked up):

    $ dockerd
    ...
    INFO[2017-11-16T17:27:52.260361465Z] [graphdriver] using prior storage driver: overlay2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 1262c57714e694193be6bbcbed83e859dc246c2f
Component: engine
2017-11-21 15:42:04 +01:00
6063e62a1f Remove unused "testutil" package
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 47af9f625d3f9e94729ec5aee4abcce813914d07
Component: engine
2017-11-21 15:09:23 +01:00
d0d7235731 Remove deprecated MkdirAllAs(), MkdirAs()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 38b3af567f676c4c35e80e493aa97b7346ae75e4
Component: engine
2017-11-21 13:53:54 +01:00
9282ca8404 Minor refactor in idtools
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ce66470f5404872db2cbaa7fbd59970700144be2
Component: engine
2017-11-21 13:49:58 +01:00
d4007aa747 Update idtools tests to test non-deprecated functions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 9aba019b72611119578ea32adb03fa49f73da522
Component: engine
2017-11-21 13:47:17 +01:00
4e6f892dc4 Merge pull request #708 from dnephin/update-cobra
Update spf13/cobra, fixes usages in generated man pages
Upstream-commit: 2d0e2d22ca
Component: cli
2017-11-21 10:51:25 +01:00
c051f4a135 Merge pull request #35547 from thaJeztah/fix-make-test
Fix "make test" failing on missing "test-unit"
Upstream-commit: dc7ba2ca3ba7abd1aa4dbbcb3c42dace1b6d3545
Component: engine
2017-11-21 10:49:38 +01:00
6e7cb1931d Fix "duplicate mount point" when --tmpfs /dev/shm is used
This is a fix to the following issue:

$ docker run --tmpfs /dev/shm busybox sh
docker: Error response from daemon: linux mounts: Duplicate mount point '/dev/shm'.

In current code (daemon.createSpec()), tmpfs mount from --tmpfs is added
to list of mounts (`ms`), when the mount from IpcMounts() is added.
While IpcMounts() is checking for existing mounts first, it does that
by using container.HasMountFor() function which only checks container.Mounts
but not container.Tmpfs.

Ultimately, the solution is to get rid of container.Tmpfs (moving its
data to container.Mounts). Current workaround is to add checking
of container.Tmpfs into container.HasMountFor().

A unit test case is included.

Unfortunately we can't call daemon.createSpec() from a unit test,
as the code relies a lot on various daemon structures to be initialized
properly, and it is hard to achieve. Therefore, we minimally mimick
the code flow of daemon.createSpec() -- barely enough to reproduce
the issue.

https://github.com/moby/moby/issues/35455

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 1861abdc4a31efad202a5c3d89a895bb7a62799a
Component: engine
2017-11-20 18:48:27 -08:00
69bca6d97b container.NetworkMounts(): don't lookup mounts twice
The code in question looks up mounts two times: first by using
HasMountFor(), and then directly by looking in container.MountPoints.
There is no need to do it twice.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: eab3ac3e70a510b97f9399efd13e3dc01a07c413
Component: engine
2017-11-20 18:48:27 -08:00
63aefcb844 Update hcsshim to v0.6.7 for go1.9 support
Signed-off-by: Darren Stahl <darst@microsoft.com>
Upstream-commit: 0bee8049c78c635b8a38064483e4c3c788779345
Component: engine
2017-11-20 16:29:01 -08:00
3cf67e0ba5 Merge pull request #35517 from stevvooe/protect-the-health-status
container: protect the health status with mutex
Upstream-commit: 9de84a78d76ed2ffe386fe21466f7401cf5d2e9d
Component: engine
2017-11-20 21:51:47 +01:00
325141c0ef Merge pull request #35495 from simonferquel/isolation-validation
Added validation of isolation settings on daemon.verifyContainerSettings
Upstream-commit: a9aeb18a0996eed4b3402ba0431269d46f5ad497
Component: engine
2017-11-20 12:09:40 -08:00
276378cfb9 Fix "make test" failing on missing "test-unit"
Commit dbf580be57a4bb854d7ce20d313e3a22ea337be5 removed
this helper script because it's no longer used in CI.

However, the "make test" target in the Makefile still
called this helper, resulting it to fail.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a17071e88f15625a6be19f80c697ab1c3471381b
Component: engine
2017-11-20 19:12:25 +01:00
408fe754a6 Merge pull request #705 from scipio3000/patch-1
Docs - Typo in volume plugin doc
Upstream-commit: 10e04c4b72
Component: cli
2017-11-20 18:55:51 +01:00
5289d7ae1c Disable adding [flags] to UseLine in man pages
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 5b4af39b8d
Component: cli
2017-11-20 12:48:10 -05:00
1da9654cd5 Update spf13/cobra
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: c01f642800
Component: cli
2017-11-20 12:42:11 -05:00
454988ca17 Merge pull request #35542 from masaeedu/patch-1
Fix consumes MIME type for NetworkConnect
Upstream-commit: 4f4a0279084921756d2b2157ad272610d7adc0ae
Component: engine
2017-11-20 18:13:26 +01:00
c23d72ffe9 Docs - Typo in volume plugin doc
There is a typo in the `plugins_volume.md#volumedriverpath` section.
The `/VolumeDriver.Path` response (v1) should be `Mountpoint`and not `Mountpoin`.

Signed-off-by: scipio3000 <gunther@gameslabs.net>
Signed-off-by: Günther Jungbluth <gunther@gameslabs.net>
Upstream-commit: e575b8e756
Component: cli
2017-11-20 15:56:09 +01:00
38076c34e8 Added validation of isolation settings on daemon.verifyContainerSettings
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Upstream-commit: e6bfe9cdcb32e97f38b53781eb1f9d7bd2ef5971
Component: engine
2017-11-20 10:34:20 +01:00
be9497fbf4 Fix consumes MIME type for NetworkConnect
This route expects `application/json`. Sending a content type header of `application/octet-stream` results in an error.

Signed-off-by: Asad Saeeduddin <masaeedu@gmail.com>
Upstream-commit: 876b32861789a0424557c640622bde47eedd2d98
Component: engine
2017-11-18 22:34:23 -05:00
23f0e9211c Merge pull request #35522 from kolyshkin/gd-custom
graphdriver: custom build-time priority list
Upstream-commit: edc204b1ffd53252649917fe54daa0b8419ed4ec
Component: engine
2017-11-17 15:48:26 -08:00
e533bd8d7a Merge pull request #35526 from brauner/2017-11-16/docker_xfs_quota_userns
skip xfs quota tests when running in user namespace
Upstream-commit: 8124d21d2ad7666e73551fcc317c109c6a02e122
Component: engine
2017-11-17 13:41:58 -05:00
5ddac3b8e8 Merge pull request #700 from rodolfoortiz/patch-1
Fixed misspelling
Upstream-commit: f6395c848c
Component: cli
2017-11-17 19:20:57 +01:00
efb2ed5d5e Add bash completion for logs --until
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 667dead8b7
Component: cli
2017-11-17 18:45:05 +01:00
afb12468a8 Add bash completion for trust sign --local
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: c29459c284
Component: cli
2017-11-17 18:30:38 +01:00
0acfb79b17 Fixed misspelling
Signed-off-by: Rodolfo Ortiz <rodolfo.ortiz@definityfirst.com>
Upstream-commit: c7d8561508
Component: cli
2017-11-17 11:27:49 -06:00
f9712fa620 Merge pull request #426 from simonferquel/service-isolation
--isolation for setting swarm service isolation mode
Upstream-commit: 5e2be6584a
Component: cli
2017-11-17 15:39:43 +01:00
c5471a4a0e Add isolation mode on service update/create and compose files
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Upstream-commit: 47cf2ea683
Component: cli
2017-11-17 15:31:13 +01:00
7e12c15274 Preparing for compose schema v3.5
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Upstream-commit: 787e30d57a
Component: cli
2017-11-17 15:30:32 +01:00
94aae8ab65 Skip further checks for quota in user namespaces
Commit 7a1618ced359a3ac921d8a05903d62f544ff17d0 regresses running Docker
in user namespaces. The new check for whether quota are supported calls
NewControl() which in turn calls makeBackingFsDev() which tries to
mknod(). Skip quota tests when we detect that we are running in a user
namespace and return ErrQuotaNotSupported to the caller. This just
restores the status quo.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Upstream-commit: 7e35df0e0484118740dbf01e7db9b482a1827ef1
Component: engine
2017-11-17 12:57:27 +01:00
6937a74b64 Supress warning when NONE was set for healthcheck
Change-Id: I9ebcf49e9e8ac76beb037779ad02ac6020169849
Signed-off-by: Li Yi <denverdino@gmail.com>
Upstream-commit: e987c554c9ff0740b9945e68228b141031bb31c6
Component: engine
2017-11-17 19:43:59 +08:00
3be11a0388 Merge pull request #697 from squeegels/patch-1
Fixed typo under User section
Upstream-commit: d981bfa964
Component: cli
2017-11-17 09:31:06 +01:00
83579492a6 Fixed typo under User section
Signed-off-by: root <root@clientele.co.za>
Signed-off-by: Squeegels <lmscrewy@gmail.com>
Signed-off-by: Squeegels <1674195+squeegels@users.noreply.github.com>
Upstream-commit: 032f676717
Component: cli
2017-11-17 09:47:41 +02:00
0db60dff81 graphdriver: custom build-time priority list
Add a way to specify a custom graphdriver priority list
during build. This can be done with something like

  go build -ldflags "-X github.com/docker/docker/daemon/graphdriver.priority=overlay2,devicemapper"

As ldflags are already used by the engine build process, and it seems
that only one (last) `-ldflags` argument is taken into account by go,
an envoronment variable `DOCKER_LDFLAGS` is introduced in order to
be able to append some text to `-ldflags`. With this in place,
using the feature becomes

  make DOCKER_LDFLAGS="-X github.com/docker/docker/daemon/graphdriver.priority=overlay2,devicemapper" dynbinary

The idea behind this is, the priority list might be different
for different distros, so vendors are now able to change it
without patching the source code.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 17708e72a7ef29fb1d4b03fbded1c5e4c08105fd
Component: engine
2017-11-16 19:43:34 -08:00
a1c54edb95 container: protect the health status with mutex
Adds a mutex to protect the status, as well. When running the race
detector with the unit test, we can see that the Status field is written
without holding this lock. Adding a mutex to read and set status
addresses the issue.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
Upstream-commit: 7db30ab0cdf072956d2ceda833b7de22fe17655c
Component: engine
2017-11-16 15:04:01 -08:00
884d22e3a4 Merge pull request #695 from mistyhacks/update-service-port-syntax
Add info about new port mapping syntax
Upstream-commit: 0fe5dcd2f2
Component: cli
2017-11-16 17:36:44 +01:00
42bb16a0de Merge pull request #35512 from cpuguy83/replace_plugun_integration_with_unit
Replace vol plugin integration test w/ unit test
Upstream-commit: ab90bc296155f341f8315a265b3c6d8112512db2
Component: engine
2017-11-16 17:35:23 +01:00
4d629f82fb Add missing lock in ProcessEvent
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
Upstream-commit: 6c03aa317404703a300ef25c3b5dc18d8e9cc64c
Component: engine
2017-11-15 19:19:26 -08:00
f78101e94a Add info about new port mapping syntax
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 9ef7caa6fe
Component: cli
2017-11-15 17:58:13 -08:00
e26667240b Merge pull request #693 from eiais/e2e
Add e2e testing for Trust revoke
Upstream-commit: 9022ea549d
Component: cli
2017-11-15 20:39:53 +01:00
ac513c6164 Merge pull request #671 from dnephin/remove-secret-config-duplication
Remove secret/config duplication in cli/compose
Upstream-commit: 801ddee343
Component: cli
2017-11-15 19:29:39 +01:00
9ef2726179 Replace vol plugin integration test w/ unit test
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 00d801dd85b486eb46eff7bd041c33f04e373699
Component: engine
2017-11-15 13:13:22 -05:00
8771152e42 Merge pull request #35429 from dnephin/build-fails-on-long-label
Fix dockerfile parser failing silently on long tokens
Upstream-commit: 7c53e732530642f817c83e1ad303f8f9f7018def
Component: engine
2017-11-15 18:48:50 +01:00
cffc0c967c Merge pull request #35492 from thaJeztah/bump-docker-py
Bump docker-py to 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
Upstream-commit: a5c679baf66488e89ccf93c2282b96673acbcb0e
Component: engine
2017-11-15 07:31:14 -08:00
55c5f024c9 Merge pull request #35504 from kolyshkin/sep-o2
daemon/graphdriver/register: separate overlay2
Upstream-commit: fa1054843f9a8a32ca33be6b73167069a8344ecf
Component: engine
2017-11-15 09:21:08 -05:00
3647d18f55 Merge pull request #35499 from cpuguy83/erroneous_errors
Cancelation errors should not be logged
Upstream-commit: 7c16e4d41769bcedfd987507ac150f516358a120
Component: engine
2017-11-15 11:34:28 +01:00
ce594a83b1 daemon/graphdriver/register: separate overlay2
Make it possible to disable overlay and overlay2 separately.

With this commit, we now have `exclude_graphdriver_overlay` and
`exclude_graphdriver_overlay2` build tags for the engine, which
is in line with any other graph driver.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: d014be5426c869d429c1a11cad9e76321dd7a326
Component: engine
2017-11-15 00:06:00 -08:00
ae3d074947 Cancelation errors should not be logged
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: b86746d60d4c43dcadd3b95fc4b2da7c03323d84
Component: engine
2017-11-14 20:32:20 -05:00
005014677c Merge pull request #34896 from cpuguy83/store_labels_when_exists
Create labels when volume exists only remotely
Upstream-commit: f62aeae97791b4c2318791a9b621d7da4c17ac32
Component: engine
2017-11-14 17:05:40 -08:00
6ad432f442 Merge pull request #35482 from stevvooe/protect-health-monitor-channel
container: protect health monitor channel
Upstream-commit: e4d0fe84f9ea88b0e0cfd847412c9f29442cc62d
Component: engine
2017-11-14 11:25:14 -08:00
8b37566333 Adds packaging for Fedora 27
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: ca096b9620cf1d8c1d0a34f052e3a3d33840fab3
Component: packaging
2017-11-14 19:13:47 +00:00
cf38fd827e Merge pull request #74 from jamiehannaford/until-logging
Add new CLI option for --until
Upstream-commit: 026c6db6f6
Component: cli
2017-11-14 18:49:46 +01:00
68402034cc Set timeout on splunk batch send
Before this change, if the splunk endpoint is blocked it will cause a
deadlock on `Close()`.
This sets a reasonable timeout for the http request to send a log batch.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 24087399d95d60be4184b9ed3eba56466878b4e1
Component: engine
2017-11-14 12:32:52 -05:00
e9b472f2e1 Add docs
Signed-off-by: Jamie Hannaford <jamie@limetree.org>
Upstream-commit: 0450a2f437
Component: cli
2017-11-14 18:04:10 +01:00
4bd3446b2b Merge pull request #35231 from sargun/add-vfs-quota-support
Add vfs quota support
Upstream-commit: 0defc6981322e16863e068f99b98326394b8cbd0
Component: engine
2017-11-14 15:05:02 +00:00
d8cda430a7 Bump docker-py to 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d1a0773d3a834a4bfa98deb07ae3f87dd6438da6
Component: engine
2017-11-14 14:17:44 +01:00
15db98f6fa Merge pull request #35465 from cpuguy83/update_containerd
Update containerd to v1 beta3
Upstream-commit: b4fbcd80c796f384eba800d1dc89892ab77c58e5
Component: engine
2017-11-14 14:01:48 +01:00
2cc0ade7cc Merge pull request #35484 from tonistiigi/clear-state
libcontainerd: fix leaking container/exec state
Upstream-commit: 1c99bc481be6abf40d4fd287d1b6634a6108a211
Component: engine
2017-11-14 11:15:30 +01:00
6f6f835501 Merge pull request #35316 from kolyshkin/facepalm
Fix honoring tmpfs-size for user /dev/shm mount
Upstream-commit: f70c715be01f5d5f4a8be4ab1b2c6e1464b478a7
Component: engine
2017-11-14 11:13:59 +01:00
523ff46adb Merge pull request #35456 from dnephin/make-runconfig-copy-deep
[Builder] Make copyRunConfig deep copy
Upstream-commit: f520822453a01673f38ed6b0ce86c52d71e43a0d
Component: engine
2017-11-14 11:12:26 +01:00
7b0db0e401 Merge pull request #691 from PatrickLang/patricklang-user
Docs - Adding note about creating Windows users
Upstream-commit: 50d218bd06
Component: cli
2017-11-14 11:10:56 +01:00
31c1f92623 integration: test case for #35271
This test case is checking that the built-in default size for /dev/shm
(which is used for `--ipcmode` being `private` or `shareable`)
is not overriding the size of user-defined tmpfs mount for /dev/shm.

In other words, this is a regression test case for issue #35271,
https://github.com/moby/moby/issues/35271

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 2e0a98b605fa278ee1f348c68fe7e07aed57b834
Component: engine
2017-11-13 22:08:23 -08:00
ca97ddf678 add e2e testing for trust revoke
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: 4a93f207a3
Component: cli
2017-11-13 17:18:10 -08:00
146e3d30b9 e2e tests: refactor using fixtures
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: cbd78572a7
Component: cli
2017-11-13 17:18:04 -08:00
ce5c429be8 libcontainerd: fix leaking container/exec state
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: 6c4ce7cb6c62fb82ed2db1d4ee3a02bc5148cdee
Component: engine
2017-11-13 15:48:21 -08:00
2ca8cee39b Disallow overlay/overlay2 on top of NFS
From https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt:

> The lower filesystem can be any filesystem supported by Linux and does
> not need to be writable. The lower filesystem can even be another
> overlayfs. The upper filesystem will normally be writable and if it
> is it must support the creation of trusted.* extended attributes, and
> must provide valid d_type in readdir responses, so NFS is not suitable.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 90dfb1d0cc59d79ccb272997d735864615010785
Component: engine
2017-11-13 23:24:23 +01:00
10c7697134 container: protect health monitor channel
While this code was likely called from a single thread before, we have
now seen panics, indicating that it could be called in parallel. This
change adds a mutex to protect opening and closing of the channel. There
may be another root cause associated with this panic, such as something
that led to the calling of this in parallel, as this code is old and we
had seen this condition until recently.

This fix is by no means a permanent fix. Typically, bugs like this
indicate misplaced channel ownership. In idiomatic uses, the channel
should have a particular "owner" that coordinates sending and closure.
In this case, the owner of the channel is unclear, so it gets opened
lazily. Synchronizing this access is a decent solution, but a refactor
may yield better results.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
Upstream-commit: 5b55747a523671fa6e626848060460a48d058451
Component: engine
2017-11-13 13:31:28 -08:00
60d1b81b0d Add deepCopyRunConfig for copying buidler runConfig
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 9bcd5d2574fe0c84542d2fa18232c34e2a9c0cac
Component: engine
2017-11-13 14:51:17 -05:00
66527d3a87 Adding note about creating Windows users
Signed-off-by: Patrick Lang <plang@microsoft.com>
Upstream-commit: cc35724c17
Component: cli
2017-11-13 11:43:38 -08:00
293c21ca60 Remove deprecated "daemon" subcommand
The `docker daemon` subcommand was only present for
backward compatibility, but deprecated in v1.13,
and scheduled for removal in v17.12

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: c6a3199236
Component: cli
2017-11-13 19:01:35 +01:00
6a81f7db2e Merge pull request #35473 from charrywanganthony/rm_stringutils
Split and remove pkg/stringutils
Upstream-commit: aea31ab242a1e5f489f1597a726267ed190a3095
Component: engine
2017-11-13 18:10:32 +01:00
2ee46bd08b Merge pull request #685 from eiais/e2e
docker trust sign: add e2e testing
Upstream-commit: 365c525fab
Component: cli
2017-11-13 17:31:42 +01:00
628966a8d4 Bump runc vendor
Updates runc to b2567b37d7b75eb4cf325b77297b140ea686ce8f which removes
some cross-repo dependencies.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: af248a3fe087805907e4b69ab017ef60d44ce093
Component: engine
2017-11-13 08:57:09 -05:00
e18edc6a6b add test for logs
Signed-off-by: Jamie Hannaford <jamie@limetree.org>
Upstream-commit: 9c9303e113
Component: cli
2017-11-13 10:57:44 +01:00
ca631a390a Merge pull request #35470 from thaJeztah/error-on-duplicate-labels
Remove deprecated support for duplicate label-keys
Upstream-commit: d5b9da206ae57255d8de490a7db8eb3ddbb590bd
Component: engine
2017-11-13 10:57:28 +01:00
f9f5db27c1 Fix user mount /dev/shm size
Commit 7120976d74195 ("Implement none, private, and shareable ipc
modes") introduces a bug: if a user-specified mount for /dev/shm
is provided, its size is overriden by value of ShmSize.

A reproducer is simple:

 docker run --rm
	--mount type=tmpfs,dst=/dev/shm,tmpfs-size=100K \
	alpine df /dev/shm

This commit is an attempt to fix the bug, as well as optimize things
a but and make the code easier to read.

https://github.com/moby/moby/issues/35271

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 31d30a985d99a0eef92116a22159727f5c332784
Component: engine
2017-11-12 21:42:59 -08:00
8369aeca8e Split and remove pkg/stringutils
Signed-off-by: Chao Wang <wangchao.fnst@cn.fujitsu.com>
Upstream-commit: 97e406678c8d695ee6eaefce41b83e9e27e239c7
Component: engine
2017-11-13 10:01:11 +08:00
aa1c9fab4f Remove deprecated support for duplicate label-keys
Support for duplicate labels (but different values) was
deprecated in commit e4c9079d091a2eeac8a74a0356e3f348db873b87
(Docker 1.13), and scheduled for removal in 17.12

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 8c6322338c91cdb88b1fef4def393d9a7b670366
Component: engine
2017-11-12 03:11:37 +01:00
6729c4835f Merge pull request #686 from mvasin/patch-1
Fix grammar
Upstream-commit: 48f4003591
Component: cli
2017-11-11 15:45:39 +01:00
7cf0bd287e Fix grammar
Signed-off-by: Mikhail Vasin <michaelvasin@gmail.com>
Upstream-commit: bdd1b1e279
Component: cli
2017-11-11 16:15:15 +03:00
f5ae1accb6 Add e2e testing for docker trust sign
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: eb025800bd
Component: cli
2017-11-10 14:26:11 -08:00
5aa9076d56 Add unit tests for some convert/service
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: f1cc679618
Component: cli
2017-11-10 16:28:39 -05:00
50743f5357 Remove duplication in compose/convert
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: a68c940f1a
Component: cli
2017-11-10 15:56:11 -05:00
a1783b999b Remove duplication in loader
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 7bd26ed690
Component: cli
2017-11-10 15:56:11 -05:00
9379e66070 Update containerd to v1 beta3
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: d3f934e304d78296e606d6e3a2ca523d249e954c
Component: engine
2017-11-10 15:44:10 -05:00
75f89d26b4 sign test: fix imports
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: a570e9b355
Component: cli
2017-11-10 11:34:04 -08:00
a754767196 Merge pull request #684 from mistyhacks/fix-spaces-service-create
Remove extra spaces from service creation examples
Upstream-commit: 70da09aac2
Component: cli
2017-11-10 11:18:15 -08:00
d77f572b3a Remove extra spaces from service creation examples
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 80211acee9
Component: cli
2017-11-10 10:14:56 -08:00
d94b0d4775 Merge pull request #35342 from charrywanganthony/inslice
Copy Inslice() to those parts that use it
Upstream-commit: 97be2a075225945ca7b92d75f85048cfd05a3a71
Component: engine
2017-11-10 07:26:42 -08:00
dcbe5b1182 Add new CLI option for --until
Signed-off-by: Jamie Hannaford <jamie.hannaford@rackspace.com>
Upstream-commit: 6f309316e2
Component: cli
2017-11-10 12:38:08 +01:00
98da414257 Copy Inslice() to those parts that use it
Signed-off-by: Chao Wang <wangchao.fnst@cn.fujitsu.com>
Upstream-commit: 5c154cfac89305f7ca9446854e56700e8a660f93
Component: engine
2017-11-10 13:42:38 +08:00
32672a8e2b Merge pull request #35453 from cpuguy83/update_fsnotify
Update fsnotify to fix deadlock in removing watch
Upstream-commit: dc90c3047e1cc59770395ded86128305e3d24543
Component: engine
2017-11-09 18:29:31 -08:00
8d5384d97c Merge pull request #35454 from cpuguy83/move_env_declaration
COPY should be the last op in the Dockerfile
Upstream-commit: 45e9630b48b99ab86a88dd9a593604810b8400b6
Component: engine
2017-11-10 10:17:21 +09:00
366ab9966c COPY should be the last op in the Dockerfile
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 503b03a3f090550052af960ece2e71d54c1fdf0e
Component: engine
2017-11-09 16:00:28 -05:00
2f7df6c0dd Update fsnotify to fix deadlock in removing watch
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: e8aa22645baf8f8254cc435e772314d4a5dee92c
Component: engine
2017-11-09 15:17:22 -05:00
7918ee610f Create labels when volume exists only remotely
Before this, if a volume exists in a driver but not in the local cache,
the store would just return a bare volume. This means that if a user
supplied options or labels, they will not get stored.

Instead only return early if we have the volume stored locally. Note
this could still have an issue with labels/opts passed in by the user
differing from what is stored, however this isn't really a new problem.

This fixes a problem where if there is a shared storage backend between
two docker nodes, a create on one node will have labels stored and a
create on the other node will not.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 4d8598ad0506b29c12632c1b8ed92eb58fc2f0e2
Component: engine
2017-11-09 15:14:06 -05:00
84fe2b7d9a Fix remote build target as Dockerfile
The test was passing previously because the preamble was already buffered. After
the change to return Scanner.Err() the final read error on the buffer was no
longer being ignored.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: a74cc833450dfc48cc95b2b109cbcb24feff4929
Component: engine
2017-11-09 15:05:26 -05:00
ca892e4f1a Fix dockerfile parser failing silently on long tokens
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 59ad3a36e2684bd36a4b02179949bd17f1406918
Component: engine
2017-11-09 15:03:20 -05:00
2bb50cbf78 Merge pull request #35250 from joppich/patch-1
Update names-generator.go
Upstream-commit: a4bdb304e29f21661e8ef398dbaeb8188aa0f46a
Component: engine
2017-11-09 06:21:02 -08:00
c716c066e5 Merge pull request #35442 from Microsoft/jjh/sysfirmware
Don't special case /sys/firmware in masked paths
Upstream-commit: d4239a6e286f546f5eda507437f643b5a1548c5d
Component: engine
2017-11-08 20:02:01 -08:00
bcc50083eb Merge pull request #35073 from mle-ii/master
Add gelf log driver plugin to Windows build
Upstream-commit: 72e179aa04999c141db96688adabfe5bcdac8293
Component: engine
2017-11-08 14:53:56 -08:00
61e5c2b6ed Merge pull request #35427 from sjeeva/master
fixed special character
Upstream-commit: 9cd6ce18af3444af58544fac3405c01818e0d388
Component: engine
2017-11-08 23:36:01 +01:00
e0e98f749d Don't special case /sys/firmware in masked paths
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: b023a46a074c14d34e09d774c9e847343541a220
Component: engine
2017-11-08 12:10:42 -08:00
6dd3e92796 Merge pull request #679 from thaJeztah/revendor-moby
Bump moby to f4d4f5863156b82ef146b6ff1e845f8dcf019f12
Upstream-commit: 458ce53f18
Component: cli
2017-11-08 14:55:54 -05:00
e52bfcca39 fixed special character
`scope`=<string> local or swarm had special character, which was breaking the Swagger UI

Signed-off-by: Jeeva S. Chelladhurai <sjeeva@gmail.com>
Upstream-commit: a21654c34b741656582b09e09127821311909dcd
Component: engine
2017-11-08 19:17:24 +00:00
8a571d7e05 Bump moby to f4d4f5863156b82ef146b6ff1e845f8dcf019f12
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 5735fff6fc
Component: cli
2017-11-08 17:50:58 +01:00
3e8332108b Merge pull request #34573 from cyphar/dm-dos-prevention-remove-mountpoint
devicemapper: remove container rootfs mountPath after umount
Upstream-commit: bbc4f78ba9c77f5a2e177c69870efed0eb7e8ba2
Component: engine
2017-11-08 17:08:07 +01:00
1fce7e41ce Add bash completion for experimental build --stream
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: c852393bff
Component: cli
2017-11-08 14:32:14 +01:00
ce00560e17 Add --log-opt awslogs-credentials-endpoint to bash completion
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 1390ae6022
Component: cli
2017-11-08 14:07:05 +01:00
49cfe581ba Add support for GELF tcp connections to bash completion
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: c231c381fe
Component: cli
2017-11-08 13:54:51 +01:00
96ed9e5d58 Merge pull request #35423 from thaJeztah/bump-image-spec
Bump opencontainers/image-spec to v1.0.0
Upstream-commit: f4d4f5863156b82ef146b6ff1e845f8dcf019f12
Component: engine
2017-11-08 09:37:16 +09:00
95cc30e089 devmapper: add a test for mount leak workaround
In order to avoid reverting our fix for mount leakage in devicemapper,
add a test which checks that devicemapper's Get() and Put() cycle can
survive having a command running in an rprivate mount propagation setup
in-between. While this is quite rudimentary, it should be sufficient.

We have to skip this test for pre-3.18 kernels.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: 1af8ea681fba1935c60c11edbbe19b894c9b286f
Component: engine
2017-11-08 11:02:11 +11:00
dfd681c198 Merge pull request #35424 from cyphar/tar-split-cve_2017_14992
vendor: update to github.com/vbatts/tar-split@v0.10.2
Upstream-commit: bd8ed57506a82a8ec3d69cd272ef8f5942c4b977
Component: engine
2017-11-07 23:09:38 +01:00
edb2c3c5b1 Merge pull request #575 from eiais/local-flag
trust sign: add --local flag
Upstream-commit: ee0615dc97
Component: cli
2017-11-07 14:15:53 -05:00
22a9ee4f49 image: add import test for CVE-2017-14992
To ensure that we don't revert CVE-2017-14992, add a test that is quite
similar to that upstream tar-split test (create an empty archive with
lots of junk and make sure the daemon doesn't crash).

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: 0a13f827a10d3bf61744d9b3f7165c5885a39c5d
Component: engine
2017-11-08 05:37:52 +11:00
dbf5fa6264 Merge pull request #35265 from cpuguy83/32609_defreference_voldriver_on_error
Fixup some issues with plugin refcounting
Upstream-commit: 5745a8531e7a52d4db09f2eafde0391b59a13b4b
Component: engine
2017-11-07 09:47:07 -08:00
c18684ecbe internal: testutil: add DevZero helper
This helper acts like /dev/zero (outputs \x00 indefinitely) in an
OS-independent fashion. This ensures we don't need to special-case
around Windows in tests that want to open /dev/zero.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: 2f8d3e1c33f77187c68893803018756d43daff15
Component: engine
2017-11-08 03:45:55 +11:00
755085f5c8 Merge pull request #35419 from johnstep/handle-scratch-image-os
Set OS on scratch image and prevent panic if empty
Upstream-commit: 2f22f64d5561dc39e70353566ba4f84f02b980c7
Component: engine
2017-11-07 08:32:27 -08:00
19146bf34e vendor: update to github.com/vbatts/tar-split@v0.10.2
Update to the latest version of tar-split, which includes a change to
fix a memory exhaustion issue where a malformed image could cause the
Docker daemon to crash.

  * tar: asm: store padding in chunks to avoid memory exhaustion

Fixes: CVE-2017-14992
Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: e0ff7cccc3cac73da41ec9ef007b0e4e97c55d01
Component: engine
2017-11-08 02:50:52 +11:00
e49f1e9075 Bump opencontainers/image-spec to v1.0.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: c5ccc7f73fecfa881a8ff9ddc5032892223204ee
Component: engine
2017-11-07 16:16:09 +01:00
72aededa94 Merge pull request #35326 from RenaudWasTaken/swarmkit-revendored
Revendored Swarmkit 
Upstream-commit: eec662bbee7eace06f4fa7088dd2311a03a65858
Component: engine
2017-11-07 06:56:15 -08:00
22f416c376 Merge pull request #670 from dnephin/cleanup-compose-volume-name
Only warn on volume.external.name for version 3.4
Upstream-commit: 025f51ca93
Component: cli
2017-11-07 14:29:22 +01:00
ce8d7a3b24 Merge pull request #474 from jhowardmsft/jjh/apis-for-platform
LCOW: CLI changes to add platform flag - pull, run, create and build
Upstream-commit: 042575aac9
Component: cli
2017-11-07 14:26:31 +01:00
9302e76682 Merge pull request #657 from dnephin/add-test-for-container-cp
Adding unit tests for container cp
Upstream-commit: 21d88629df
Component: cli
2017-11-07 14:22:22 +01:00
7cfb40e0bf Set OS on scratch image and prevent panic if empty
Signed-off-by: John Stephens <johnstep@docker.com>
Upstream-commit: a97817b673cbd3bfaf6e752282c4992ac43ff594
Component: engine
2017-11-06 18:22:15 -08:00
bab1ef9f35 Add quota support to VFS graphdriver
This patch adds the capability for the VFS graphdriver to use
XFS project quotas. It reuses the existing quota management
code that was created by overlay2 on XFS.

It doesn't rely on a filesystem whitelist, but instead
the quota-capability detection code.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: 7a1618ced359a3ac921d8a05903d62f544ff17d0
Component: engine
2017-11-06 15:53:51 -08:00
127d797434 Only warn on volume.external.name for version 3.4
Also remove use of volume.external.name

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: aea9544db5
Component: cli
2017-11-06 17:04:36 -05:00
aee7705a5f Added NodeGenericResource config tests
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: 734346a37e0cd5d2576f759d302beed5033ff14e
Component: engine
2017-11-06 21:47:26 +01:00
e5124fd7ef Updated GenericResource CLI
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: ebe14310b7728cca6d092ff66236577a3f3016d5
Component: engine
2017-11-06 21:47:26 +01:00
ae808b0eb3 Merge pull request #35398 from thaJeztah/fix-api-version-for-until-option
Move "until" option to correct API version
Upstream-commit: b00b1b1c40750dd0239fb30e421686b63b4183bd
Component: engine
2017-11-05 07:23:42 -05:00
f0b2e74732 Merge pull request #35394 from chris-crone/e2e-add-headers
Add missing headers for e2e test image build
Upstream-commit: ee21669f5329733cced55e1c678cd6cee393a6e4
Component: engine
2017-11-05 09:50:54 +01:00
59e0e866f3 Merge pull request #34162 from cpuguy83/move_logread_logic
Move jsonlog read logic
Upstream-commit: edaba571bac5d9dfaaa1b0b7c601ad712cae58d3
Component: engine
2017-11-04 13:53:36 -07:00
63e16f39ad Merge pull request #35244 from joyce/joyce/todo-fixes
fix todo for printing error messages
Upstream-commit: 48694a3f880650a1b41765ab0bebb373d0b73a22
Component: engine
2017-11-04 13:52:45 -07:00
dff2ac1e17 Move json log reading into log file object
This allows much of the read logic to be shared for other things,
especially for the new log driver proposed in
https://github.com/moby/moby/issues/33475

The only logic for reads in the json logger is around decoding log
messages, which gets passed into the log file object.

This also helps with implementing compression as it allows us to
simplify locking strategies.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 16f7cd674902b69b97692de2a83915a1a6be2cdb
Component: engine
2017-11-04 08:31:58 -04:00
70ca1da8d3 Refactor log file writer
Make the `*RotateFileWriter` specifically about writing
`logger.Message`'s, which is what it's used for.

This allows for future changes where the log writer can cache details
about log entries such as (e.g.) the timestamps included in a particular
log file, which can be used to optimize reads.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 52d82b4fbc9f0fe00f63e2df9a3d2a49d4095bda
Component: engine
2017-11-04 08:15:20 -04:00
18aef1e39d Merge pull request #35404 from tonistiigi/stream-ctx-fix
builder: fix long stream sync
Upstream-commit: 2c1043c913b3d2313e5558825f3dc8fc1727042b
Component: engine
2017-11-04 01:07:06 +01:00
b9b2e53e40 builder: fix long stream sync
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: c6703b722e1c0914342d61ca6af77aea93150873
Component: engine
2017-11-03 12:53:17 -07:00
cffa465570 Merge pull request #35399 from justincormack/mask-scsi
Add /proc/scsi to masked paths
Upstream-commit: a8cefcf6af6c6bfa1d60a2d9deb80a01ce008690
Component: engine
2017-11-03 11:58:20 -07:00
6edab5bbbd fix todo for printing error messages
Signed-off-by: Joyce <mail@joycejang.com>
Upstream-commit: 883ab41ce8f5163ba8ce0450ffff1e63c266f23b
Component: engine
2017-11-03 11:35:41 -07:00
61e2a38de5 Add /proc/scsi to masked paths
This is writeable, and can be used to remove devices. Containers do
not need to know about scsi devices.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
Upstream-commit: a21ecdf3c8a343a7c94e4c4d01b178c87ca7aaa1
Component: engine
2017-11-03 15:12:22 +00:00
84f5991ee5 Move "until" option to correct API version
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6f34bd6f968be243659ad62976822036f4f4eb17
Component: engine
2017-11-03 16:11:07 +01:00
5de35938b7 Merge pull request #32914 from jamiehannaford/until-logging
Add --until flag for docker logs; closes #32807
Upstream-commit: 68a4552529c2eafb7093dc2bc25e7fc243bf363f
Component: engine
2017-11-03 16:08:30 +01:00
ab9214e3c9 Merge pull request #35368 from dnephin/remove-version-file
Remove version file
Upstream-commit: 47a1786be2a2f1458eea5e39e8e93c375cd6fdaa
Component: engine
2017-11-03 07:58:37 -07:00
7264e2410c Revendored swarmkit
Signed-off-by: Renaud Gaubert <renaud.gaubert@gmail.com>
Upstream-commit: b3960fc1c450961ef3f31d6db21ac237d1b4d99d
Component: engine
2017-11-03 15:43:50 +01:00
fc04cb890d Merge pull request #35365 from Microsoft/jjh/removeduplicateoomscoreadj
Remove duplicate redundant setting of OOMScoreAdj in OCI spec
Upstream-commit: f5c70c5b75238804be39f048eef6aad9cc0cd166
Component: engine
2017-11-03 13:59:51 +00:00
593039ced7 Merge pull request #35383 from thaJeztah/new-misty-handle
Update Misty's GitHub handle
Upstream-commit: 7801be2eee987013cc20148d0335f42bec618835
Component: engine
2017-11-03 12:59:47 +01:00
ca401e539a Merge pull request #35168 from justincormack/update-contributing
First pass updating CONTRIBUTING
Upstream-commit: dfbf0f2e915696740e4d4dd3fb9877f676ead9f0
Component: engine
2017-11-03 12:57:21 +01:00
4aac83aaac First pass updating CONTRIBUTING
This largely removes references to Docker where possible.

The HOWTO guides are still Docker docs and refer to Docker not
moby, so the next step is to rework these as Moby docs and put
them in `docs/` in this repo.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
Upstream-commit: cecd0de3a9f783b34f75ca5e6394b9a0c123999e
Component: engine
2017-11-03 11:54:55 +00:00
73e10347de Merge pull request #35344 from rhatdan/readonly-/dev
/dev should not be readonly with --readonly flag
Upstream-commit: 7d8affa3ef1ec904c1f10814f17406f39ff55fc9
Component: engine
2017-11-03 12:54:51 +01:00
d055b6f5d3 Merge pull request #35388 from tonistiigi/rlock-fix
cluster: avoid recursive readlock on swarm info
Upstream-commit: 47b3209f687c240dc2841bcfc147b2ffa341a7fe
Component: engine
2017-11-03 18:09:16 +09:00
fc26552dd2 e2e: Add missing headers for build
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
Upstream-commit: 37553a6963455fc0d5cea1ae218575cc28d3d251
Component: engine
2017-11-03 10:09:06 +01:00
5ead3bed6b Merge pull request #35389 from thaJeztah/improve-containerd-version-parsing
Use containerd API to get version
Upstream-commit: 4063bbd08877af9d2b75b863c2b469e6cb8f4fa9
Component: engine
2017-11-03 18:06:22 +09:00
e3495e0554 Merge pull request #35382 from thaJeztah/fix-api-version
Fix API version
Upstream-commit: a9182202f76be31a7bec510dd00cf24677e58c7e
Component: engine
2017-11-03 09:52:55 +01:00
d2b0c1cba5 Merge pull request #35375 from cpuguy83/update_dockerpy
Update docker-py commit
Upstream-commit: f5a2f3b40c46979e45559f75c37dfc85f97335a6
Component: engine
2017-11-02 18:42:18 -07:00
4a715bb927 Use containerd API to get version
The `docker info` code was shelling out to obtain the
version of containerd (using the `--version` flag).

Parsing the output of this version string is error-prone,
and not needed, as the containerd API can return the
version.

This patch adds a `Version()` method to the containerd Client
interface, and uses this to get the containerd version.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: fec2b144feaaa18998ec2ed34c9bc843c4c29abd
Component: engine
2017-11-03 01:46:58 +01:00
304c69a1ec cluster: avoid recursive readlock on swarm info
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: ee1be71e9dc52db8a7ac951ba96f18a5c894806a
Component: engine
2017-11-02 16:34:00 -07:00
9136cbe399 temporarily move docker-py tests for faster feedback
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 073dd7ab39da342793c30c08192a8005498e0ffd
Component: engine
2017-11-02 18:05:38 -04:00
cbad1c68f7 Update docker-py commit
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 16d83571f5f8f833aca123874cbb34ff023df995
Component: engine
2017-11-02 18:02:52 -04:00
0cd754e14e Merge pull request #34224 from estesp/no-chown-nwfiles-outside-metadata
Only chown network files within container metadata
Upstream-commit: 462d79165f48f838102d4206af70e64c1e3d6a6d
Component: engine
2017-11-02 15:00:42 -07:00
633f82e30c Merge pull request #664 from thaJeztah/new-misty-handle
Update Misty's GitHub handle
Upstream-commit: e2ada663d2
Component: cli
2017-11-02 17:57:08 +01:00
fd4c48b1d3 Update Misty's GitHub handle
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 14b1535dfe
Component: cli
2017-11-02 16:50:38 +01:00
9f6163c9a9 Update Misty's GitHub handle
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 30b4b5640e7117fc38755a7d5aae0d9a872efaaf
Component: engine
2017-11-02 16:46:37 +01:00
3e0fab4d2e /dev should not be readonly with --readonly flag
/dev is mounted on a tmpfs inside of a container.  Processes inside of containers
some times need to create devices nodes, or to setup a socket that listens on /dev/log
Allowing these containers to run with the --readonly flag makes sense.  Making a tmpfs
readonly does not add any security to the container, since there is plenty of places
where the container can write tmpfs content.

I have no idea why /dev was excluded.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Upstream-commit: 5f3bd2473ee2a1b9f37ba0130e934133d0e01f89
Component: engine
2017-11-02 10:28:51 -04:00
c2ca3d9c02 Merge pull request #35371 from thaJeztah/remove-version-matrix
Remove Docker/API version matrix
Upstream-commit: 4bc5a5765288c797bb6989a9e08938b5327236dc
Component: engine
2017-11-02 06:10:20 -07:00
b878f3dd1f Fix API version
Commit 3ba1dda1914fa7d380d9d3220c3b158a41f90cba bumped
the API version, but forgot to actually bump the version
in code.

This patch fixes the version to match those changes :-)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 7f8dbe4a86650b02ffb490098b9f3bf0912c575d
Component: engine
2017-11-02 13:08:27 +01:00
564091fdbb Merge pull request #35373 from yongtang/11012017-solaris
Remove solaris build tag and `contrib/mkimage/solaris`
Upstream-commit: 76531ccdeb5850156150b88c6a4a56bb8c35dc44
Component: engine
2017-11-02 16:39:02 +09:00
eefbd135ae Remove solaris build tag and `contrib/mkimage/solaris
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 4785f1a7ab7ec857dc3ca849ee6ecadf519ef30e
Component: engine
2017-11-02 00:01:46 +00:00
7559d4940b Merge pull request #35369 from thaJeztah/fix-api-changes
Move Isolation API changes to the correct version
Upstream-commit: deae42863209d742ddf96c922e12268c6d887033
Component: engine
2017-11-02 00:38:19 +01:00
4380d9b1d1 Merge pull request #35363 from yongtang/11012017-Dockerfile.solaris
Remove Dockerfile.solaris reference
Upstream-commit: 64e1d4a1f0081f669fff8ed0ad630b202c0cda8a
Component: engine
2017-11-01 16:36:00 -07:00
bd820b2e31 Remove Docker/API version matrix
The Swagger file contained a version matrix to
find which API version is used by which version
of Docker.

Given that Docker is a downstream of the Moby project,
we should not be maintaining such a matrix in this
repository.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 3fb228ba50ccb921148e0174e5e5e45ab650c3e5
Component: engine
2017-11-01 22:29:26 +01:00
a1f2fd42a7 Move Isolation API changes to the correct version
Commit d91c5f42eb37c6f88cec4021c10c0a1ded1785c3 added
support for "Isolation" mode for services, but didn't
get merged before API 1.34.

This patch moves the description in the API version
history to the correct API version (1.35), and does
a slight rewording of the functionality.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 4533a16fa98785c8c18bf9b9a32da5390fc74757
Component: engine
2017-11-01 22:13:10 +01:00
45def429d3 Merge pull request #34424 from simonferquel/swarm-service-isolation
Added support for swarm service isolation mode
Upstream-commit: d91c5f42eb37c6f88cec4021c10c0a1ded1785c3
Component: engine
2017-11-01 16:41:10 -04:00
9a9cb24385 Remove version file
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 1e1ad008db1af4f415b9ef9b8d6d225a09ab42e1
Component: engine
2017-11-01 16:25:03 -04:00
a60239224c Merge pull request #35364 from dnephin/remove-w2l-scripts
Remove W2L scripts
Upstream-commit: d1d69524c25fdc729f1a35826ffce5d37038f141
Component: engine
2017-11-01 15:56:04 -04:00
b9e1e46d81 Merge pull request #35360 from thaJeztah/fix-autogen-warning
Fix .go-autogen warnings
Upstream-commit: a17bfb78e8c33f67338f480637948f537cb69f40
Component: engine
2017-11-01 15:12:09 -04:00
89d76e74a5 Merge pull request #35341 from tklauser/utsname-x-sys
Simplify Utsname string conversion
Upstream-commit: 0bcca5ea863d8e100ede8b7e48d8209cc4620fec
Component: engine
2017-11-01 11:36:38 -07:00
242504f367 Remove dupl setting of OOMScoreAdj in OCI spec
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: f0b44881b5d43b18871dee2ecc2bb313046038f6
Component: engine
2017-11-01 11:01:43 -07:00
8146500811 Remove W2L scripts
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 6d87d178131429217dec0621263d43c848dc7589
Component: engine
2017-11-01 13:09:09 -04:00
d488311b88 Merge pull request #35351 from dnephin/remove-packaging-scripts
Remove packaging scripts
Upstream-commit: be6a523bb9cebe739005327279ad7c090f6c87bf
Component: engine
2017-11-01 17:37:47 +01:00
4d81559763 Remove Dockerfile.solaris reference
Remove Dockerfile.solaris reference in `hack/make/.detect-daemon-osarch`
as `Dockerfile.solaris` has been removed.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: d157d98a5fbfc98f4adec20ce510b99c795b0d9c
Component: engine
2017-11-01 16:26:29 +00:00
0faeccd9ce Merge pull request #35357 from ripcurld0/small_nitpick
Nitpick plugin/manager.go: use loop to create directories
Upstream-commit: f6700d52244de7ee121c0acc564d38753cadaf7c
Component: engine
2017-11-01 16:33:23 +01:00
86be218c45 Only chown network files within container metadata
If the user specifies a mountpath from the host, we should not be
attempting to chown files outside the daemon's metadata directory
(represented by `daemon.repository` at init time).

This forces users who want to use user namespaces to handle the
ownership needs of any external files mounted as network files
(/etc/resolv.conf, /etc/hosts, /etc/hostname) separately from the
daemon. In all other volume/bind mount situations we have taken this
same line--we don't chown host file content.

Docker-DCO-1.1-Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
Upstream-commit: 42716dcf5c986e4cbb51f480f2782c05e5bd0b41
Component: engine
2017-11-01 10:14:01 -04:00
a92483bbdf Fix .go-autogen warnings
The `.integration-test-helpers` script was sourced by `/etc/bash/bash.rc`.
However, the `$SCRIPTDIR` environment variable is set through `hack/make.sh`,
so will not be set when calling the `.integration-test-helpers` script directly.

Before this patch;

    make BIND_DIR=. shell
    ...
    bash: /make/.go-autogen: No such file or directory

After this patch, the warning is no longer printed

Also removed sourcing `.go-autogen` from test-integration and build-integration-test-binary,
as they already sourced `.integration-test-helpers` (which sources
`.go-autogen`).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6d5e468db1f07c12140af0cf36ba0d1a09bb4ca9
Component: engine
2017-11-01 12:03:32 +01:00
0bcfa85080 Nitpick plugin/manager.go: use loop to create directories
Instead of duplicating the same if condition per plugin manager directory,
use one if condition and a for-loop.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Upstream-commit: d75f1d848721f04fdc703a2e88a98600f29933a6
Component: engine
2017-11-01 11:29:37 +02:00
fb29de3583 Add --until flag for docker logs; closes #32807
Signed-off-by: Jamie Hannaford <jamie.hannaford@rackspace.com>
Upstream-commit: e8d9a61f4c9e1f3cfdf1c889c541c9dc72a4bb40
Component: engine
2017-11-01 10:08:49 +01:00
2f5eef6e9a Merge pull request #35348 from thaJeztah/bump-selinux
bump opencontainers/selinux to b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
Upstream-commit: ba99c19b593bdb9e7b90793681fe89b0a91781ed
Component: engine
2017-10-31 20:12:34 -07:00
0954691f2f Remove packaging scripts
These scripts have not been used for a while now, and should not be used again
because they are for releasing docker, not moby

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: eef85648e43fef2ec73462fd3d734947384cb16e
Component: engine
2017-10-31 18:37:05 -04:00
7bfb66c670 Merge pull request #35347 from lioncruise/patch-1
Fix grammatical problems in several annotations
Upstream-commit: 100ec844ccad6b79bcb11650e32e9a05ff51a441
Component: engine
2017-10-31 15:25:27 -07:00
7afaa41128 Merge pull request #35350 from crosbymichael/ctd-static
Add containerd static compile
Upstream-commit: 842bbeb63d82a55ee6ce537f860e9b37c146481c
Component: engine
2017-10-31 14:01:16 -07:00
31ecf1d5a7 Merge pull request #661 from thaJeztah/bump-golang-to-1.8.5
Bump Go to 1.8.5
Upstream-commit: 5a4fe7fe05
Component: cli
2017-10-31 16:24:27 -04:00
8126d722b0 Merge pull request #55 from seemethere/add_artful
Add Ubuntu 17.10, Artful
Upstream-commit: 7b2f5e75e1b30ab70bee294e0215f399ffe32d25
Component: packaging
2017-10-31 13:19:41 -07:00
dbab169d62 Bump Go to 1.8.5
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: bc8282a235
Component: cli
2017-10-31 21:04:59 +01:00
9e1b28e972 Merge pull request #35343 from thaJeztah/bump-api-version-1.35
Bump API version to 1.35
Upstream-commit: 3ba1dda1914fa7d380d9d3220c3b158a41f90cba
Component: engine
2017-10-31 12:37:12 -07:00
5e3a8a19fe Update to 1.8.5
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: c16053e90143cd8a9a559b749407d938f0cb4456
Component: packaging
2017-10-31 11:22:44 -07:00
cf57f4873b Merge pull request #58 from thaJeztah/bump-golang-to-1.8.5
Bump Golang to 1.8.5
Upstream-commit: 798ac05bb417d6f51fba3da55d1b9a9c7b686d61
Component: packaging
2017-10-31 11:22:37 -07:00
f9bbb79bc5 Bump Golang to 1.8.5
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: f7e22edc5125feab9887cf6cd6b94a153a88ed89
Component: packaging
2017-10-31 18:57:28 +01:00
7fe5d41e3a Merge pull request #53 from thaJeztah/bump-golang-to-1.8.4
Bump Go to 1.8.4
Upstream-commit: 18b39977570d17368c9d03e862e0ce264f7ef082
Component: packaging
2017-10-31 10:54:14 -07:00
77f73751db LCOW: Add --platform= CLI flag to pull/create/run/build
Signed-off-by: John Howard <jhoward@microsoft.com>

This is the CLI updates for the document discussed in https://github.com/moby/moby/issues/34617
to support Linux Containers on Windows. It adds --platform= as CLI flags to the four
commands listed above. Import still to be completed (needs daemon changes).
Upstream-commit: d8b782560e
Component: cli
2017-10-31 09:50:43 -07:00
b1394ae4a5 Merge pull request #34271 from tonistiigi/build-symlink-hash
builder: fix build cache hash for broken symlink
Upstream-commit: 3ab20a87fa10360df891a67b8307399cdf1ab429
Component: engine
2017-10-31 09:38:57 -07:00
d76235b88c bump opencontainers/selinux to b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
This vendoring fixes two issues.

1. When a user specifies an SELinux MCS Label (level) to override moby picking
   an unigue MCS label, the code currently picks a label then overrides with the
   user selected. This works fine, except the unique MCS Label is leaked and will
   not be used until the daemon is restarted.
2. The override label, is not reserved. This could potentially cause an issue
   where the daemon could pick the same MCS Label again for a different container.
   (~ 1/500,000 Chance).

The updated selinux go bindings, now release the overriden unigue label, and reserve
the one specified by the user.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 73c82386148fe14a47cc515c622bd23b9b7d99b9
Component: engine
2017-10-31 16:54:16 +01:00
3c035adcf7 Add containerd static compile
Fixes #35349

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 007db062f0c39bf31e1150aa26d045778ab7d24e
Component: engine
2017-10-31 11:50:29 -04:00
bf8eb18312 Merge pull request #660 from thaJeztah/bump-version-to-v17.12-dev
Bump version to 17.12.0-dev
Upstream-commit: 1dc89aa98f
Component: cli
2017-10-31 16:37:42 +01:00
95c878aac5 Fix grammatical problems in several annotations
Signed-off-by: qinshijun <272700767@qq.com>
Upstream-commit: 3c376a882b89bc1ff4f7b47667f49440a516bd70
Component: engine
2017-10-31 22:47:58 +08:00
b5133b1bd8 Update names-generator.go to include Cédric Villani and Valentina
Tershkova

Signed-off-by: Jorit Kleine-Möllhoff <joppich@bricknet.de>
Upstream-commit: f69f8f367987717a154d4c95ea9261bc9416734a
Component: engine
2017-10-31 15:38:57 +01:00
06a81bf15d Merge pull request #658 from arehman199/fix-a-number-of-typos
fix a number of minor typos
Upstream-commit: a0140b4ddb
Component: cli
2017-10-31 15:07:51 +01:00
6b11145c27 Bump API version to 1.35
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ba6b5aa7f28dbc76c6e0c494eb228a652a0d55a7
Component: engine
2017-10-31 12:57:14 +01:00
356175fe57 Bump version to 17.12.0-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a195685bac
Component: cli
2017-10-31 12:33:06 +01:00
379ed62f4b Merge pull request #609 from albers/completion-trust
Add bash completion for `docker trust` commands
Upstream-commit: d0197347ea
Component: cli
2017-10-31 11:24:35 +01:00
70aedb437f fix a number of minor typos
Fix 19 typos, grammatical errors and duplicated words.

These fixes have minimal impact on the code as these are either in the
doc files or in comments inside the code files.

Signed-off-by: Abdur Rehman <abdur_rehman@mentor.com>
Upstream-commit: c3fe9d85ef
Component: cli
2017-10-31 15:21:51 +05:00
f64b1b1e67 Simplify Utsname string conversion
Update golang.org/x/sys to 95c6576299259db960f6c5b9b69ea52422860fce in
order to get the unix.Utsname with byte array instead of int8/uint8
members.

This allows to use simple byte slice to string conversions instead of
using charsToString or its open-coded version.

Also see golang/go#20753 for details.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Upstream-commit: 6d068bc25b35a420e63e295ea4ab4ac4a6e6665b
Component: engine
2017-10-31 10:59:32 +01:00
f85a09c5e7 Merge pull request #654 from dnephin/pr-fix-image-rm
Fix behaviour of `rmi -f` with unexpected errors
Upstream-commit: 6e04da39b8
Component: cli
2017-10-31 10:38:38 +01:00
f817bbeeb6 Merge pull request #35335 from dnephin/remove-a-test
Remove a test that was moved to docker/cli
Upstream-commit: 147ec3be2e7fe5d35553401990317cf49088ec86
Component: engine
2017-10-31 07:56:03 +01:00
57801c5154 trust sign: add --local flag
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: f5a50650d6
Component: cli
2017-10-30 16:06:03 -07:00
b617f5a57f Remove a test that was moved to docker/cli
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 1a03bd396b21f0c291499e1c5bd185d23e20ffc1
Component: engine
2017-10-30 18:39:11 -04:00
b96759ddb9 Adding unit tests for cp
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: b7b62ca26a
Component: cli
2017-10-30 18:33:28 -04:00
74cd535226 Use t.Run() for tests
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: b900676523
Component: cli
2017-10-30 13:00:03 -04:00
0f02c6fd5a docker rm -f exits with 1 if the image was not removed
Signed-off-by: Arash Deshmeh <adeshmeh@ca.ibm.com>
Upstream-commit: 125302cfa6
Component: cli
2017-10-30 12:50:19 -04:00
1377e81acb Added support for swarm service isolation mode
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
Upstream-commit: f28cb422e69bd4239401e6ea32b65b56485d6691
Component: engine
2017-10-30 16:16:18 +01:00
52f9a6e75e Change multi-type parameters to single type
Signed-off-by: Asad Saeeduddin <masaeedu@gmail.com>
Upstream-commit: c6d32bebe5b6a0919fcb530692092dd5516e5b54
Component: engine
2017-10-26 06:10:24 -04:00
1c3f4cf12c Fixup some issues with plugin refcounting
In some circumstances we were not properly releasing plugin references,
leading to failures in removing a plugin with no way to recover other
than restarting the daemon.

1. If volume create fails (in the driver)
2. If a driver validation fails (should be rare)
3. If trying to get a plugin that does not match the passed in capability

Ideally the test for 1 and 2 would just be a unit test, however the
plugin interfaces are too complicated as `plugingetter` relies on
github.com/pkg/plugin/Client (a concrete type), which will require
spinning up services from within the unit test... it just wouldn't be a
unit test at this point.
I attempted to refactor this a bit, but since both libnetwork and
swarmkit are reliant on `plugingetter` as well, this would not work.
This really requires a re-write of the lower-level plugin management to
decouple these pieces.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 3816b514387efd24394f0b8e61d55502aa6ac9ac
Component: engine
2017-10-21 15:17:57 -04:00
e18e9addc6 Add Ubuntu 17.10, Artful
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 1468941a50dba7e0a82a01cb938338041f028ef9
Component: packaging
2017-10-20 11:46:49 -07:00
24d0fa40df Bump Go to 1.8.4
Bumps the Go version used to 1.8.4, which contains
security fixes; https://groups.google.com/forum/#!topic/golang-announce/1hZYiemnkdE

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 9f50d4449ab79e467e7c2a2a498bf00ebd9db48c
Component: packaging
2017-10-14 23:26:31 +02:00
a2e7813d7e Fix tests after Hash() behavior change
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: d5b15f0d3ee6b9575a919ca5ba568631957425e0
Component: engine
2017-10-10 14:23:12 -07:00
e06cccc917 Add bash completion for docker trust commands
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: bb28364824
Component: cli
2017-10-07 13:29:10 +02:00
a34160d786 Remove unused variable from bash completion
Removes a copy & paste leftover.

Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 891c3a9d96
Component: cli
2017-10-07 13:29:10 +02:00
7cd305fd99 Add docs for Dockerfile ADD/COPY --chown flag
Document the new `--chown` flag added to the ADD and COPY commands in
the Dockerfile format.

Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
Upstream-commit: a83b9f102b
Component: cli
2017-10-05 12:35:01 -04:00
d069c92fec Add gelf log driver plugin to Windows build
Signed-off-by: Mike Estes <mle_ii@yahoo.com>
Upstream-commit: 10b449b997373df37f285594a624545ad3e173b2
Component: engine
2017-10-03 12:42:54 -07:00
5103c6279f builder: fix build cache hash for broken symlink
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: 793ebdbf4b187b3680aed0073643040ddbeef523
Component: engine
2017-09-29 09:27:51 -07:00
87c0724076 devicemapper: remove container rootfs mountPath after umount
libdm currently has a fairly substantial DoS bug that makes certain
operations fail on a libdm device if the device has active references
through mountpoints. This is a significant problem with the advent of
mount namespaces and MS_PRIVATE, and can cause certain --volume mounts
to cause libdm to no longer be able to remove containers:

  % docker run -d --name testA busybox top
  % docker run -d --name testB -v /var/lib/docker:/docker busybox top
  % docker rm -f testA
  [fails on libdm with dm_task_run errors.]

This also solves the problem of unprivileged users being able to DoS
docker by using unprivileged mount namespaces to preseve mounts that
Docker has dropped.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: 92e45b81e0a8b68d9567a2068247460a1ba59600
Component: engine
2017-09-06 20:11:01 +10:00
1247 changed files with 36102 additions and 25134 deletions

View File

@ -1 +1,88 @@
# Changelog
Items starting with `DEPRECATE` are important deprecation notices. For more
information on the list of deprecated flags and APIs please have a look at
https://docs.docker.com/engine/deprecated/ where target removal dates can also
be found.
## 17.12.0-ce (2017-12-DD)
### Builder
- Fix build cache hash for broken symlink [moby/moby#34271](https://github.com/moby/moby/pull/34271)
- Fix long stream sync [moby/moby#35404](https://github.com/moby/moby/pull/35404)
- Fix dockerfile parser failing silently on long tokens [moby/moby#35429](https://github.com/moby/moby/pull/35429)
### Client
* Remove secret/config duplication in cli/compose [docker/cli#671](https://github.com/docker/cli/pull/671)
* Add `--local` flag to `docker trust sign` [docker/cli#575](https://github.com/docker/cli/pull/575)
* Add `docker trust inspect` [docker/cli#694](https://github.com/docker/cli/pull/694)
+ Add `name` field to secrets and configs to allow interpolation in Compose files [docker/cli#668](https://github.com/docker/cli/pull/668)
+ Add `--isolation` for setting swarm service isolation mode [docker/cli#426](https://github.com/docker/cli/pull/426)
* Remove deprecated "daemon" subcommand [docker/cli#689](https://github.com/docker/cli/pull/689)
- Fix behaviour of `rmi -f` with unexpected errors [docker/cli#654](https://github.com/docker/cli/pull/654)
* Integrated Generic resource in service create [docker/cli#429](https://github.com/docker/cli/pull/429)
### Documentation
* Update API version history for 1.35 [moby/moby#35724](https://github.com/moby/moby/pull/35724)
### Logging
* Logentries driver line-only=true []byte output fix [moby/moby#35612](https://github.com/moby/moby/pull/35612)
* Logentries line-only logopt fix to maintain backwards compatibility [moby/moby#35628](https://github.com/moby/moby/pull/35628)
+ Add `--until` flag for docker logs [moby/moby#32914](https://github.com/moby/moby/pull/32914)
+ Add gelf log driver plugin to Windows build [moby/moby#35073](https://github.com/moby/moby/pull/35073)
* Set timeout on splunk batch send [moby/moby#35496](https://github.com/moby/moby/pull/35496)
### Networking
* Move load balancer sandbox creation/deletion into libnetwork [moby/moby#35422](https://github.com/moby/moby/pull/35422)
* Only chown network files within container metadata [moby/moby#34224](https://github.com/moby/moby/pull/34224)
* Restore error type in FindNetwork [moby/moby#35634](https://github.com/moby/moby/pull/35634)
- Fix consumes MIME type for NetworkConnect [moby/moby#35542](https://github.com/moby/moby/pull/35542)
+ Added support for persisting Windows network driver specific options [moby/moby#35563](https://github.com/moby/moby/pull/35563)
- Fix timeout on netlink sockets and watchmiss leak [moby/moby#35677](https://github.com/moby/moby/pull/35677)
+ New daemon config for networking diagnosis [moby/moby#35677](https://github.com/moby/moby/pull/35677)
### Runtime
* Update to containerd v1.0.0 [moby/moby#35707](https://github.com/moby/moby/pull/35707)
* Have VFS graphdriver use accelerated in-kernel copy [moby/moby#35537](https://github.com/moby/moby/pull/35537)
* Introduce `workingdir` option for docker exec [moby/moby#35661](https://github.com/moby/moby/pull/35661)
* Bump Go to 1.9.2 [moby/moby#33892](https://github.com/moby/moby/pull/33892) [docker/cli#716](https://github.com/docker/cli/pull/716)
* `/dev` should not be readonly with `--readonly` flag [moby/moby#35344](https://github.com/moby/moby/pull/35344)
+ Add custom build-time Graphdrivers priority list [moby/moby#35522](https://github.com/moby/moby/pull/35522)
* LCOW: CLI changes to add platform flag - pull, run, create and build [docker/cli#474](https://github.com/docker/cli/pull/474)
* Fix width/height on Windoes for `docker exec` [moby/moby#35631](https://github.com/moby/moby/pull/35631)
* Detect overlay2 support on pre-4.0 kernels [moby/moby#35527](https://github.com/moby/moby/pull/35527)
* Devicemapper: remove container rootfs mountPath after umount [moby/moby#34573](https://github.com/moby/moby/pull/34573)
* Disallow overlay/overlay2 on top of NFS [moby/moby#35483](https://github.com/moby/moby/pull/35483)
- Fix potential panic during plugin set. [moby/moby#35632](https://github.com/moby/moby/pull/35632)
- Fix some issues with locking on the container [moby/moby#35501](https://github.com/moby/moby/pull/35501)
- Fixup some issues with plugin refcounting [moby/moby#35265](https://github.com/moby/moby/pull/35265)
+ Add missing lock in ProcessEvent [moby/moby#35516](https://github.com/moby/moby/pull/35516)
+ Add vfs quota support [moby/moby#35231](https://github.com/moby/moby/pull/35231)
* Skip empty directories on prior graphdriver detection [moby/moby#35528](https://github.com/moby/moby/pull/35528)
* Skip xfs quota tests when running in user namespace [moby/moby#35526](https://github.com/moby/moby/pull/35526)
+ Added SubSecondPrecision to config option. [moby/moby#35529](https://github.com/moby/moby/pull/35529)
* Update fsnotify to fix deadlock in removing watch [moby/moby#35453](https://github.com/moby/moby/pull/35453)
- Fix "duplicate mount point" when `--tmpfs /dev/shm` is used [moby/moby#35467](https://github.com/moby/moby/pull/35467)
- Fix honoring tmpfs-size for user `/dev/shm` mount [moby/moby#35316](https://github.com/moby/moby/pull/35316)
- Fix EBUSY errors under overlayfs and v4.13+ kernels [moby/moby#34948](https://github.com/moby/moby/pull/34948)
* Container: protect health monitor channel [moby/moby#35482](https://github.com/moby/moby/pull/35482)
* Container: protect the health status with mutex [moby/moby#35517](https://github.com/moby/moby/pull/35517)
* Container: update real-time resources [moby/moby#33731](https://github.com/moby/moby/pull/33731)
* Create labels when volume exists only remotely [moby/moby#34896](https://github.com/moby/moby/pull/34896)
* Fix leaking container/exec state [moby/moby#35484](https://github.com/moby/moby/pull/35484)
### Swarm Mode
+ Added support for swarm service isolation mode [moby/moby#34424](https://github.com/moby/moby/pull/34424)
### Packaging
+ Added Packaging for Fedora 27 [docker/docker-ce-packaging#59](https://github.com/docker/docker-ce-packaging/pull/59)
* Changed default versioning scheme to 0.0.0-dev unless specified for packaging [docker/docker-ce-packaging#67](https://github.com/docker/docker-ce-packaging/pull/67)

View File

@ -1 +1 @@
17.09.0-dev
17.12.0-ce-rc2

View File

@ -5,5 +5,5 @@ cli/command/stack/** @dnephin @vdemeester
cli/compose/** @dnephin @vdemeester
contrib/completion/bash/** @albers
contrib/completion/zsh/** @sdurrheimer
docs/** @mstanleyjones @vdemeester @thaJeztah
docs/** @mistyhacks @vdemeester @thaJeztah
scripts/** @dnephin

View File

@ -133,7 +133,7 @@
[people.misty]
Name = "Misty Stanley-Jones"
Email = "misty@docker.com"
GitHub = "mstanleyjones"
GitHub = "mistyhacks"
[people.mlaventure]
Name = "Kenfe-Mickaël Laventure"

View File

@ -1 +1 @@
17.11.0-dev
17.12.0-ce-rc2

View File

@ -12,12 +12,15 @@ import (
type fakeClient struct {
client.Client
inspectFunc func(string) (types.ContainerJSON, error)
execInspectFunc func(execID string) (types.ContainerExecInspect, error)
execCreateFunc func(container string, config types.ExecConfig) (types.IDResponse, error)
createContainerFunc func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
infoFunc func() (types.Info, error)
inspectFunc func(string) (types.ContainerJSON, error)
execInspectFunc func(execID string) (types.ContainerExecInspect, error)
execCreateFunc func(container string, config types.ExecConfig) (types.IDResponse, error)
createContainerFunc func(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (container.ContainerCreateCreatedBody, error)
imageCreateFunc func(parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)
infoFunc func() (types.Info, error)
containerStatPathFunc func(container, path string) (types.ContainerPathStat, error)
containerCopyFromFunc func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)
logFunc func(string, types.ContainerLogsOptions) (io.ReadCloser, error)
}
func (f *fakeClient) ContainerInspect(_ context.Context, containerID string) (types.ContainerJSON, error) {
@ -71,3 +74,24 @@ func (f *fakeClient) Info(_ context.Context) (types.Info, error) {
}
return types.Info{}, nil
}
func (f *fakeClient) ContainerStatPath(_ context.Context, container, path string) (types.ContainerPathStat, error) {
if f.containerStatPathFunc != nil {
return f.containerStatPathFunc(container, path)
}
return types.ContainerPathStat{}, nil
}
func (f *fakeClient) CopyFromContainer(_ context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
if f.containerCopyFromFunc != nil {
return f.containerCopyFromFunc(container, srcPath)
}
return nil, types.ContainerPathStat{}, nil
}
func (f *fakeClient) ContainerLogs(_ context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) {
if f.logFunc != nil {
return f.logFunc(container, options)
}
return nil, nil
}

View File

@ -26,13 +26,17 @@ type copyOptions struct {
type copyDirection int
const (
fromContainer copyDirection = (1 << iota)
fromContainer copyDirection = 1 << iota
toContainer
acrossContainers = fromContainer | toContainer
)
type cpConfig struct {
followLink bool
copyUIDGID bool
sourcePath string
destPath string
container string
}
// NewCopyCommand creates a new `docker cp` command
@ -65,58 +69,57 @@ func NewCopyCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.BoolVarP(&opts.followLink, "follow-link", "L", false, "Always follow symbol link in SRC_PATH")
flags.BoolVarP(&opts.copyUIDGID, "archive", "a", false, "Archive mode (copy all uid/gid information)")
return cmd
}
func runCopy(dockerCli command.Cli, opts copyOptions) error {
srcContainer, srcPath := splitCpArg(opts.source)
dstContainer, dstPath := splitCpArg(opts.destination)
destContainer, destPath := splitCpArg(opts.destination)
copyConfig := cpConfig{
followLink: opts.followLink,
copyUIDGID: opts.copyUIDGID,
sourcePath: srcPath,
destPath: destPath,
}
var direction copyDirection
if srcContainer != "" {
direction |= fromContainer
copyConfig.container = srcContainer
}
if dstContainer != "" {
if destContainer != "" {
direction |= toContainer
}
cpParam := &cpConfig{
followLink: opts.followLink,
copyConfig.container = destContainer
}
ctx := context.Background()
switch direction {
case fromContainer:
return copyFromContainer(ctx, dockerCli, srcContainer, srcPath, dstPath, cpParam)
return copyFromContainer(ctx, dockerCli, copyConfig)
case toContainer:
return copyToContainer(ctx, dockerCli, srcPath, dstContainer, dstPath, cpParam, opts.copyUIDGID)
return copyToContainer(ctx, dockerCli, copyConfig)
case acrossContainers:
// Copying between containers isn't supported.
return errors.New("copying between containers is not supported")
default:
// User didn't specify any container.
return errors.New("must specify at least one container source")
}
}
func statContainerPath(ctx context.Context, dockerCli command.Cli, containerName, path string) (types.ContainerPathStat, error) {
return dockerCli.Client().ContainerStatPath(ctx, containerName, path)
}
func resolveLocalPath(localPath string) (absPath string, err error) {
if absPath, err = filepath.Abs(localPath); err != nil {
return
}
return archive.PreserveTrailingDotOrSeparator(absPath, localPath, filepath.Separator), nil
}
func copyFromContainer(ctx context.Context, dockerCli command.Cli, srcContainer, srcPath, dstPath string, cpParam *cpConfig) (err error) {
func copyFromContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpConfig) (err error) {
dstPath := copyConfig.destPath
srcPath := copyConfig.sourcePath
if dstPath != "-" {
// Get an absolute destination path.
dstPath, err = resolveLocalPath(dstPath)
@ -125,10 +128,11 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, srcContainer,
}
}
client := dockerCli.Client()
// if client requests to follow symbol link, then must decide target file to be copied
var rebaseName string
if cpParam.followLink {
srcStat, err := statContainerPath(ctx, dockerCli, srcContainer, srcPath)
if copyConfig.followLink {
srcStat, err := client.ContainerStatPath(ctx, copyConfig.container, srcPath)
// If the destination is a symbolic link, we should follow it.
if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
@ -145,20 +149,17 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, srcContainer,
}
content, stat, err := dockerCli.Client().CopyFromContainer(ctx, srcContainer, srcPath)
content, stat, err := client.CopyFromContainer(ctx, copyConfig.container, srcPath)
if err != nil {
return err
}
defer content.Close()
if dstPath == "-" {
// Send the response to STDOUT.
_, err = io.Copy(os.Stdout, content)
_, err = io.Copy(dockerCli.Out(), content)
return err
}
// Prepare source copy info.
srcInfo := archive.CopyInfo{
Path: srcPath,
Exists: true,
@ -171,13 +172,17 @@ func copyFromContainer(ctx context.Context, dockerCli command.Cli, srcContainer,
_, srcBase := archive.SplitPathDirEntry(srcInfo.Path)
preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName)
}
// See comments in the implementation of `archive.CopyTo` for exactly what
// goes into deciding how and whether the source archive needs to be
// altered for the correct copy behavior.
return archive.CopyTo(preArchive, srcInfo, dstPath)
}
func copyToContainer(ctx context.Context, dockerCli command.Cli, srcPath, dstContainer, dstPath string, cpParam *cpConfig, copyUIDGID bool) (err error) {
// In order to get the copy behavior right, we need to know information
// about both the source and destination. The API is a simple tar
// archive/extract API but we can use the stat info header about the
// destination to be more informed about exactly what the destination is.
func copyToContainer(ctx context.Context, dockerCli command.Cli, copyConfig cpConfig) (err error) {
srcPath := copyConfig.sourcePath
dstPath := copyConfig.destPath
if srcPath != "-" {
// Get an absolute source path.
srcPath, err = resolveLocalPath(srcPath)
@ -186,14 +191,10 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, srcPath, dstCon
}
}
// In order to get the copy behavior right, we need to know information
// about both the source and destination. The API is a simple tar
// archive/extract API but we can use the stat info header about the
// destination to be more informed about exactly what the destination is.
client := dockerCli.Client()
// Prepare destination copy info by stat-ing the container path.
dstInfo := archive.CopyInfo{Path: dstPath}
dstStat, err := statContainerPath(ctx, dockerCli, dstContainer, dstPath)
dstStat, err := client.ContainerStatPath(ctx, copyConfig.container, dstPath)
// If the destination is a symbolic link, we should evaluate it.
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
@ -205,7 +206,7 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, srcPath, dstCon
}
dstInfo.Path = linkTarget
dstStat, err = statContainerPath(ctx, dockerCli, dstContainer, linkTarget)
dstStat, err = client.ContainerStatPath(ctx, copyConfig.container, linkTarget)
}
// Ignore any error and assume that the parent directory of the destination
@ -224,15 +225,14 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, srcPath, dstCon
)
if srcPath == "-" {
// Use STDIN.
content = os.Stdin
resolvedDstPath = dstInfo.Path
if !dstInfo.IsDir {
return errors.Errorf("destination \"%s:%s\" must be a directory", dstContainer, dstPath)
return errors.Errorf("destination \"%s:%s\" must be a directory", copyConfig.container, dstPath)
}
} else {
// Prepare source copy info.
srcInfo, err := archive.CopyInfoSourcePath(srcPath, cpParam.followLink)
srcInfo, err := archive.CopyInfoSourcePath(srcPath, copyConfig.followLink)
if err != nil {
return err
}
@ -267,10 +267,9 @@ func copyToContainer(ctx context.Context, dockerCli command.Cli, srcPath, dstCon
options := types.CopyToContainerOptions{
AllowOverwriteDirWithFile: false,
CopyUIDGID: copyUIDGID,
CopyUIDGID: copyConfig.copyUIDGID,
}
return dockerCli.Client().CopyToContainer(ctx, dstContainer, resolvedDstPath, content, options)
return client.CopyToContainer(ctx, copyConfig.container, resolvedDstPath, content, options)
}
// We use `:` as a delimiter between CONTAINER and PATH, but `:` could also be

View File

@ -0,0 +1,160 @@
package container
import (
"io"
"io/ioutil"
"runtime"
"strings"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/archive"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRunCopyWithInvalidArguments(t *testing.T) {
var testcases = []struct {
doc string
options copyOptions
expectedErr string
}{
{
doc: "copy between container",
options: copyOptions{
source: "first:/path",
destination: "second:/path",
},
expectedErr: "copying between containers is not supported",
},
{
doc: "copy without a container",
options: copyOptions{
source: "./source",
destination: "./dest",
},
expectedErr: "must specify at least one container source",
},
}
for _, testcase := range testcases {
t.Run(testcase.doc, func(t *testing.T) {
err := runCopy(test.NewFakeCli(nil), testcase.options)
assert.EqualError(t, err, testcase.expectedErr)
})
}
}
func TestRunCopyFromContainerToStdout(t *testing.T) {
tarContent := "the tar content"
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
return ioutil.NopCloser(strings.NewReader(tarContent)), types.ContainerPathStat{}, nil
},
}
options := copyOptions{source: "container:/path", destination: "-"}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
require.NoError(t, err)
assert.Equal(t, tarContent, cli.OutBuffer().String())
assert.Equal(t, "", cli.ErrBuffer().String())
}
func TestRunCopyFromContainerToFilesystem(t *testing.T) {
destDir := fs.NewDir(t, "cp-test",
fs.WithFile("file1", "content\n"))
defer destDir.Remove()
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err
},
}
options := copyOptions{source: "container:/path", destination: destDir.Path()}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
require.NoError(t, err)
assert.Equal(t, "", cli.OutBuffer().String())
assert.Equal(t, "", cli.ErrBuffer().String())
content, err := ioutil.ReadFile(destDir.Join("file1"))
require.NoError(t, err)
assert.Equal(t, "content\n", string(content))
}
func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.T) {
destDir := fs.NewDir(t, "cp-test",
fs.WithFile("file1", "content\n"))
defer destDir.Remove()
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err
},
}
options := copyOptions{
source: "container:/path",
destination: destDir.Join("missing", "foo"),
}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
testutil.ErrorContains(t, err, destDir.Join("missing"))
}
func TestSplitCpArg(t *testing.T) {
var testcases = []struct {
doc string
path string
os string
expectedContainer string
expectedPath string
}{
{
doc: "absolute path with colon",
os: "linux",
path: "/abs/path:withcolon",
expectedPath: "/abs/path:withcolon",
},
{
doc: "relative path with colon",
path: "./relative:path",
expectedPath: "./relative:path",
},
{
doc: "absolute path with drive",
os: "windows",
path: `d:\abs\path`,
expectedPath: `d:\abs\path`,
},
{
doc: "no separator",
path: "relative/path",
expectedPath: "relative/path",
},
{
doc: "with separator",
path: "container:/opt/foo",
expectedPath: "/opt/foo",
expectedContainer: "container",
},
}
for _, testcase := range testcases {
t.Run(testcase.doc, func(t *testing.T) {
skip.IfCondition(t, testcase.os != "" && testcase.os != runtime.GOOS)
container, path := splitCpArg(testcase.path)
assert.Equal(t, testcase.expectedContainer, container)
assert.Equal(t, testcase.expectedPath, path)
})
}
}

View File

@ -21,7 +21,8 @@ import (
)
type createOptions struct {
name string
name string
platform string
}
// NewCreateCommand creates a new cobra.Command for `docker create`
@ -51,6 +52,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
// with hostname
flags.Bool("help", false, "Print usage")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
copts = addFlags(flags)
return cmd
@ -62,7 +64,7 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name)
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name, opts.platform)
if err != nil {
return err
}
@ -70,7 +72,7 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
return nil
}
func pullImage(ctx context.Context, dockerCli command.Cli, image string, out io.Writer) error {
func pullImage(ctx context.Context, dockerCli command.Cli, image string, platform string, out io.Writer) error {
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return err
@ -90,6 +92,7 @@ func pullImage(ctx context.Context, dockerCli command.Cli, image string, out io.
options := types.ImageCreateOptions{
RegistryAuth: encodedAuth,
Platform: platform,
}
responseBody, err := dockerCli.Client().ImageCreate(ctx, image, options)
@ -155,7 +158,7 @@ func newCIDFile(path string) (*cidFile, error) {
return &cidFile{path: path, file: f}, nil
}
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string) (*container.ContainerCreateCreatedBody, error) {
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string, platform string) (*container.ContainerCreateCreatedBody, error) {
config := containerConfig.Config
hostConfig := containerConfig.HostConfig
networkingConfig := containerConfig.NetworkingConfig
@ -198,7 +201,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
// we don't want to write to stdout anything apart from container.ID
if err := pullImage(ctx, dockerCli, config.Image, stderr); err != nil {
if err := pullImage(ctx, dockerCli, config.Image, platform, stderr); err != nil {
return nil, err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {

View File

@ -5,6 +5,7 @@ import (
"io"
"io/ioutil"
"os"
"runtime"
"strings"
"testing"
@ -106,7 +107,7 @@ func TestCreateContainerPullsImageIfMissing(t *testing.T) {
},
HostConfig: &container.HostConfig{},
}
body, err := createContainer(context.Background(), cli, config, "name")
body, err := createContainer(context.Background(), cli, config, "name", runtime.GOOS)
require.NoError(t, err)
expected := container.ContainerCreateCreatedBody{ID: containerID}
assert.Equal(t, expected, *body)

View File

@ -24,6 +24,7 @@ type execOptions struct {
user string
privileged bool
env opts.ListOpts
workdir string
container string
command []string
}
@ -58,6 +59,8 @@ func NewExecCommand(dockerCli command.Cli) *cobra.Command {
flags.BoolVarP(&options.privileged, "privileged", "", false, "Give extended privileges to the command")
flags.VarP(&options.env, "env", "e", "Set environment variables")
flags.SetAnnotation("env", "version", []string{"1.25"})
flags.StringVarP(&options.workdir, "workdir", "w", "", "Working directory inside the container")
flags.SetAnnotation("workdir", "version", []string{"1.35"})
return cmd
}
@ -190,6 +193,7 @@ func parseExec(opts execOptions, configFile *configfile.ConfigFile) *types.ExecC
Cmd: opts.command,
Detach: opts.detach,
Env: opts.env.GetAll(),
WorkingDir: opts.workdir,
}
// If -d is not set, attach to everything by default

View File

@ -14,6 +14,7 @@ import (
type logsOptions struct {
follow bool
since string
until string
timestamps bool
details bool
tail string
@ -38,6 +39,8 @@ func NewLogsCommand(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output")
flags.StringVar(&opts.since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)")
flags.StringVar(&opts.until, "until", "", "Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)")
flags.SetAnnotation("until", "version", []string{"1.35"})
flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps")
flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs")
@ -51,6 +54,7 @@ func runLogs(dockerCli command.Cli, opts *logsOptions) error {
ShowStdout: true,
ShowStderr: true,
Since: opts.since,
Until: opts.until,
Timestamps: opts.timestamps,
Follow: opts.follow,
Tail: opts.tail,

View File

@ -0,0 +1,62 @@
package container
import (
"io"
"io/ioutil"
"strings"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/stretchr/testify/assert"
)
var logFn = func(expectedOut string) func(string, types.ContainerLogsOptions) (io.ReadCloser, error) {
return func(container string, opts types.ContainerLogsOptions) (io.ReadCloser, error) {
return ioutil.NopCloser(strings.NewReader(expectedOut)), nil
}
}
func TestRunLogs(t *testing.T) {
inspectFn := func(containerID string) (types.ContainerJSON, error) {
return types.ContainerJSON{
Config: &container.Config{Tty: true},
ContainerJSONBase: &types.ContainerJSONBase{State: &types.ContainerState{Running: false}},
}, nil
}
var testcases = []struct {
doc string
options *logsOptions
client fakeClient
expectedError string
expectedOut string
expectedErr string
}{
{
doc: "successful logs",
expectedOut: "foo",
options: &logsOptions{},
client: fakeClient{logFunc: logFn("foo"), inspectFunc: inspectFn},
},
}
for _, testcase := range testcases {
t.Run(testcase.doc, func(t *testing.T) {
cli := test.NewFakeCli(&testcase.client)
err := runLogs(cli, testcase.options)
if testcase.expectedError != "" {
testutil.ErrorContains(t, err, testcase.expectedError)
} else {
if !assert.NoError(t, err) {
return
}
}
assert.Equal(t, testcase.expectedOut, cli.OutBuffer().String())
assert.Equal(t, testcase.expectedErr, cli.ErrBuffer().String())
})
}
}

View File

@ -29,6 +29,7 @@ type runOptions struct {
sigProxy bool
name string
detachKeys string
platform string
}
// NewRunCommand create a new `docker run` command
@ -62,6 +63,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
// with hostname
flags.Bool("help", false, "Print usage")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
copts = addFlags(flags)
return cmd
@ -160,7 +162,7 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
ctx, cancelFun := context.WithCancel(context.Background())
createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name)
createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name, opts.platform)
if err != nil {
reportError(stderr, cmdPath, err.Error(), true)
return runStartContainerErr(err)

View File

@ -64,6 +64,7 @@ type buildOptions struct {
target string
imageIDFile string
stream bool
platform string
}
// dockerfileFromStdin returns true when the user specified that the Dockerfile
@ -135,6 +136,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
command.AddTrustVerificationFlags(flags)
command.AddPlatformFlag(flags, &options.platform)
flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
flags.SetAnnotation("squash", "experimental", nil)
@ -305,8 +307,8 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
progressOutput = &lastProgressOutput{output: progressOutput}
}
// if up to this point nothing has set the context then we must have have
// another way for sending it(streaming) and set the context to the Dockerfile
// if up to this point nothing has set the context then we must have another
// way for sending it(streaming) and set the context to the Dockerfile
if dockerfileCtx != nil && buildCtx == nil {
buildCtx = dockerfileCtx
}
@ -374,6 +376,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
ExtraHosts: options.extraHosts.GetAll(),
Target: options.target,
RemoteContext: remote,
Platform: options.platform,
}
if s != nil {

View File

@ -14,8 +14,9 @@ import (
)
type pullOptions struct {
remote string
all bool
remote string
all bool
platform string
}
// NewPullCommand creates a new `docker pull` command
@ -35,6 +36,8 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
return cmd
@ -63,9 +66,9 @@ func runPull(cli command.Cli, opts pullOptions) error {
// Check if reference has a digest
_, isCanonical := distributionRef.(reference.Canonical)
if command.IsTrusted() && !isCanonical {
err = trustedPull(ctx, cli, imgRefAndAuth)
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
} else {
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all)
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
}
if err != nil {
if strings.Contains(err.Error(), "when fetching 'plugin'") {

View File

@ -9,6 +9,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types"
apiclient "github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@ -56,9 +57,13 @@ func runRemove(dockerCli command.Cli, opts removeOptions, images []string) error
}
var errs []string
var fatalErr = false
for _, img := range images {
dels, err := client.ImageRemove(ctx, img, options)
if err != nil {
if !apiclient.IsErrNotFound(err) {
fatalErr = true
}
errs = append(errs, err.Error())
} else {
for _, del := range dels {
@ -73,7 +78,7 @@ func runRemove(dockerCli command.Cli, opts removeOptions, images []string) error
if len(errs) > 0 {
msg := strings.Join(errs, "\n")
if !opts.force {
if !opts.force || fatalErr {
return errors.New(msg)
}
fmt.Fprintf(dockerCli.Err(), msg)

View File

@ -13,6 +13,18 @@ import (
"github.com/stretchr/testify/assert"
)
type notFound struct {
imageID string
}
func (n notFound) Error() string {
return fmt.Sprintf("Error: No such image: %s", n.imageID)
}
func (n notFound) NotFound() bool {
return true
}
func TestNewRemoveCommandAlias(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
assert.True(t, cmd.HasAlias("rmi"))
@ -31,6 +43,15 @@ func TestNewRemoveCommandErrors(t *testing.T) {
name: "wrong args",
expectedError: "requires at least 1 argument.",
},
{
name: "ImageRemove fail with force option",
args: []string{"-f", "image1"},
expectedError: "error removing image",
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
},
},
{
name: "ImageRemove fail",
args: []string{"arg1"},
@ -43,12 +64,14 @@ func TestNewRemoveCommandErrors(t *testing.T) {
},
}
for _, tc := range testCases {
cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{
imageRemoveFunc: tc.imageRemoveFunc,
}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
t.Run(tc.name, func(t *testing.T) {
cmd := NewRemoveCommand(test.NewFakeCli(&fakeClient{
imageRemoveFunc: tc.imageRemoveFunc,
}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
}
}
@ -57,7 +80,7 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
name string
args []string
imageRemoveFunc func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error)
expectedErrMsg string
expectedStderr string
}{
{
name: "Image Deleted",
@ -68,14 +91,16 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
},
},
{
name: "Image Deleted with force option",
name: "Image not found with force option",
args: []string{"-f", "image1"},
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
assert.Equal(t, true, options.Force)
return []types.ImageDeleteResponseItem{}, notFound{"image1"}
},
expectedErrMsg: "error removing image",
expectedStderr: "Error: No such image: image1",
},
{
name: "Image Untagged",
args: []string{"image1"},
@ -96,14 +121,14 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc})
cmd := NewRemoveCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
if tc.expectedErrMsg != "" {
assert.Equal(t, tc.expectedErrMsg, cli.ErrBuffer().String())
}
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("remove-command-success.%s.golden", tc.name))
t.Run(tc.name, func(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{imageRemoveFunc: tc.imageRemoveFunc})
cmd := NewRemoveCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.Equal(t, tc.expectedStderr, cli.ErrBuffer().String())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("remove-command-success.%s.golden", tc.name))
})
}
}

View File

@ -180,7 +180,7 @@ func imagePushPrivileged(ctx context.Context, cli command.Cli, authConfig types.
}
// trustedPull handles content trust pulling of an image
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) error {
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, platform string) error {
refs, err := getTrustedPullTargets(cli, imgRefAndAuth)
if err != nil {
return err
@ -202,7 +202,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
if err != nil {
return err
}
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false); err != nil {
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false, platform); err != nil {
return err
}
@ -268,7 +268,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
}
// imagePullPrivileged pulls the image and displays it to the output
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, all bool) error {
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, all bool, platform string) error {
ref := reference.FamiliarString(imgRefAndAuth.Reference())
encodedAuth, err := command.EncodeAuthToBase64(*imgRefAndAuth.AuthConfig())
@ -280,8 +280,8 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
RegistryAuth: encodedAuth,
PrivilegeFunc: requestPrivilege,
All: all,
Platform: platform,
}
responseBody, err := cli.Client().ImagePull(ctx, ref, options)
if err != nil {
return err

View File

@ -5,6 +5,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
cliopts "github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/versions"
"github.com/spf13/cobra"
@ -58,6 +59,9 @@ func newCreateCommand(dockerCli command.Cli) *cobra.Command {
flags.Var(&opts.hosts, flagHost, "Set one or more custom host-to-IP mappings (host:ip)")
flags.SetAnnotation(flagHost, "version", []string{"1.25"})
flags.Var(cliopts.NewListOptsRef(&opts.resources.resGenericResources, ValidateSingleGenericResource), "generic-resource", "User defined resources")
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
flags.SetInterspersed(false)
return cmd
}

View File

@ -0,0 +1,105 @@
package service
import (
"fmt"
"strings"
"github.com/pkg/errors"
"github.com/docker/docker/api/types/swarm"
swarmapi "github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/api/genericresource"
)
// GenericResource is a concept that a user can use to advertise user-defined
// resources on a node and thus better place services based on these resources.
// E.g: NVIDIA GPUs, Intel FPGAs, ...
// See https://github.com/docker/swarmkit/blob/master/design/generic_resources.md
// ValidateSingleGenericResource validates that a single entry in the
// generic resource list is valid.
// i.e 'GPU=UID1' is valid however 'GPU:UID1' or 'UID1' isn't
func ValidateSingleGenericResource(val string) (string, error) {
if strings.Count(val, "=") < 1 {
return "", fmt.Errorf("invalid generic-resource format `%s` expected `name=value`", val)
}
return val, nil
}
// ParseGenericResources parses an array of Generic resourceResources
// Requesting Named Generic Resources for a service is not supported this
// is filtered here.
func ParseGenericResources(value []string) ([]swarm.GenericResource, error) {
if len(value) == 0 {
return nil, nil
}
resources, err := genericresource.Parse(value)
if err != nil {
return nil, errors.Wrapf(err, "invalid generic resource specification")
}
swarmResources := genericResourcesFromGRPC(resources)
for _, res := range swarmResources {
if res.NamedResourceSpec != nil {
return nil, fmt.Errorf("invalid generic-resource request `%s=%s`, Named Generic Resources is not supported for service create or update", res.NamedResourceSpec.Kind, res.NamedResourceSpec.Value)
}
}
return swarmResources, nil
}
// genericResourcesFromGRPC converts a GRPC GenericResource to a GenericResource
func genericResourcesFromGRPC(genericRes []*swarmapi.GenericResource) []swarm.GenericResource {
var generic []swarm.GenericResource
for _, res := range genericRes {
var current swarm.GenericResource
switch r := res.Resource.(type) {
case *swarmapi.GenericResource_DiscreteResourceSpec:
current.DiscreteResourceSpec = &swarm.DiscreteGenericResource{
Kind: r.DiscreteResourceSpec.Kind,
Value: r.DiscreteResourceSpec.Value,
}
case *swarmapi.GenericResource_NamedResourceSpec:
current.NamedResourceSpec = &swarm.NamedGenericResource{
Kind: r.NamedResourceSpec.Kind,
Value: r.NamedResourceSpec.Value,
}
}
generic = append(generic, current)
}
return generic
}
func buildGenericResourceMap(genericRes []swarm.GenericResource) (map[string]swarm.GenericResource, error) {
m := make(map[string]swarm.GenericResource)
for _, res := range genericRes {
if res.DiscreteResourceSpec == nil {
return nil, fmt.Errorf("invalid generic-resource `%+v` for service task", res)
}
_, ok := m[res.DiscreteResourceSpec.Kind]
if ok {
return nil, fmt.Errorf("duplicate generic-resource `%+v` for service task", res.DiscreteResourceSpec.Kind)
}
m[res.DiscreteResourceSpec.Kind] = res
}
return m, nil
}
func buildGenericResourceList(genericRes map[string]swarm.GenericResource) []swarm.GenericResource {
var l []swarm.GenericResource
for _, res := range genericRes {
l = append(l, res)
}
return l
}

View File

@ -0,0 +1,22 @@
package service
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestValidateSingleGenericResource(t *testing.T) {
incorrect := []string{"foo", "fooo-bar"}
correct := []string{"foo=bar", "bar=1", "foo=barbar"}
for _, v := range incorrect {
_, err := ValidateSingleGenericResource(v)
assert.Error(t, err)
}
for _, v := range correct {
_, err := ValidateSingleGenericResource(v)
assert.NoError(t, err)
}
}

View File

@ -222,23 +222,30 @@ func (opts updateOptions) rollbackConfig(flags *pflag.FlagSet) *swarm.UpdateConf
}
type resourceOptions struct {
limitCPU opts.NanoCPUs
limitMemBytes opts.MemBytes
resCPU opts.NanoCPUs
resMemBytes opts.MemBytes
limitCPU opts.NanoCPUs
limitMemBytes opts.MemBytes
resCPU opts.NanoCPUs
resMemBytes opts.MemBytes
resGenericResources []string
}
func (r *resourceOptions) ToResourceRequirements() *swarm.ResourceRequirements {
func (r *resourceOptions) ToResourceRequirements() (*swarm.ResourceRequirements, error) {
generic, err := ParseGenericResources(r.resGenericResources)
if err != nil {
return nil, err
}
return &swarm.ResourceRequirements{
Limits: &swarm.Resources{
NanoCPUs: r.limitCPU.Value(),
MemoryBytes: r.limitMemBytes.Value(),
},
Reservations: &swarm.Resources{
NanoCPUs: r.resCPU.Value(),
MemoryBytes: r.resMemBytes.Value(),
NanoCPUs: r.resCPU.Value(),
MemoryBytes: r.resMemBytes.Value(),
GenericResources: generic,
},
}
}, nil
}
type restartPolicyOptions struct {
@ -505,6 +512,8 @@ type serviceOptions struct {
healthcheck healthCheckOptions
secrets opts.SecretOpt
configs opts.ConfigOpt
isolation string
}
func newServiceOptions() *serviceOptions {
@ -586,6 +595,11 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
return service, err
}
resources, err := options.resources.ToResourceRequirements()
if err != nil {
return service, err
}
service = swarm.ServiceSpec{
Annotations: swarm.Annotations{
Name: options.name,
@ -614,9 +628,10 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
Hosts: convertExtraHostsToSwarmHosts(options.hosts.GetAll()),
StopGracePeriod: options.ToStopGracePeriod(flags),
Healthcheck: healthConfig,
Isolation: container.Isolation(options.isolation),
},
Networks: networks,
Resources: options.resources.ToResourceRequirements(),
Resources: resources,
RestartPolicy: options.restartPolicy.ToRestartPolicy(flags),
Placement: &swarm.Placement{
Constraints: options.constraints.GetAll(),
@ -784,6 +799,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
flags.StringVar(&opts.stopSignal, flagStopSignal, "", "Signal to stop the container")
flags.SetAnnotation(flagStopSignal, "version", []string{"1.28"})
flags.StringVar(&opts.isolation, flagIsolation, "", "Service container isolation mode")
flags.SetAnnotation(flagIsolation, "version", []string{"1.35"})
}
const (
@ -813,6 +830,8 @@ const (
flagEnvFile = "env-file"
flagEnvRemove = "env-rm"
flagEnvAdd = "env-add"
flagGenericResourcesRemove = "generic-resource-rm"
flagGenericResourcesAdd = "generic-resource-add"
flagGroup = "group"
flagGroupAdd = "group-add"
flagGroupRemove = "group-rm"
@ -879,4 +898,5 @@ const (
flagConfig = "config"
flagConfigAdd = "config-add"
flagConfigRemove = "config-rm"
flagIsolation = "isolation"
)

View File

@ -85,3 +85,41 @@ func TestHealthCheckOptionsToHealthConfigConflict(t *testing.T) {
_, err := opt.toHealthConfig()
assert.EqualError(t, err, "--no-healthcheck conflicts with --health-* options")
}
func TestResourceOptionsToResourceRequirements(t *testing.T) {
incorrectOptions := []resourceOptions{
{
resGenericResources: []string{"foo=bar", "foo=1"},
},
{
resGenericResources: []string{"foo=bar", "foo=baz"},
},
{
resGenericResources: []string{"foo=bar"},
},
{
resGenericResources: []string{"foo=1", "foo=2"},
},
}
for _, opt := range incorrectOptions {
_, err := opt.ToResourceRequirements()
assert.Error(t, err)
}
correctOptions := []resourceOptions{
{
resGenericResources: []string{"foo=1"},
},
{
resGenericResources: []string{"foo=1", "bar=2"},
},
}
for _, opt := range correctOptions {
r, err := opt.ToResourceRequirements()
assert.NoError(t, err)
assert.Len(t, r.Reservations.GenericResources, len(opt.resGenericResources))
}
}

View File

@ -95,6 +95,12 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
flags.Var(&options.hosts, flagHostAdd, "Add a custom host-to-IP mapping (host:ip)")
flags.SetAnnotation(flagHostAdd, "version", []string{"1.25"})
// Add needs parsing, Remove only needs the key
flags.Var(newListOptsVar(), flagGenericResourcesRemove, "Remove a Generic resource")
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
flags.Var(newListOptsVarWithValidator(ValidateSingleGenericResource), flagGenericResourcesAdd, "Add a Generic resource")
flags.SetAnnotation(flagHostAdd, "version", []string{"1.32"})
return cmd
}
@ -102,6 +108,10 @@ func newListOptsVar() *opts.ListOpts {
return opts.NewListOptsRef(&[]string{}, nil)
}
func newListOptsVarWithValidator(validator opts.ValidatorFctType) *opts.ListOpts {
return opts.NewListOptsRef(&[]string{}, validator)
}
// nolint: gocyclo
func runUpdate(dockerCli command.Cli, flags *pflag.FlagSet, options *serviceOptions, serviceID string) error {
apiClient := dockerCli.Client()
@ -269,6 +279,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
}
}
updateIsolation := func(flag string, field *container.Isolation) error {
if flags.Changed(flag) {
val, _ := flags.GetString(flag)
*field = container.Isolation(val)
}
return nil
}
cspec := spec.TaskTemplate.ContainerSpec
task := &spec.TaskTemplate
@ -288,6 +306,9 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
updateString(flagWorkdir, &cspec.Dir)
updateString(flagUser, &cspec.User)
updateString(flagHostname, &cspec.Hostname)
if err := updateIsolation(flagIsolation, &cspec.Isolation); err != nil {
return err
}
if err := updateMounts(flags, &cspec.Mounts); err != nil {
return err
}
@ -303,6 +324,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
updateInt64Value(flagReserveMemory, &task.Resources.Reservations.MemoryBytes)
}
if err := addGenericResources(flags, task); err != nil {
return err
}
if err := removeGenericResources(flags, task); err != nil {
return err
}
updateDurationOpt(flagStopGracePeriod, &cspec.StopGracePeriod)
if anyChanged(flags, flagRestartCondition, flagRestartDelay, flagRestartMaxAttempts, flagRestartWindow) {
@ -459,6 +488,72 @@ func anyChanged(flags *pflag.FlagSet, fields ...string) bool {
return false
}
func addGenericResources(flags *pflag.FlagSet, spec *swarm.TaskSpec) error {
if !flags.Changed(flagGenericResourcesAdd) {
return nil
}
if spec.Resources == nil {
spec.Resources = &swarm.ResourceRequirements{}
}
if spec.Resources.Reservations == nil {
spec.Resources.Reservations = &swarm.Resources{}
}
values := flags.Lookup(flagGenericResourcesAdd).Value.(*opts.ListOpts).GetAll()
generic, err := ParseGenericResources(values)
if err != nil {
return err
}
m, err := buildGenericResourceMap(spec.Resources.Reservations.GenericResources)
if err != nil {
return err
}
for _, toAddRes := range generic {
m[toAddRes.DiscreteResourceSpec.Kind] = toAddRes
}
spec.Resources.Reservations.GenericResources = buildGenericResourceList(m)
return nil
}
func removeGenericResources(flags *pflag.FlagSet, spec *swarm.TaskSpec) error {
// Can only be Discrete Resources
if !flags.Changed(flagGenericResourcesRemove) {
return nil
}
if spec.Resources == nil {
spec.Resources = &swarm.ResourceRequirements{}
}
if spec.Resources.Reservations == nil {
spec.Resources.Reservations = &swarm.Resources{}
}
values := flags.Lookup(flagGenericResourcesRemove).Value.(*opts.ListOpts).GetAll()
m, err := buildGenericResourceMap(spec.Resources.Reservations.GenericResources)
if err != nil {
return err
}
for _, toRemoveRes := range values {
if _, ok := m[toRemoveRes]; !ok {
return fmt.Errorf("could not find generic-resource `%s` to remove it", toRemoveRes)
}
delete(m, toRemoveRes)
}
spec.Resources.Reservations.GenericResources = buildGenericResourceList(m)
return nil
}
func updatePlacementConstraints(flags *pflag.FlagSet, placement *swarm.Placement) {
if flags.Changed(flagConstraintAdd) {
values := flags.Lookup(flagConstraintAdd).Value.(*opts.ListOpts).GetAll()

View File

@ -518,3 +518,71 @@ func TestUpdateStopSignal(t *testing.T) {
updateService(nil, nil, flags, spec)
assert.Equal(t, "SIGWINCH", cspec.StopSignal)
}
func TestUpdateIsolationValid(t *testing.T) {
flags := newUpdateCommand(nil).Flags()
err := flags.Set("isolation", "process")
require.NoError(t, err)
spec := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
ContainerSpec: &swarm.ContainerSpec{},
},
}
err = updateService(context.Background(), nil, flags, &spec)
require.NoError(t, err)
assert.Equal(t, container.IsolationProcess, spec.TaskTemplate.ContainerSpec.Isolation)
}
func TestUpdateIsolationInvalid(t *testing.T) {
// validation depends on daemon os / version so validation should be done on the daemon side
flags := newUpdateCommand(nil).Flags()
err := flags.Set("isolation", "test")
require.NoError(t, err)
spec := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
ContainerSpec: &swarm.ContainerSpec{},
},
}
err = updateService(context.Background(), nil, flags, &spec)
require.NoError(t, err)
assert.Equal(t, container.Isolation("test"), spec.TaskTemplate.ContainerSpec.Isolation)
}
func TestAddGenericResources(t *testing.T) {
task := &swarm.TaskSpec{}
flags := newUpdateCommand(nil).Flags()
assert.Nil(t, addGenericResources(flags, task))
flags.Set(flagGenericResourcesAdd, "foo=1")
assert.NoError(t, addGenericResources(flags, task))
assert.Len(t, task.Resources.Reservations.GenericResources, 1)
// Checks that foo isn't added a 2nd time
flags = newUpdateCommand(nil).Flags()
flags.Set(flagGenericResourcesAdd, "bar=1")
assert.NoError(t, addGenericResources(flags, task))
assert.Len(t, task.Resources.Reservations.GenericResources, 2)
}
func TestRemoveGenericResources(t *testing.T) {
task := &swarm.TaskSpec{}
flags := newUpdateCommand(nil).Flags()
assert.Nil(t, removeGenericResources(flags, task))
flags.Set(flagGenericResourcesRemove, "foo")
assert.Error(t, removeGenericResources(flags, task))
flags = newUpdateCommand(nil).Flags()
flags.Set(flagGenericResourcesAdd, "foo=1")
addGenericResources(flags, task)
flags = newUpdateCommand(nil).Flags()
flags.Set(flagGenericResourcesAdd, "bar=1")
addGenericResources(flags, task)
flags = newUpdateCommand(nil).Flags()
flags.Set(flagGenericResourcesRemove, "foo")
assert.NoError(t, removeGenericResources(flags, task))
assert.Len(t, task.Resources.Reservations.GenericResources, 1)
}

View File

@ -1,34 +1,52 @@
package system
import (
"fmt"
"runtime"
"sort"
"text/template"
"time"
"golang.org/x/net/context"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/templates"
"github.com/docker/docker/api/types"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
var versionTemplate = `Client:
Version: {{.Client.Version}}
API version: {{.Client.APIVersion}}{{if ne .Client.APIVersion .Client.DefaultAPIVersion}} (downgraded from {{.Client.DefaultAPIVersion}}){{end}}
Go version: {{.Client.GoVersion}}
Git commit: {{.Client.GitCommit}}
Built: {{.Client.BuildTime}}
OS/Arch: {{.Client.Os}}/{{.Client.Arch}}{{if .ServerOK}}
var versionTemplate = `{{with .Client -}}
Client:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}}
Version: {{.Version}}
API version: {{.APIVersion}}{{if ne .APIVersion .DefaultAPIVersion}} (downgraded from {{.DefaultAPIVersion}}){{end}}
Go version: {{.GoVersion}}
Git commit: {{.GitCommit}}
Built: {{.BuildTime}}
OS/Arch: {{.Os}}/{{.Arch}}
{{- end}}
Server:
Version: {{.Server.Version}}
API version: {{.Server.APIVersion}} (minimum version {{.Server.MinAPIVersion}})
Go version: {{.Server.GoVersion}}
Git commit: {{.Server.GitCommit}}
Built: {{.Server.BuildTime}}
OS/Arch: {{.Server.Os}}/{{.Server.Arch}}
Experimental: {{.Server.Experimental}}{{end}}`
{{- if .ServerOK}}{{with .Server}}
Server:{{if ne .Platform.Name ""}} {{.Platform.Name}}{{end}}
{{- range $component := .Components}}
{{$component.Name}}:
{{- if eq $component.Name "Engine" }}
Version: {{.Version}}
API version: {{index .Details "ApiVersion"}} (minimum version {{index .Details "MinAPIVersion"}})
Go version: {{index .Details "GoVersion"}}
Git commit: {{index .Details "GitCommit"}}
Built: {{index .Details "BuildTime"}}
OS/Arch: {{index .Details "Os"}}/{{index .Details "Arch"}}
Experimental: {{index .Details "Experimental"}}
{{- else }}
Version: {{$component.Version}}
{{- $detailsOrder := getDetailsOrder $component}}
{{- range $key := $detailsOrder}}
{{$key}}: {{index $component.Details $key}}
{{- end}}
{{- end}}
{{- end}}
{{- end}}{{end}}`
type versionOptions struct {
format string
@ -41,6 +59,8 @@ type versionInfo struct {
}
type clientVersion struct {
Platform struct{ Name string } `json:",omitempty"`
Version string
APIVersion string `json:"ApiVersion"`
DefaultAPIVersion string `json:"DefaultAPIVersion,omitempty"`
@ -77,15 +97,27 @@ func NewVersionCommand(dockerCli *command.DockerCli) *cobra.Command {
return cmd
}
func reformatDate(buildTime string) string {
t, errTime := time.Parse(time.RFC3339Nano, buildTime)
if errTime == nil {
return t.Format(time.ANSIC)
}
return buildTime
}
func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error {
ctx := context.Background()
templateFormat := versionTemplate
tmpl := templates.New("version")
if opts.format != "" {
templateFormat = opts.format
} else {
tmpl = tmpl.Funcs(template.FuncMap{"getDetailsOrder": getDetailsOrder})
}
tmpl, err := templates.Parse(templateFormat)
var err error
tmpl, err = tmpl.Parse(templateFormat)
if err != nil {
return cli.StatusError{StatusCode: 64,
Status: "Template parsing error: " + err.Error()}
@ -103,22 +135,41 @@ func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error {
Arch: runtime.GOARCH,
},
}
serverVersion, err := dockerCli.Client().ServerVersion(ctx)
if err == nil {
vd.Server = &serverVersion
}
vd.Client.Platform.Name = cli.PlatformName
// first we need to make BuildTime more human friendly
t, errTime := time.Parse(time.RFC3339Nano, vd.Client.BuildTime)
if errTime == nil {
vd.Client.BuildTime = t.Format(time.ANSIC)
}
vd.Client.BuildTime = reformatDate(vd.Client.BuildTime)
if vd.ServerOK() {
t, errTime = time.Parse(time.RFC3339Nano, vd.Server.BuildTime)
if errTime == nil {
vd.Server.BuildTime = t.Format(time.ANSIC)
sv, err := dockerCli.Client().ServerVersion(ctx)
if err == nil {
vd.Server = &sv
foundEngine := false
for _, component := range sv.Components {
if component.Name == "Engine" {
foundEngine = true
buildTime, ok := component.Details["BuildTime"]
if ok {
component.Details["BuildTime"] = reformatDate(buildTime)
}
break
}
}
if !foundEngine {
vd.Server.Components = append(vd.Server.Components, types.ComponentVersion{
Name: "Engine",
Version: sv.Version,
Details: map[string]string{
"ApiVersion": sv.APIVersion,
"MinAPIVersion": sv.MinAPIVersion,
"GitCommit": sv.GitCommit,
"GoVersion": sv.GoVersion,
"Os": sv.Os,
"Arch": sv.Arch,
"BuildTime": reformatDate(vd.Server.BuildTime),
"Experimental": fmt.Sprintf("%t", sv.Experimental),
},
})
}
}
@ -128,3 +179,12 @@ func runVersion(dockerCli *command.DockerCli, opts *versionOptions) error {
dockerCli.Out().Write([]byte{'\n'})
return err
}
func getDetailsOrder(v types.ComponentVersion) []string {
out := make([]string, 0, len(v.Details))
for k := range v.Details {
out = append(out, k)
}
sort.Strings(out)
return out
}

View File

@ -192,7 +192,24 @@ func (e EmptyTargetsNotaryRepository) GetAllTargetMetadataByName(name string) ([
}
func (e EmptyTargetsNotaryRepository) ListRoles() ([]client.RoleWithSignatures, error) {
return []client.RoleWithSignatures{}, nil
rootRole := data.Role{
RootRole: data.RootRole{
KeyIDs: []string{"rootID"},
Threshold: 1,
},
Name: data.CanonicalRootRole,
}
targetsRole := data.Role{
RootRole: data.RootRole{
KeyIDs: []string{"targetsID"},
Threshold: 1,
},
Name: data.CanonicalTargetsRole,
}
return []client.RoleWithSignatures{
{Role: rootRole},
{Role: targetsRole}}, nil
}
func (e EmptyTargetsNotaryRepository) GetDelegationRoles() ([]data.Role, error) {

View File

@ -20,6 +20,7 @@ func NewTrustCommand(dockerCli command.Cli) *cobra.Command {
newSignCommand(dockerCli),
newTrustKeyCommand(dockerCli),
newTrustSignerCommand(dockerCli),
newInspectCommand(dockerCli),
)
return cmd
}

View File

@ -0,0 +1,167 @@
package trust
import (
"context"
"encoding/hex"
"fmt"
"sort"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/trust"
"github.com/sirupsen/logrus"
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data"
)
// trustTagKey represents a unique signed tag and hex-encoded hash pair
type trustTagKey struct {
SignedTag string
Digest string
}
// trustTagRow encodes all human-consumable information for a signed tag, including signers
type trustTagRow struct {
trustTagKey
Signers []string
}
type trustTagRowList []trustTagRow
func (tagComparator trustTagRowList) Len() int {
return len(tagComparator)
}
func (tagComparator trustTagRowList) Less(i, j int) bool {
return tagComparator[i].SignedTag < tagComparator[j].SignedTag
}
func (tagComparator trustTagRowList) Swap(i, j int) {
tagComparator[i], tagComparator[j] = tagComparator[j], tagComparator[i]
}
// trustRepo represents consumable information about a trusted repository
type trustRepo struct {
Name string
SignedTags trustTagRowList
Signers []trustSigner
AdminstrativeKeys []trustSigner
}
// trustSigner represents a trusted signer in a trusted repository
// a signer is defined by a name and list of trustKeys
type trustSigner struct {
Name string `json:",omitempty"`
Keys []trustKey `json:",omitempty"`
}
// trustKey contains information about trusted keys
type trustKey struct {
ID string `json:",omitempty"`
}
// lookupTrustInfo returns processed signature and role information about a notary repository.
// This information is to be pretty printed or serialized into a machine-readable format.
func lookupTrustInfo(cli command.Cli, remote string) (trustTagRowList, []client.RoleWithSignatures, []data.Role, error) {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote)
if err != nil {
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, err
}
tag := imgRefAndAuth.Tag()
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
if err != nil {
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
}
if err = clearChangeList(notaryRepo); err != nil {
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, err
}
defer clearChangeList(notaryRepo)
// Retrieve all released signatures, match them, and pretty print them
allSignedTargets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil {
logrus.Debug(trust.NotaryError(remote, err))
// print an empty table if we don't have signed targets, but have an initialized notary repo
if _, ok := err.(client.ErrNoSuchTarget); !ok {
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signatures or cannot access %s", remote)
}
}
signatureRows := matchReleasedSignatures(allSignedTargets)
// get the administrative roles
adminRolesWithSigs, err := notaryRepo.ListRoles()
if err != nil {
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signers for %s", remote)
}
// get delegation roles with the canonical key IDs
delegationRoles, err := notaryRepo.GetDelegationRoles()
if err != nil {
logrus.Debugf("no delegation roles found, or error fetching them for %s: %v", remote, err)
}
return signatureRows, adminRolesWithSigs, delegationRoles, nil
}
func formatAdminRole(roleWithSigs client.RoleWithSignatures) string {
adminKeyList := roleWithSigs.KeyIDs
sort.Strings(adminKeyList)
var role string
switch roleWithSigs.Name {
case data.CanonicalTargetsRole:
role = "Repository Key"
case data.CanonicalRootRole:
role = "Root Key"
default:
return ""
}
return fmt.Sprintf("%s:\t%s\n", role, strings.Join(adminKeyList, ", "))
}
func getDelegationRoleToKeyMap(rawDelegationRoles []data.Role) map[string][]string {
signerRoleToKeyIDs := make(map[string][]string)
for _, delRole := range rawDelegationRoles {
switch delRole.Name {
case trust.ReleasesRole, data.CanonicalRootRole, data.CanonicalSnapshotRole, data.CanonicalTargetsRole, data.CanonicalTimestampRole:
continue
default:
signerRoleToKeyIDs[notaryRoleToSigner(delRole.Name)] = delRole.KeyIDs
}
}
return signerRoleToKeyIDs
}
// aggregate all signers for a "released" hash+tagname pair. To be "released," the tag must have been
// signed into the "targets" or "targets/releases" role. Output is sorted by tag name
func matchReleasedSignatures(allTargets []client.TargetSignedStruct) trustTagRowList {
signatureRows := trustTagRowList{}
// do a first pass to get filter on tags signed into "targets" or "targets/releases"
releasedTargetRows := map[trustTagKey][]string{}
for _, tgt := range allTargets {
if isReleasedTarget(tgt.Role.Name) {
releasedKey := trustTagKey{tgt.Target.Name, hex.EncodeToString(tgt.Target.Hashes[notary.SHA256])}
releasedTargetRows[releasedKey] = []string{}
}
}
// now fill out all signers on released keys
for _, tgt := range allTargets {
targetKey := trustTagKey{tgt.Target.Name, hex.EncodeToString(tgt.Target.Hashes[notary.SHA256])}
// only considered released targets
if _, ok := releasedTargetRows[targetKey]; ok && !isReleasedTarget(tgt.Role.Name) {
releasedTargetRows[targetKey] = append(releasedTargetRows[targetKey], notaryRoleToSigner(tgt.Role.Name))
}
}
// compile the final output as a sorted slice
for targetKey, signers := range releasedTargetRows {
signatureRows = append(signatureRows, trustTagRow{targetKey, signers})
}
sort.Sort(signatureRows)
return signatureRows
}

View File

@ -0,0 +1,83 @@
package trust
import (
"encoding/json"
"sort"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/inspect"
"github.com/spf13/cobra"
"github.com/theupdateframework/notary/tuf/data"
)
func newInspectCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "inspect IMAGE[:TAG] [IMAGE[:TAG]...]",
Short: "Return low-level information about keys and signatures",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runInspect(dockerCli, args)
},
}
return cmd
}
func runInspect(dockerCli command.Cli, remotes []string) error {
getRefFunc := func(ref string) (interface{}, []byte, error) {
i, err := getRepoTrustInfo(dockerCli, ref)
return nil, i, err
}
return inspect.Inspect(dockerCli.Out(), remotes, "", getRefFunc)
}
func getRepoTrustInfo(cli command.Cli, remote string) ([]byte, error) {
signatureRows, adminRolesWithSigs, delegationRoles, err := lookupTrustInfo(cli, remote)
if err != nil {
return []byte{}, err
}
// process the signatures to include repo admin if signed by the base targets role
for idx, sig := range signatureRows {
if len(sig.Signers) == 0 {
signatureRows[idx].Signers = append(sig.Signers, releasedRoleName)
}
}
signerList, adminList := []trustSigner{}, []trustSigner{}
signerRoleToKeyIDs := getDelegationRoleToKeyMap(delegationRoles)
for signerName, signerKeys := range signerRoleToKeyIDs {
signerKeyList := []trustKey{}
for _, keyID := range signerKeys {
signerKeyList = append(signerKeyList, trustKey{ID: keyID})
}
signerList = append(signerList, trustSigner{signerName, signerKeyList})
}
sort.Slice(signerList, func(i, j int) bool { return signerList[i].Name > signerList[j].Name })
for _, adminRole := range adminRolesWithSigs {
switch adminRole.Name {
case data.CanonicalRootRole:
rootKeys := []trustKey{}
for _, keyID := range adminRole.KeyIDs {
rootKeys = append(rootKeys, trustKey{ID: keyID})
}
adminList = append(adminList, trustSigner{"Root", rootKeys})
case data.CanonicalTargetsRole:
targetKeys := []trustKey{}
for _, keyID := range adminRole.KeyIDs {
targetKeys = append(targetKeys, trustKey{ID: keyID})
}
adminList = append(adminList, trustSigner{"Repository", targetKeys})
}
}
sort.Slice(adminList, func(i, j int) bool { return adminList[i].Name > adminList[j].Name })
return json.Marshal(trustRepo{
Name: remote,
SignedTags: signatureRows,
Signers: signerList,
AdminstrativeKeys: adminList,
})
}

View File

@ -0,0 +1,135 @@
package trust
import (
"io/ioutil"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestTrustInspectCommandErrors(t *testing.T) {
testCases := []struct {
name string
args []string
expectedError string
}{
{
name: "not-enough-args",
expectedError: "requires exactly 1 argument",
},
{
name: "too-many-args",
args: []string{"remote1", "remote2"},
expectedError: "requires exactly 1 argument",
},
{
name: "sha-reference",
args: []string{"870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"},
expectedError: "invalid repository name",
},
{
name: "invalid-img-reference",
args: []string{"ALPINE"},
expectedError: "invalid reference format",
},
}
for _, tc := range testCases {
cmd := newViewCommand(
test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestTrustInspectCommandOfflineErrors(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getOfflineNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"nonexistent-reg-name.io/image"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
cli = test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getOfflineNotaryRepository)
cmd = newInspectCommand(cli)
cmd.SetArgs([]string{"nonexistent-reg-name.io/image:tag"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
}
func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getUninitializedNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"reg/unsigned-img"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img")
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-uninitialized.golden")
cli = test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getUninitializedNotaryRepository)
cmd = newInspectCommand(cli)
cmd.SetArgs([]string{"reg/unsigned-img:tag"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img:tag")
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-uninitialized.golden")
}
func TestTrustInspectCommandEmptyNotaryRepo(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"reg/img:unsigned-tag"})
cmd.SetOutput(ioutil.Discard)
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-empty-repo.golden")
}
func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"signed-repo"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-full-repo-no-signers.golden")
}
func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"signed-repo:green"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-one-tag-no-signers.golden")
}
func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"signed-repo"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-full-repo-with-signers.golden")
}
func TestTrustInspectCommandMultipleFullReposWithSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"signed-repo", "signed-repo"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-multiple-repos-with-signers.golden")
}
func TestTrustInspectCommandUnsignedTagInSignedRepo(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedNotaryRepository)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"signed-repo:unsigned"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-unsigned-tag-with-signers.golden")
}

View File

@ -18,19 +18,29 @@ import (
"github.com/theupdateframework/notary/tuf/data"
)
type signOptions struct {
local bool
imageName string
}
func newSignCommand(dockerCli command.Cli) *cobra.Command {
options := signOptions{}
cmd := &cobra.Command{
Use: "sign IMAGE:TAG",
Short: "Sign an image",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runSignImage(dockerCli, args[0])
options.imageName = args[0]
return runSignImage(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVar(&options.local, "local", false, "Sign a locally tagged image")
return cmd
}
func runSignImage(cli command.Cli, imageName string) error {
func runSignImage(cli command.Cli, options signOptions) error {
imageName := options.imageName
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), imageName)
if err != nil {
@ -71,13 +81,15 @@ func runSignImage(cli command.Cli, imageName string) error {
}
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(cli, imgRefAndAuth.RepoInfo().Index, "push")
target, err := createTarget(notaryRepo, imgRefAndAuth.Tag())
if err != nil {
if err != nil || options.local {
switch err := err.(type) {
case client.ErrNoSuchTarget, client.ErrRepositoryNotExist:
// If the error is nil then the local flag is set
case client.ErrNoSuchTarget, client.ErrRepositoryNotExist, nil:
// Fail fast if the image doesn't exist locally
if err := checkLocalImageExistence(ctx, cli, imageName); err != nil {
return err
}
fmt.Fprintf(cli.Err(), "Signing and pushing trust data for local image %s, may overwrite remote trust data\n", imageName)
return image.TrustedPush(ctx, cli, imgRefAndAuth.RepoInfo(), imgRefAndAuth.Reference(), *imgRefAndAuth.AuthConfig(), requestPrivilege)
default:
return err
@ -164,7 +176,7 @@ func getExistingSignatureInfoForReleasedTag(notaryRepo client.Repository, tag st
func prettyPrintExistingSignatureInfo(out io.Writer, existingSigInfo trustTagRow) {
sort.Strings(existingSigInfo.Signers)
joinedSigners := strings.Join(existingSigInfo.Signers, ", ")
fmt.Fprintf(out, "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.TagName, existingSigInfo.HashHex, joinedSigners)
fmt.Fprintf(out, "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.SignedTag, existingSigInfo.Digest, joinedSigners)
}
func initNotaryRepoWithSigners(notaryRepo client.Repository, newSigner data.RoleName) error {

View File

@ -1,13 +1,12 @@
package trust
import (
"bytes"
"encoding/json"
"io/ioutil"
"os"
"testing"
"bytes"
"github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/trust"
"github.com/docker/cli/internal/test"
@ -296,3 +295,13 @@ func TestSignCommandChangeListIsCleanedOnError(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, len(cl.List()), 0)
}
func TestSignCommandLocalFlag(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
cmd := newSignCommand(cli)
cmd.SetArgs([]string{"--local", "reg-name.io/image:red"})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "error during connect: Get /images/reg-name.io/image:red/json: unsupported protocol scheme")
}

View File

@ -0,0 +1,25 @@
[
{
"Name": "reg/img:unsigned-tag",
"SignedTags": [],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -1,6 +1,33 @@
SIGNED TAG DIGEST SIGNERS
green 677265656e2d646967657374 (Repo Admin)
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID
[
{
"Name": "signed-repo",
"SignedTags": [
{
"SignedTag": "green",
"Digest": "677265656e2d646967657374",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -1,14 +1,65 @@
SIGNED TAG DIGEST SIGNERS
blue 626c75652d646967657374 alice
green 677265656e2d646967657374 (Repo Admin)
red 7265642d646967657374 alice, bob
List of signers and their keys for signed-repo:
SIGNER KEYS
alice A
bob B
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID
[
{
"Name": "signed-repo",
"SignedTags": [
{
"SignedTag": "blue",
"Digest": "626c75652d646967657374",
"Signers": [
"alice"
]
},
{
"SignedTag": "green",
"Digest": "677265656e2d646967657374",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "red",
"Digest": "7265642d646967657374",
"Signers": [
"alice",
"bob"
]
}
],
"Signers": [
{
"Name": "bob",
"Keys": [
{
"ID": "B"
}
]
},
{
"Name": "alice",
"Keys": [
{
"ID": "A"
}
]
}
],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -0,0 +1,128 @@
[
{
"Name": "signed-repo",
"SignedTags": [
{
"SignedTag": "blue",
"Digest": "626c75652d646967657374",
"Signers": [
"alice"
]
},
{
"SignedTag": "green",
"Digest": "677265656e2d646967657374",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "red",
"Digest": "7265642d646967657374",
"Signers": [
"alice",
"bob"
]
}
],
"Signers": [
{
"Name": "bob",
"Keys": [
{
"ID": "B"
}
]
},
{
"Name": "alice",
"Keys": [
{
"ID": "A"
}
]
}
],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
},
{
"Name": "signed-repo",
"SignedTags": [
{
"SignedTag": "blue",
"Digest": "626c75652d646967657374",
"Signers": [
"alice"
]
},
{
"SignedTag": "green",
"Digest": "677265656e2d646967657374",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "red",
"Digest": "7265642d646967657374",
"Signers": [
"alice",
"bob"
]
}
],
"Signers": [
{
"Name": "bob",
"Keys": [
{
"ID": "B"
}
]
},
{
"Name": "alice",
"Keys": [
{
"ID": "A"
}
]
}
],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -1,6 +1,33 @@
SIGNED TAG DIGEST SIGNERS
green 677265656e2d646967657374 (Repo Admin)
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID
[
{
"Name": "signed-repo:green",
"SignedTags": [
{
"SignedTag": "green",
"Digest": "677265656e2d646967657374",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -0,0 +1 @@
[]

View File

@ -1,13 +1,42 @@
No signatures for signed-repo:unsigned
List of signers and their keys for signed-repo:
SIGNER KEYS
alice A
bob B
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID
[
{
"Name": "signed-repo:unsigned",
"SignedTags": [],
"Signers": [
{
"Name": "bob",
"Keys": [
{
"ID": "B"
}
]
},
{
"Name": "alice",
"Keys": [
{
"ID": "A"
}
]
}
],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "rootID"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "targetsID"
}
]
}
]
}
]

View File

@ -0,0 +1,6 @@
SIGNED TAG DIGEST SIGNERS
green 677265656e2d646967657374 (Repo Admin)
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID

View File

@ -0,0 +1,14 @@
SIGNED TAG DIGEST SIGNERS
blue 626c75652d646967657374 alice
green 677265656e2d646967657374 (Repo Admin)
red 7265642d646967657374 alice, bob
List of signers and their keys for signed-repo:
SIGNER KEYS
alice A
bob B
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID

View File

@ -0,0 +1,6 @@
SIGNED TAG DIGEST SIGNERS
green 677265656e2d646967657374 (Repo Admin)
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID

View File

@ -0,0 +1,13 @@
No signatures for signed-repo:unsigned
List of signers and their keys for signed-repo:
SIGNER KEYS
alice A
bob B
Administrative keys for signed-repo:
Repository Key: targetsID
Root Key: rootID

View File

@ -1,8 +1,6 @@
package trust
import (
"context"
"encoding/hex"
"fmt"
"io"
"sort"
@ -11,80 +9,28 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/trust"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/tuf/data"
)
// trustTagKey represents a unique signed tag and hex-encoded hash pair
type trustTagKey struct {
TagName string
HashHex string
}
// trustTagRow encodes all human-consumable information for a signed tag, including signers
type trustTagRow struct {
trustTagKey
Signers []string
}
type trustTagRowList []trustTagRow
func (tagComparator trustTagRowList) Len() int {
return len(tagComparator)
}
func (tagComparator trustTagRowList) Less(i, j int) bool {
return tagComparator[i].TagName < tagComparator[j].TagName
}
func (tagComparator trustTagRowList) Swap(i, j int) {
tagComparator[i], tagComparator[j] = tagComparator[j], tagComparator[i]
}
func newViewCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "view IMAGE[:TAG]",
Short: "Display detailed information about keys and signatures",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return lookupTrustInfo(dockerCli, args[0])
return viewTrustInfo(dockerCli, args[0])
},
}
return cmd
}
func lookupTrustInfo(cli command.Cli, remote string) error {
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, image.AuthResolver(cli), remote)
func viewTrustInfo(cli command.Cli, remote string) error {
signatureRows, adminRolesWithSigs, delegationRoles, err := lookupTrustInfo(cli, remote)
if err != nil {
return err
}
tag := imgRefAndAuth.Tag()
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
if err != nil {
return trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
}
if err = clearChangeList(notaryRepo); err != nil {
return err
}
defer clearChangeList(notaryRepo)
// Retrieve all released signatures, match them, and pretty print them
allSignedTargets, err := notaryRepo.GetAllTargetMetadataByName(tag)
if err != nil {
logrus.Debug(trust.NotaryError(imgRefAndAuth.Reference().Name(), err))
// print an empty table if we don't have signed targets, but have an initialized notary repo
if _, ok := err.(client.ErrNoSuchTarget); !ok {
return fmt.Errorf("No signatures or cannot access %s", remote)
}
}
signatureRows := matchReleasedSignatures(allSignedTargets)
if len(signatureRows) > 0 {
if err := printSignatures(cli.Out(), signatureRows); err != nil {
return err
@ -92,18 +38,6 @@ func lookupTrustInfo(cli command.Cli, remote string) error {
} else {
fmt.Fprintf(cli.Out(), "\nNo signatures for %s\n\n", remote)
}
// get the administrative roles
adminRolesWithSigs, err := notaryRepo.ListRoles()
if err != nil {
return fmt.Errorf("No signers for %s", remote)
}
// get delegation roles with the canonical key IDs
delegationRoles, err := notaryRepo.GetDelegationRoles()
if err != nil {
logrus.Debugf("no delegation roles found, or error fetching them for %s: %v", remote, err)
}
signerRoleToKeyIDs := getDelegationRoleToKeyMap(delegationRoles)
// If we do not have additional signers, do not display
@ -117,7 +51,6 @@ func lookupTrustInfo(cli command.Cli, remote string) error {
// This will always have the root and targets information
fmt.Fprintf(cli.Out(), "\nAdministrative keys for %s:\n", strings.Split(remote, ":")[0])
printSortedAdminKeys(cli.Out(), adminRolesWithSigs)
return nil
}
@ -128,65 +61,6 @@ func printSortedAdminKeys(out io.Writer, adminRoles []client.RoleWithSignatures)
}
}
func formatAdminRole(roleWithSigs client.RoleWithSignatures) string {
adminKeyList := roleWithSigs.KeyIDs
sort.Strings(adminKeyList)
var role string
switch roleWithSigs.Name {
case data.CanonicalTargetsRole:
role = "Repository Key"
case data.CanonicalRootRole:
role = "Root Key"
default:
return ""
}
return fmt.Sprintf("%s:\t%s\n", role, strings.Join(adminKeyList, ", "))
}
func getDelegationRoleToKeyMap(rawDelegationRoles []data.Role) map[string][]string {
signerRoleToKeyIDs := make(map[string][]string)
for _, delRole := range rawDelegationRoles {
switch delRole.Name {
case trust.ReleasesRole, data.CanonicalRootRole, data.CanonicalSnapshotRole, data.CanonicalTargetsRole, data.CanonicalTimestampRole:
continue
default:
signerRoleToKeyIDs[notaryRoleToSigner(delRole.Name)] = delRole.KeyIDs
}
}
return signerRoleToKeyIDs
}
// aggregate all signers for a "released" hash+tagname pair. To be "released," the tag must have been
// signed into the "targets" or "targets/releases" role. Output is sorted by tag name
func matchReleasedSignatures(allTargets []client.TargetSignedStruct) trustTagRowList {
signatureRows := trustTagRowList{}
// do a first pass to get filter on tags signed into "targets" or "targets/releases"
releasedTargetRows := map[trustTagKey][]string{}
for _, tgt := range allTargets {
if isReleasedTarget(tgt.Role.Name) {
releasedKey := trustTagKey{tgt.Target.Name, hex.EncodeToString(tgt.Target.Hashes[notary.SHA256])}
releasedTargetRows[releasedKey] = []string{}
}
}
// now fill out all signers on released keys
for _, tgt := range allTargets {
targetKey := trustTagKey{tgt.Target.Name, hex.EncodeToString(tgt.Target.Hashes[notary.SHA256])}
// only considered released targets
if _, ok := releasedTargetRows[targetKey]; ok && !isReleasedTarget(tgt.Role.Name) {
releasedTargetRows[targetKey] = append(releasedTargetRows[targetKey], notaryRoleToSigner(tgt.Role.Name))
}
}
// compile the final output as a sorted slice
for targetKey, signers := range releasedTargetRows {
signatureRows = append(signatureRows, trustTagRow{targetKey, signers})
}
sort.Sort(signatureRows)
return signatureRows
}
// pretty print with ordered rows
func printSignatures(out io.Writer, signatureRows trustTagRowList) error {
trustTagCtx := formatter.Context{
@ -201,8 +75,8 @@ func printSignatures(out io.Writer, signatureRows trustTagRowList) error {
formattedSigners = append(formattedSigners, fmt.Sprintf("(%s)", releasedRoleName))
}
formattedTags = append(formattedTags, formatter.SignedTagInfo{
Name: sigRow.TagName,
Digest: sigRow.HashHex,
Name: sigRow.SignedTag,
Digest: sigRow.Digest,
Signers: formattedSigners,
})
}

View File

@ -20,7 +20,7 @@ type fakeClient struct {
dockerClient.Client
}
func TestTrustInspectCommandErrors(t *testing.T) {
func TestTrustViewCommandErrors(t *testing.T) {
testCases := []struct {
name string
args []string
@ -55,7 +55,7 @@ func TestTrustInspectCommandErrors(t *testing.T) {
}
}
func TestTrustInspectCommandOfflineErrors(t *testing.T) {
func TestTrustViewCommandOfflineErrors(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getOfflineNotaryRepository)
cmd := newViewCommand(cli)
@ -71,7 +71,7 @@ func TestTrustInspectCommandOfflineErrors(t *testing.T) {
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access nonexistent-reg-name.io/image")
}
func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
func TestTrustViewCommandUninitializedErrors(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getUninitializedNotaryRepository)
cmd := newViewCommand(cli)
@ -87,7 +87,7 @@ func TestTrustInspectCommandUninitializedErrors(t *testing.T) {
testutil.ErrorContains(t, cmd.Execute(), "No signatures or cannot access reg/unsigned-img:tag")
}
func TestTrustInspectCommandEmptyNotaryRepoErrors(t *testing.T) {
func TestTrustViewCommandEmptyNotaryRepoErrors(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getEmptyTargetsNotaryRepository)
cmd := newViewCommand(cli)
@ -107,44 +107,44 @@ func TestTrustInspectCommandEmptyNotaryRepoErrors(t *testing.T) {
assert.Contains(t, cli.OutBuffer().String(), "Administrative keys for reg/img:")
}
func TestTrustInspectCommandFullRepoWithoutSigners(t *testing.T) {
func TestTrustViewCommandFullRepoWithoutSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
cmd := newViewCommand(cli)
cmd.SetArgs([]string{"signed-repo"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-full-repo-no-signers.golden")
golden.Assert(t, cli.OutBuffer().String(), "trust-view-full-repo-no-signers.golden")
}
func TestTrustInspectCommandOneTagWithoutSigners(t *testing.T) {
func TestTrustViewCommandOneTagWithoutSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedWithNoSignersNotaryRepository)
cmd := newViewCommand(cli)
cmd.SetArgs([]string{"signed-repo:green"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-one-tag-no-signers.golden")
golden.Assert(t, cli.OutBuffer().String(), "trust-view-one-tag-no-signers.golden")
}
func TestTrustInspectCommandFullRepoWithSigners(t *testing.T) {
func TestTrustViewCommandFullRepoWithSigners(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedNotaryRepository)
cmd := newViewCommand(cli)
cmd.SetArgs([]string{"signed-repo"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-full-repo-with-signers.golden")
golden.Assert(t, cli.OutBuffer().String(), "trust-view-full-repo-with-signers.golden")
}
func TestTrustInspectCommandUnsignedTagInSignedRepo(t *testing.T) {
func TestTrustViewCommandUnsignedTagInSignedRepo(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{})
cli.SetNotaryClient(getLoadedNotaryRepository)
cmd := newViewCommand(cli)
cmd.SetArgs([]string{"signed-repo:unsigned"})
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "trust-inspect-unsigned-tag-with-signers.golden")
golden.Assert(t, cli.OutBuffer().String(), "trust-view-unsigned-tag-with-signers.golden")
}
func TestNotaryRoleToSigner(t *testing.T) {
@ -224,8 +224,8 @@ func TestMatchOneReleasedSingleSignature(t *testing.T) {
outputRow := matchedSigRows[0]
// Empty signers because "targets/releases" doesn't show up
assert.Empty(t, outputRow.Signers)
assert.Equal(t, releasedTgt.Name, outputRow.TagName)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.HashHex)
assert.Equal(t, releasedTgt.Name, outputRow.SignedTag)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.Digest)
}
func TestMatchOneReleasedMultiSignature(t *testing.T) {
@ -249,8 +249,8 @@ func TestMatchOneReleasedMultiSignature(t *testing.T) {
outputRow := matchedSigRows[0]
// We should have three signers
assert.Equal(t, outputRow.Signers, []string{"a", "b", "c"})
assert.Equal(t, releasedTgt.Name, outputRow.TagName)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.HashHex)
assert.Equal(t, releasedTgt.Name, outputRow.SignedTag)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.Digest)
}
func TestMatchMultiReleasedMultiSignature(t *testing.T) {
@ -288,18 +288,18 @@ func TestMatchMultiReleasedMultiSignature(t *testing.T) {
// note that the output is sorted by tag name, so we can reliably index to validate data:
outputTargetA := matchedSigRows[0]
assert.Equal(t, outputTargetA.Signers, []string{"a"})
assert.Equal(t, targetA.Name, outputTargetA.TagName)
assert.Equal(t, hex.EncodeToString(targetA.Hashes[notary.SHA256]), outputTargetA.HashHex)
assert.Equal(t, targetA.Name, outputTargetA.SignedTag)
assert.Equal(t, hex.EncodeToString(targetA.Hashes[notary.SHA256]), outputTargetA.Digest)
outputTargetB := matchedSigRows[1]
assert.Equal(t, outputTargetB.Signers, []string{"a", "b"})
assert.Equal(t, targetB.Name, outputTargetB.TagName)
assert.Equal(t, hex.EncodeToString(targetB.Hashes[notary.SHA256]), outputTargetB.HashHex)
assert.Equal(t, targetB.Name, outputTargetB.SignedTag)
assert.Equal(t, hex.EncodeToString(targetB.Hashes[notary.SHA256]), outputTargetB.Digest)
outputTargetC := matchedSigRows[2]
assert.Equal(t, outputTargetC.Signers, []string{"a", "b", "c"})
assert.Equal(t, targetC.Name, outputTargetC.TagName)
assert.Equal(t, hex.EncodeToString(targetC.Hashes[notary.SHA256]), outputTargetC.HashHex)
assert.Equal(t, targetC.Name, outputTargetC.SignedTag)
assert.Equal(t, hex.EncodeToString(targetC.Hashes[notary.SHA256]), outputTargetC.Digest)
}
func TestMatchReleasedSignatureFromTargets(t *testing.T) {
@ -313,8 +313,8 @@ func TestMatchReleasedSignatureFromTargets(t *testing.T) {
outputRow := matchedSigRows[0]
// Empty signers because "targets" doesn't show up
assert.Empty(t, outputRow.Signers)
assert.Equal(t, releasedTgt.Name, outputRow.TagName)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.HashHex)
assert.Equal(t, releasedTgt.Name, outputRow.SignedTag)
assert.Equal(t, hex.EncodeToString(releasedTgt.Hashes[notary.SHA256]), outputRow.Digest)
}
func TestGetSignerRolesWithKeyIDs(t *testing.T) {

View File

@ -11,6 +11,7 @@ import (
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/system"
"github.com/spf13/pflag"
)
// CopyToFile writes the content of the reader to the specified file
@ -117,3 +118,10 @@ func PruneFilters(dockerCli Cli, pruneFilters filters.Args) filters.Args {
return pruneFilters
}
// AddPlatformFlag adds `platform` to a set of flags for API version 1.32 and later.
func AddPlatformFlag(flags *pflag.FlagSet, target *string) {
flags.StringVar(target, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable")
flags.SetAnnotation("platform", "version", []string{"1.32"})
flags.SetAnnotation("platform", "experimental", nil)
}

View File

@ -101,18 +101,11 @@ func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig)
continue
}
data, err := ioutil.ReadFile(secret.File)
obj, err := fileObjectConfig(namespace, name, composetypes.FileObjectConfig(secret))
if err != nil {
return nil, err
}
result = append(result, swarm.SecretSpec{
Annotations: swarm.Annotations{
Name: namespace.Scope(name),
Labels: AddStackLabel(namespace, secret.Labels),
},
Data: data,
})
result = append(result, swarm.SecretSpec{Annotations: obj.Annotations, Data: obj.Data})
}
return result, nil
}
@ -125,18 +118,37 @@ func Configs(namespace Namespace, configs map[string]composetypes.ConfigObjConfi
continue
}
data, err := ioutil.ReadFile(config.File)
obj, err := fileObjectConfig(namespace, name, composetypes.FileObjectConfig(config))
if err != nil {
return nil, err
}
result = append(result, swarm.ConfigSpec{
Annotations: swarm.Annotations{
Name: namespace.Scope(name),
Labels: AddStackLabel(namespace, config.Labels),
},
Data: data,
})
result = append(result, swarm.ConfigSpec{Annotations: obj.Annotations, Data: obj.Data})
}
return result, nil
}
type swarmFileObject struct {
Annotations swarm.Annotations
Data []byte
}
func fileObjectConfig(namespace Namespace, name string, obj composetypes.FileObjectConfig) (swarmFileObject, error) {
data, err := ioutil.ReadFile(obj.File)
if err != nil {
return swarmFileObject{}, err
}
if obj.Name != "" {
name = obj.Name
} else {
name = namespace.Scope(name)
}
return swarmFileObject{
Annotations: swarm.Annotations{
Name: name,
Labels: AddStackLabel(namespace, obj.Labels),
},
Data: data,
}, nil
}

View File

@ -149,6 +149,7 @@ func Service(
Configs: configs,
ReadOnly: service.ReadOnly,
Privileges: &privileges,
Isolation: container.Isolation(service.Isolation),
},
LogDriver: logDriver,
Resources: resources,
@ -255,43 +256,24 @@ func convertServiceSecrets(
secretSpecs map[string]composetypes.SecretConfig,
) ([]*swarm.SecretReference, error) {
refs := []*swarm.SecretReference{}
for _, secret := range secrets {
target := secret.Target
if target == "" {
target = secret.Source
}
secretSpec, exists := secretSpecs[secret.Source]
lookup := func(key string) (composetypes.FileObjectConfig, error) {
secretSpec, exists := secretSpecs[key]
if !exists {
return nil, errors.Errorf("undefined secret %q", secret.Source)
}
source := namespace.Scope(secret.Source)
if secretSpec.External.External {
source = secretSpec.External.Name
}
uid := secret.UID
gid := secret.GID
if uid == "" {
uid = "0"
}
if gid == "" {
gid = "0"
}
mode := secret.Mode
if mode == nil {
mode = uint32Ptr(0444)
return composetypes.FileObjectConfig{}, errors.Errorf("undefined secret %q", key)
}
return composetypes.FileObjectConfig(secretSpec), nil
}
for _, secret := range secrets {
obj, err := convertFileObject(namespace, composetypes.FileReferenceConfig(secret), lookup)
if err != nil {
return nil, err
}
file := swarm.SecretReferenceFileTarget(obj.File)
refs = append(refs, &swarm.SecretReference{
File: &swarm.SecretReferenceFileTarget{
Name: target,
UID: uid,
GID: gid,
Mode: os.FileMode(*mode),
},
SecretName: source,
File: &file,
SecretName: obj.Name,
})
}
@ -312,43 +294,24 @@ func convertServiceConfigObjs(
configSpecs map[string]composetypes.ConfigObjConfig,
) ([]*swarm.ConfigReference, error) {
refs := []*swarm.ConfigReference{}
for _, config := range configs {
target := config.Target
if target == "" {
target = config.Source
}
configSpec, exists := configSpecs[config.Source]
lookup := func(key string) (composetypes.FileObjectConfig, error) {
configSpec, exists := configSpecs[key]
if !exists {
return nil, errors.Errorf("undefined config %q", config.Source)
}
source := namespace.Scope(config.Source)
if configSpec.External.External {
source = configSpec.External.Name
}
uid := config.UID
gid := config.GID
if uid == "" {
uid = "0"
}
if gid == "" {
gid = "0"
}
mode := config.Mode
if mode == nil {
mode = uint32Ptr(0444)
return composetypes.FileObjectConfig{}, errors.Errorf("undefined config %q", key)
}
return composetypes.FileObjectConfig(configSpec), nil
}
for _, config := range configs {
obj, err := convertFileObject(namespace, composetypes.FileReferenceConfig(config), lookup)
if err != nil {
return nil, err
}
file := swarm.ConfigReferenceFileTarget(obj.File)
refs = append(refs, &swarm.ConfigReference{
File: &swarm.ConfigReferenceFileTarget{
Name: target,
UID: uid,
GID: gid,
Mode: os.FileMode(*mode),
},
ConfigName: source,
File: &file,
ConfigName: obj.Name,
})
}
@ -361,6 +324,63 @@ func convertServiceConfigObjs(
return confs, err
}
type swarmReferenceTarget struct {
Name string
UID string
GID string
Mode os.FileMode
}
type swarmReferenceObject struct {
File swarmReferenceTarget
ID string
Name string
}
func convertFileObject(
namespace Namespace,
config composetypes.FileReferenceConfig,
lookup func(key string) (composetypes.FileObjectConfig, error),
) (swarmReferenceObject, error) {
target := config.Target
if target == "" {
target = config.Source
}
obj, err := lookup(config.Source)
if err != nil {
return swarmReferenceObject{}, err
}
source := namespace.Scope(config.Source)
if obj.Name != "" {
source = obj.Name
}
uid := config.UID
gid := config.GID
if uid == "" {
uid = "0"
}
if gid == "" {
gid = "0"
}
mode := config.Mode
if mode == nil {
mode = uint32Ptr(0444)
}
return swarmReferenceObject{
File: swarmReferenceTarget{
Name: target,
UID: uid,
GID: gid,
Mode: os.FileMode(*mode),
},
Name: source,
}, nil
}
func uint32Ptr(value uint32) *uint32 {
return &value
}
@ -490,9 +510,25 @@ func convertResources(source composetypes.Resources) (*swarm.ResourceRequirement
return nil, err
}
}
var generic []swarm.GenericResource
for _, res := range source.Reservations.GenericResources {
var r swarm.GenericResource
if res.DiscreteResourceSpec != nil {
r.DiscreteResourceSpec = &swarm.DiscreteGenericResource{
Kind: res.DiscreteResourceSpec.Kind,
Value: res.DiscreteResourceSpec.Value,
}
}
generic = append(generic, r)
}
resources.Reservations = &swarm.Resources{
NanoCPUs: cpus,
MemoryBytes: int64(source.Reservations.MemoryBytes),
NanoCPUs: cpus,
MemoryBytes: int64(source.Reservations.MemoryBytes),
GenericResources: generic,
}
}
return resources, nil

View File

@ -1,15 +1,21 @@
package convert
import (
"os"
"sort"
"strings"
"testing"
"time"
composetypes "github.com/docker/cli/cli/compose/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestConvertRestartPolicyFromNone(t *testing.T) {
@ -372,3 +378,179 @@ func TestConvertUpdateConfigOrder(t *testing.T) {
})
assert.Equal(t, updateConfig.Order, "stop-first")
}
func TestConvertFileObject(t *testing.T) {
namespace := NewNamespace("testing")
config := composetypes.FileReferenceConfig{
Source: "source",
Target: "target",
UID: "user",
GID: "group",
Mode: uint32Ptr(0644),
}
swarmRef, err := convertFileObject(namespace, config, lookupConfig)
require.NoError(t, err)
expected := swarmReferenceObject{
Name: "testing_source",
File: swarmReferenceTarget{
Name: config.Target,
UID: config.UID,
GID: config.GID,
Mode: os.FileMode(0644),
},
}
assert.Equal(t, expected, swarmRef)
}
func lookupConfig(key string) (composetypes.FileObjectConfig, error) {
if key != "source" {
return composetypes.FileObjectConfig{}, errors.New("bad key")
}
return composetypes.FileObjectConfig{}, nil
}
func TestConvertFileObjectDefaults(t *testing.T) {
namespace := NewNamespace("testing")
config := composetypes.FileReferenceConfig{Source: "source"}
swarmRef, err := convertFileObject(namespace, config, lookupConfig)
require.NoError(t, err)
expected := swarmReferenceObject{
Name: "testing_source",
File: swarmReferenceTarget{
Name: config.Source,
UID: "0",
GID: "0",
Mode: os.FileMode(0444),
},
}
assert.Equal(t, expected, swarmRef)
}
func TestServiceConvertsIsolation(t *testing.T) {
src := composetypes.ServiceConfig{
Isolation: "hyperv",
}
result, err := Service("1.35", Namespace{name: "foo"}, src, nil, nil, nil, nil)
require.NoError(t, err)
assert.Equal(t, container.IsolationHyperV, result.TaskTemplate.ContainerSpec.Isolation)
}
func TestConvertServiceSecrets(t *testing.T) {
namespace := Namespace{name: "foo"}
secrets := []composetypes.ServiceSecretConfig{
{Source: "foo_secret"},
{Source: "bar_secret"},
}
secretSpecs := map[string]composetypes.SecretConfig{
"foo_secret": {
Name: "foo_secret",
},
"bar_secret": {
Name: "bar_secret",
},
}
client := &fakeClient{
secretListFunc: func(opts types.SecretListOptions) ([]swarm.Secret, error) {
assert.Contains(t, opts.Filters.Get("name"), "foo_secret")
assert.Contains(t, opts.Filters.Get("name"), "bar_secret")
return []swarm.Secret{
{Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "foo_secret"}}},
{Spec: swarm.SecretSpec{Annotations: swarm.Annotations{Name: "bar_secret"}}},
}, nil
},
}
refs, err := convertServiceSecrets(client, namespace, secrets, secretSpecs)
require.NoError(t, err)
expected := []*swarm.SecretReference{
{
SecretName: "bar_secret",
File: &swarm.SecretReferenceFileTarget{
Name: "bar_secret",
UID: "0",
GID: "0",
Mode: 0444,
},
},
{
SecretName: "foo_secret",
File: &swarm.SecretReferenceFileTarget{
Name: "foo_secret",
UID: "0",
GID: "0",
Mode: 0444,
},
},
}
require.Equal(t, expected, refs)
}
func TestConvertServiceConfigs(t *testing.T) {
namespace := Namespace{name: "foo"}
configs := []composetypes.ServiceConfigObjConfig{
{Source: "foo_config"},
{Source: "bar_config"},
}
configSpecs := map[string]composetypes.ConfigObjConfig{
"foo_config": {
Name: "foo_config",
},
"bar_config": {
Name: "bar_config",
},
}
client := &fakeClient{
configListFunc: func(opts types.ConfigListOptions) ([]swarm.Config, error) {
assert.Contains(t, opts.Filters.Get("name"), "foo_config")
assert.Contains(t, opts.Filters.Get("name"), "bar_config")
return []swarm.Config{
{Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "foo_config"}}},
{Spec: swarm.ConfigSpec{Annotations: swarm.Annotations{Name: "bar_config"}}},
}, nil
},
}
refs, err := convertServiceConfigObjs(client, namespace, configs, configSpecs)
require.NoError(t, err)
expected := []*swarm.ConfigReference{
{
ConfigName: "bar_config",
File: &swarm.ConfigReferenceFileTarget{
Name: "bar_config",
UID: "0",
GID: "0",
Mode: 0444,
},
},
{
ConfigName: "foo_config",
File: &swarm.ConfigReferenceFileTarget{
Name: "foo_config",
UID: "0",
GID: "0",
Mode: 0444,
},
},
}
require.Equal(t, expected, refs)
}
type fakeClient struct {
client.Client
secretListFunc func(types.SecretListOptions) ([]swarm.Secret, error)
configListFunc func(types.ConfigListOptions) ([]swarm.Config, error)
}
func (c *fakeClient) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {
if c.secretListFunc != nil {
return c.secretListFunc(options)
}
return []swarm.Secret{}, nil
}
func (c *fakeClient) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {
if c.configListFunc != nil {
return c.configListFunc(options)
}
return []swarm.Config{}, nil
}

View File

@ -68,16 +68,15 @@ func convertVolumeToMount(
result.VolumeOptions.NoCopy = volume.Volume.NoCopy
}
// External named volumes
if stackVolume.External.External {
result.Source = stackVolume.External.Name
return result, nil
}
if stackVolume.Name != "" {
result.Source = stackVolume.Name
}
// External named volumes
if stackVolume.External.External {
return result, nil
}
result.VolumeOptions.Labels = AddStackLabel(namespace, stackVolume.Labels)
if stackVolume.Driver != "" || stackVolume.DriverOpts != nil {
result.VolumeOptions.DriverConfig = &mount.Driver{

View File

@ -148,20 +148,16 @@ func TestConvertVolumeToMountNamedVolumeWithNameCustomizd(t *testing.T) {
func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) {
stackVolumes := volumes{
"outside": composetypes.VolumeConfig{
External: composetypes.External{
External: true,
Name: "special",
},
Name: "special",
External: composetypes.External{External: true},
},
}
namespace := NewNamespace("foo")
expected := mount.Mount{
Type: mount.TypeVolume,
Source: "special",
Target: "/foo",
VolumeOptions: &mount.VolumeOptions{
NoCopy: false,
},
Type: mount.TypeVolume,
Source: "special",
Target: "/foo",
VolumeOptions: &mount.VolumeOptions{NoCopy: false},
}
config := composetypes.ServiceVolumeConfig{
Type: "volume",
@ -176,10 +172,8 @@ func TestConvertVolumeToMountNamedVolumeExternal(t *testing.T) {
func TestConvertVolumeToMountNamedVolumeExternalNoCopy(t *testing.T) {
stackVolumes := volumes{
"outside": composetypes.VolumeConfig{
External: composetypes.External{
External: true,
Name: "special",
},
Name: "special",
External: composetypes.External{External: true},
},
}
namespace := NewNamespace("foo")

View File

@ -1,4 +1,4 @@
version: "3.4"
version: "3.5"
services:
foo:
@ -16,7 +16,6 @@ services:
labels: [FOO=BAR]
cap_add:
- ALL
@ -54,6 +53,13 @@ services:
reservations:
cpus: '0.0001'
memory: 20M
generic_resources:
- discrete_resource_spec:
kind: 'gpu'
value: 2
- discrete_resource_spec:
kind: 'ssd'
value: 1
restart_policy:
condition: on-failure
delay: 5s

View File

@ -12,6 +12,7 @@ import (
"github.com/docker/cli/cli/compose/template"
"github.com/docker/cli/cli/compose/types"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/versions"
"github.com/docker/go-connections/nat"
units "github.com/docker/go-units"
shellwords "github.com/mattn/go-shellwords"
@ -49,6 +50,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
}
configDict := getConfigDict(configDetails)
configDetails.Version = schema.Version(configDict)
if err := validateForbidden(configDict); err != nil {
return nil, err
@ -60,7 +62,7 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
return nil, err
}
if err := schema.Validate(configDict, schema.Version(configDict)); err != nil {
if err := schema.Validate(configDict, configDetails.Version); err != nil {
return nil, err
}
return loadSections(configDict, configDetails)
@ -96,28 +98,28 @@ func loadSections(config map[string]interface{}, configDetails types.ConfigDetai
{
key: "networks",
fnc: func(config map[string]interface{}) error {
cfg.Networks, err = LoadNetworks(config)
cfg.Networks, err = LoadNetworks(config, configDetails.Version)
return err
},
},
{
key: "volumes",
fnc: func(config map[string]interface{}) error {
cfg.Volumes, err = LoadVolumes(config)
cfg.Volumes, err = LoadVolumes(config, configDetails.Version)
return err
},
},
{
key: "secrets",
fnc: func(config map[string]interface{}) error {
cfg.Secrets, err = LoadSecrets(config, configDetails.WorkingDir)
cfg.Secrets, err = LoadSecrets(config, configDetails)
return err
},
},
{
key: "configs",
fnc: func(config map[string]interface{}) error {
cfg.Configs, err = LoadConfigObjs(config, configDetails.WorkingDir)
cfg.Configs, err = LoadConfigObjs(config, configDetails)
return err
},
},
@ -423,17 +425,30 @@ func transformUlimits(data interface{}) (interface{}, error) {
// LoadNetworks produces a NetworkConfig map from a compose file Dict
// the source Dict is not validated if directly used. Use Load() to enable validation
func LoadNetworks(source map[string]interface{}) (map[string]types.NetworkConfig, error) {
func LoadNetworks(source map[string]interface{}, version string) (map[string]types.NetworkConfig, error) {
networks := make(map[string]types.NetworkConfig)
err := transform(source, &networks)
if err != nil {
return networks, err
}
for name, network := range networks {
if network.External.External && network.External.Name == "" {
network.External.Name = name
networks[name] = network
if !network.External.External {
continue
}
switch {
case network.External.Name != "":
if network.Name != "" {
return nil, errors.Errorf("network %s: network.external.name and network.name conflict; only use network.name", name)
}
if versions.GreaterThanOrEqualTo(version, "3.5") {
logrus.Warnf("network %s: network.external.name is deprecated in favor of network.name", name)
}
network.Name = network.External.Name
network.External.Name = ""
case network.Name == "":
network.Name = name
}
networks[name] = network
}
return networks, nil
}
@ -446,76 +461,100 @@ func externalVolumeError(volume, key string) error {
// LoadVolumes produces a VolumeConfig map from a compose file Dict
// the source Dict is not validated if directly used. Use Load() to enable validation
func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, error) {
func LoadVolumes(source map[string]interface{}, version string) (map[string]types.VolumeConfig, error) {
volumes := make(map[string]types.VolumeConfig)
err := transform(source, &volumes)
if err != nil {
if err := transform(source, &volumes); err != nil {
return volumes, err
}
for name, volume := range volumes {
if volume.External.External {
if volume.Driver != "" {
return nil, externalVolumeError(name, "driver")
}
if len(volume.DriverOpts) > 0 {
return nil, externalVolumeError(name, "driver_opts")
}
if len(volume.Labels) > 0 {
return nil, externalVolumeError(name, "labels")
}
if volume.External.Name == "" {
volume.External.Name = name
volumes[name] = volume
} else {
logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name)
if volume.Name != "" {
return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name)
}
}
for name, volume := range volumes {
if !volume.External.External {
continue
}
switch {
case volume.Driver != "":
return nil, externalVolumeError(name, "driver")
case len(volume.DriverOpts) > 0:
return nil, externalVolumeError(name, "driver_opts")
case len(volume.Labels) > 0:
return nil, externalVolumeError(name, "labels")
case volume.External.Name != "":
if volume.Name != "" {
return nil, errors.Errorf("volume %s: volume.external.name and volume.name conflict; only use volume.name", name)
}
if versions.GreaterThanOrEqualTo(version, "3.4") {
logrus.Warnf("volume %s: volume.external.name is deprecated in favor of volume.name", name)
}
volume.Name = volume.External.Name
volume.External.Name = ""
case volume.Name == "":
volume.Name = name
}
volumes[name] = volume
}
return volumes, nil
}
// LoadSecrets produces a SecretConfig map from a compose file Dict
// the source Dict is not validated if directly used. Use Load() to enable validation
func LoadSecrets(source map[string]interface{}, workingDir string) (map[string]types.SecretConfig, error) {
func LoadSecrets(source map[string]interface{}, details types.ConfigDetails) (map[string]types.SecretConfig, error) {
secrets := make(map[string]types.SecretConfig)
if err := transform(source, &secrets); err != nil {
return secrets, err
}
for name, secret := range secrets {
if secret.External.External && secret.External.Name == "" {
secret.External.Name = name
secrets[name] = secret
}
if secret.File != "" {
secret.File = absPath(workingDir, secret.File)
obj, err := loadFileObjectConfig(name, "secret", types.FileObjectConfig(secret), details)
if err != nil {
return nil, err
}
secrets[name] = types.SecretConfig(obj)
}
return secrets, nil
}
// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict
// the source Dict is not validated if directly used. Use Load() to enable validation
func LoadConfigObjs(source map[string]interface{}, workingDir string) (map[string]types.ConfigObjConfig, error) {
func LoadConfigObjs(source map[string]interface{}, details types.ConfigDetails) (map[string]types.ConfigObjConfig, error) {
configs := make(map[string]types.ConfigObjConfig)
if err := transform(source, &configs); err != nil {
return configs, err
}
for name, config := range configs {
if config.External.External && config.External.Name == "" {
config.External.Name = name
configs[name] = config
}
if config.File != "" {
config.File = absPath(workingDir, config.File)
obj, err := loadFileObjectConfig(name, "config", types.FileObjectConfig(config), details)
if err != nil {
return nil, err
}
configs[name] = types.ConfigObjConfig(obj)
}
return configs, nil
}
func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig, details types.ConfigDetails) (types.FileObjectConfig, error) {
// if "external: true"
if obj.External.External {
// handle deprecated external.name
if obj.External.Name != "" {
if obj.Name != "" {
return obj, errors.Errorf("%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name", objType, name)
}
if versions.GreaterThanOrEqualTo(details.Version, "3.5") {
logrus.Warnf("%[1]s %[2]s: %[1]s.external.name is deprecated in favor of %[1]s.name", objType, name)
}
obj.Name = obj.External.Name
obj.External.Name = ""
} else {
if obj.Name == "" {
obj.Name = name
}
}
// if not "external: true"
} else {
obj.File = absPath(details.WorkingDir, obj.File)
}
return obj, nil
}
func absPath(workingDir string, filePath string) string {
if filepath.IsAbs(filePath) {
return filePath

View File

@ -1,6 +1,7 @@
package loader
import (
"bytes"
"fmt"
"io/ioutil"
"os"
@ -9,6 +10,7 @@ import (
"time"
"github.com/docker/cli/cli/compose/types"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -624,17 +626,18 @@ networks:
},
},
Configs: map[string]types.ConfigObjConfig{
"appconfig": {External: types.External{External: true, Name: "appconfig"}},
"appconfig": {External: types.External{External: true}, Name: "appconfig"},
},
Secrets: map[string]types.SecretConfig{
"super": {External: types.External{External: true, Name: "super"}},
"super": {External: types.External{External: true}, Name: "super"},
},
Volumes: map[string]types.VolumeConfig{
"data": {External: types.External{External: true, Name: "data"}},
"data": {External: types.External{External: true}, Name: "data"},
},
Networks: map[string]types.NetworkConfig{
"front": {
External: types.External{External: true, Name: "front"},
External: types.External{External: true},
Name: "front",
Internal: true,
Attachable: true,
},
@ -798,7 +801,7 @@ volumes:
assert.Contains(t, err.Error(), "external_volume")
}
func TestInvalidExternalNameAndNameCombination(t *testing.T) {
func TestLoadVolumeInvalidExternalNameAndNameCombination(t *testing.T) {
_, err := loadYAML(`
version: "3.4"
volumes:
@ -877,6 +880,20 @@ func TestFullExample(t *testing.T) {
Reservations: &types.Resource{
NanoCPUs: "0.0001",
MemoryBytes: 20 * 1024 * 1024,
GenericResources: []types.GenericResource{
{
DiscreteResourceSpec: &types.DiscreteGenericResource{
Kind: "gpu",
Value: 2,
},
},
{
DiscreteResourceSpec: &types.DiscreteGenericResource{
Kind: "ssd",
Value: 1,
},
},
},
},
},
RestartPolicy: &types.RestartPolicy{
@ -1156,17 +1173,13 @@ func TestFullExample(t *testing.T) {
},
"external-network": {
External: types.External{
Name: "external-network",
External: true,
},
Name: "external-network",
External: types.External{External: true},
},
"other-external-network": {
External: types.External{
Name: "my-cool-network",
External: true,
},
Name: "my-cool-network",
External: types.External{External: true},
},
}
@ -1190,23 +1203,16 @@ func TestFullExample(t *testing.T) {
},
},
"external-volume": {
External: types.External{
Name: "external-volume",
External: true,
},
Name: "external-volume",
External: types.External{External: true},
},
"other-external-volume": {
External: types.External{
Name: "my-cool-volume",
External: true,
},
Name: "my-cool-volume",
External: types.External{External: true},
},
"external-volume3": {
Name: "this-is-volume3",
External: types.External{
Name: "external-volume3",
External: true,
},
Name: "this-is-volume3",
External: types.External{External: true},
},
}
@ -1406,3 +1412,206 @@ services:
require.Len(t, config.Services, 1)
assert.Equal(t, expected, config.Services[0].ExtraHosts)
}
func TestLoadVolumesWarnOnDeprecatedExternalNameVersion34(t *testing.T) {
buf, cleanup := patchLogrus()
defer cleanup()
source := map[string]interface{}{
"foo": map[string]interface{}{
"external": map[string]interface{}{
"name": "oops",
},
},
}
volumes, err := LoadVolumes(source, "3.4")
require.NoError(t, err)
expected := map[string]types.VolumeConfig{
"foo": {
Name: "oops",
External: types.External{External: true},
},
}
assert.Equal(t, expected, volumes)
assert.Contains(t, buf.String(), "volume.external.name is deprecated")
}
func patchLogrus() (*bytes.Buffer, func()) {
buf := new(bytes.Buffer)
out := logrus.StandardLogger().Out
logrus.SetOutput(buf)
return buf, func() { logrus.SetOutput(out) }
}
func TestLoadVolumesWarnOnDeprecatedExternalNameVersion33(t *testing.T) {
buf, cleanup := patchLogrus()
defer cleanup()
source := map[string]interface{}{
"foo": map[string]interface{}{
"external": map[string]interface{}{
"name": "oops",
},
},
}
volumes, err := LoadVolumes(source, "3.3")
require.NoError(t, err)
expected := map[string]types.VolumeConfig{
"foo": {
Name: "oops",
External: types.External{External: true},
},
}
assert.Equal(t, expected, volumes)
assert.Equal(t, "", buf.String())
}
func TestLoadV35(t *testing.T) {
actual, err := loadYAML(`
version: "3.5"
services:
foo:
image: busybox
isolation: process
configs:
foo:
name: fooqux
external: true
bar:
name: barqux
file: ./example1.env
secrets:
foo:
name: fooqux
external: true
bar:
name: barqux
file: ./full-example.yml
`)
require.NoError(t, err)
assert.Len(t, actual.Services, 1)
assert.Len(t, actual.Secrets, 2)
assert.Len(t, actual.Configs, 2)
assert.Equal(t, "process", actual.Services[0].Isolation)
}
func TestLoadV35InvalidIsolation(t *testing.T) {
// validation should be done only on the daemon side
actual, err := loadYAML(`
version: "3.5"
services:
foo:
image: busybox
isolation: invalid
configs:
super:
external: true
`)
require.NoError(t, err)
require.Len(t, actual.Services, 1)
assert.Equal(t, "invalid", actual.Services[0].Isolation)
}
func TestLoadSecretInvalidExternalNameAndNameCombination(t *testing.T) {
_, err := loadYAML(`
version: "3.5"
secrets:
external_secret:
name: user_specified_name
external:
name: external_name
`)
require.Error(t, err)
assert.Contains(t, err.Error(), "secret.external.name and secret.name conflict; only use secret.name")
assert.Contains(t, err.Error(), "external_secret")
}
func TestLoadSecretsWarnOnDeprecatedExternalNameVersion35(t *testing.T) {
buf, cleanup := patchLogrus()
defer cleanup()
source := map[string]interface{}{
"foo": map[string]interface{}{
"external": map[string]interface{}{
"name": "oops",
},
},
}
details := types.ConfigDetails{
Version: "3.5",
}
secrets, err := LoadSecrets(source, details)
require.NoError(t, err)
expected := map[string]types.SecretConfig{
"foo": {
Name: "oops",
External: types.External{External: true},
},
}
assert.Equal(t, expected, secrets)
assert.Contains(t, buf.String(), "secret.external.name is deprecated")
}
func TestLoadNetworksWarnOnDeprecatedExternalNameVersion35(t *testing.T) {
buf, cleanup := patchLogrus()
defer cleanup()
source := map[string]interface{}{
"foo": map[string]interface{}{
"external": map[string]interface{}{
"name": "oops",
},
},
}
networks, err := LoadNetworks(source, "3.5")
require.NoError(t, err)
expected := map[string]types.NetworkConfig{
"foo": {
Name: "oops",
External: types.External{External: true},
},
}
assert.Equal(t, expected, networks)
assert.Contains(t, buf.String(), "network.external.name is deprecated")
}
func TestLoadNetworksWarnOnDeprecatedExternalNameVersion34(t *testing.T) {
buf, cleanup := patchLogrus()
defer cleanup()
source := map[string]interface{}{
"foo": map[string]interface{}{
"external": map[string]interface{}{
"name": "oops",
},
},
}
networks, err := LoadNetworks(source, "3.4")
require.NoError(t, err)
expected := map[string]types.NetworkConfig{
"foo": {
Name: "oops",
External: types.External{External: true},
},
}
assert.Equal(t, expected, networks)
assert.Equal(t, "", buf.String())
}
func TestLoadNetworkInvalidExternalNameAndNameCombination(t *testing.T) {
_, err := loadYAML(`
version: "3.5"
networks:
foo:
name: user_specified_name
external:
name: external_name
`)
require.Error(t, err)
assert.Contains(t, err.Error(), "network.external.name and network.name conflict; only use network.name")
assert.Contains(t, err.Error(), "foo")
}

File diff suppressed because one or more lines are too long

View File

@ -262,7 +262,8 @@
"nocopy": {"type": "boolean"}
}
}
}
},
"additionalProperties": false
}
],
"uniqueItems": true

View File

@ -296,7 +296,8 @@
"nocopy": {"type": "boolean"}
}
}
}
},
"additionalProperties": false
}
],
"uniqueItems": true

View File

@ -299,7 +299,8 @@
"nocopy": {"type": "boolean"}
}
}
}
},
"additionalProperties": false
}
],
"uniqueItems": true

View File

@ -0,0 +1,573 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v3.5.json",
"type": "object",
"required": ["version"],
"properties": {
"version": {
"type": "string"
},
"services": {
"id": "#/properties/services",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service"
}
},
"additionalProperties": false
},
"networks": {
"id": "#/properties/networks",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/network"
}
}
},
"volumes": {
"id": "#/properties/volumes",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/volume"
}
},
"additionalProperties": false
},
"secrets": {
"id": "#/properties/secrets",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/secret"
}
},
"additionalProperties": false
},
"configs": {
"id": "#/properties/configs",
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/config"
}
},
"additionalProperties": false
}
},
"patternProperties": {"^x-": {}},
"additionalProperties": false,
"definitions": {
"service": {
"id": "#/definitions/service",
"type": "object",
"properties": {
"deploy": {"$ref": "#/definitions/deployment"},
"build": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"context": {"type": "string"},
"dockerfile": {"type": "string"},
"args": {"$ref": "#/definitions/list_or_dict"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"cache_from": {"$ref": "#/definitions/list_of_strings"},
"network": {"type": "string"},
"target": {"type": "string"},
"shm_size": {"type": ["integer", "string"]}
},
"additionalProperties": false
}
]
},
"cap_add": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cap_drop": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"cgroup_parent": {"type": "string"},
"command": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"configs": {
"type": "array",
"items": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"source": {"type": "string"},
"target": {"type": "string"},
"uid": {"type": "string"},
"gid": {"type": "string"},
"mode": {"type": "number"}
}
}
]
}
},
"container_name": {"type": "string"},
"credential_spec": {"type": "object", "properties": {
"file": {"type": "string"},
"registry": {"type": "string"}
}},
"depends_on": {"$ref": "#/definitions/list_of_strings"},
"devices": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"dns": {"$ref": "#/definitions/string_or_list"},
"dns_search": {"$ref": "#/definitions/string_or_list"},
"domainname": {"type": "string"},
"entrypoint": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"env_file": {"$ref": "#/definitions/string_or_list"},
"environment": {"$ref": "#/definitions/list_or_dict"},
"expose": {
"type": "array",
"items": {
"type": ["string", "number"],
"format": "expose"
},
"uniqueItems": true
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/list_or_dict"},
"healthcheck": {"$ref": "#/definitions/healthcheck"},
"hostname": {"type": "string"},
"image": {"type": "string"},
"ipc": {"type": "string"},
"isolation": {"type": "string"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"options": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number", "null"]}
}
}
},
"additionalProperties": false
},
"mac_address": {"type": "string"},
"network_mode": {"type": "string"},
"networks": {
"oneOf": [
{"$ref": "#/definitions/list_of_strings"},
{
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"oneOf": [
{
"type": "object",
"properties": {
"aliases": {"$ref": "#/definitions/list_of_strings"},
"ipv4_address": {"type": "string"},
"ipv6_address": {"type": "string"}
},
"additionalProperties": false
},
{"type": "null"}
]
}
},
"additionalProperties": false
}
]
},
"pid": {"type": ["string", "null"]},
"ports": {
"type": "array",
"items": {
"oneOf": [
{"type": "number", "format": "ports"},
{"type": "string", "format": "ports"},
{
"type": "object",
"properties": {
"mode": {"type": "string"},
"target": {"type": "integer"},
"published": {"type": "integer"},
"protocol": {"type": "string"}
},
"additionalProperties": false
}
]
},
"uniqueItems": true
},
"privileged": {"type": "boolean"},
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"security_opt": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"shm_size": {"type": ["number", "string"]},
"secrets": {
"type": "array",
"items": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"properties": {
"source": {"type": "string"},
"target": {"type": "string"},
"uid": {"type": "string"},
"gid": {"type": "string"},
"mode": {"type": "number"}
}
}
]
}
},
"sysctls": {"$ref": "#/definitions/list_or_dict"},
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {
"type": "object",
"patternProperties": {
"^[a-z]+$": {
"oneOf": [
{"type": "integer"},
{
"type":"object",
"properties": {
"hard": {"type": "integer"},
"soft": {"type": "integer"}
},
"required": ["soft", "hard"],
"additionalProperties": false
}
]
}
}
},
"user": {"type": "string"},
"userns_mode": {"type": "string"},
"volumes": {
"type": "array",
"items": {
"oneOf": [
{"type": "string"},
{
"type": "object",
"required": ["type"],
"properties": {
"type": {"type": "string"},
"source": {"type": "string"},
"target": {"type": "string"},
"read_only": {"type": "boolean"},
"consistency": {"type": "string"},
"bind": {
"type": "object",
"properties": {
"propagation": {"type": "string"}
}
},
"volume": {
"type": "object",
"properties": {
"nocopy": {"type": "boolean"}
}
}
},
"additionalProperties": false
}
],
"uniqueItems": true
}
},
"working_dir": {"type": "string"}
},
"additionalProperties": false
},
"healthcheck": {
"id": "#/definitions/healthcheck",
"type": "object",
"additionalProperties": false,
"properties": {
"disable": {"type": "boolean"},
"interval": {"type": "string", "format": "duration"},
"retries": {"type": "number"},
"test": {
"oneOf": [
{"type": "string"},
{"type": "array", "items": {"type": "string"}}
]
},
"timeout": {"type": "string", "format": "duration"},
"start_period": {"type": "string", "format": "duration"}
}
},
"deployment": {
"id": "#/definitions/deployment",
"type": ["object", "null"],
"properties": {
"mode": {"type": "string"},
"endpoint_mode": {"type": "string"},
"replicas": {"type": "integer"},
"labels": {"$ref": "#/definitions/list_or_dict"},
"update_config": {
"type": "object",
"properties": {
"parallelism": {"type": "integer"},
"delay": {"type": "string", "format": "duration"},
"failure_action": {"type": "string"},
"monitor": {"type": "string", "format": "duration"},
"max_failure_ratio": {"type": "number"},
"order": {"type": "string", "enum": [
"start-first", "stop-first"
]}
},
"additionalProperties": false
},
"resources": {
"type": "object",
"properties": {
"limits": {
"type": "object",
"properties": {
"cpus": {"type": "string"},
"memory": {"type": "string"}
},
"additionalProperties": false
},
"reservations": {
"type": "object",
"properties": {
"cpus": {"type": "string"},
"memory": {"type": "string"},
"generic_resources": {"$ref": "#/definitions/generic_resources"}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"restart_policy": {
"type": "object",
"properties": {
"condition": {"type": "string"},
"delay": {"type": "string", "format": "duration"},
"max_attempts": {"type": "integer"},
"window": {"type": "string", "format": "duration"}
},
"additionalProperties": false
},
"placement": {
"type": "object",
"properties": {
"constraints": {"type": "array", "items": {"type": "string"}},
"preferences": {
"type": "array",
"items": {
"type": "object",
"properties": {
"spread": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"generic_resources": {
"id": "#/definitions/generic_resources",
"type": "array",
"items": {
"type": "object",
"properties": {
"discrete_resource_spec": {
"type": "object",
"properties": {
"kind": {"type": "string"},
"value": {"type": "number"}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"network": {
"id": "#/definitions/network",
"type": ["object", "null"],
"properties": {
"name": {"type": "string"},
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"ipam": {
"type": "object",
"properties": {
"driver": {"type": "string"},
"config": {
"type": "array",
"items": {
"type": "object",
"properties": {
"subnet": {"type": "string"}
},
"additionalProperties": false
}
}
},
"additionalProperties": false
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"internal": {"type": "boolean"},
"attachable": {"type": "boolean"},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"volume": {
"id": "#/definitions/volume",
"type": ["object", "null"],
"properties": {
"name": {"type": "string"},
"driver": {"type": "string"},
"driver_opts": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number"]}
}
},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
},
"additionalProperties": false
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"secret": {
"id": "#/definitions/secret",
"type": "object",
"properties": {
"name": {"type": "string"},
"file": {"type": "string"},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
}
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"config": {
"id": "#/definitions/config",
"type": "object",
"properties": {
"name": {"type": "string"},
"file": {"type": "string"},
"external": {
"type": ["boolean", "object"],
"properties": {
"name": {"type": "string"}
}
},
"labels": {"$ref": "#/definitions/list_or_dict"}
},
"additionalProperties": false
},
"string_or_list": {
"oneOf": [
{"type": "string"},
{"$ref": "#/definitions/list_of_strings"}
]
},
"list_of_strings": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": true
},
"list_or_dict": {
"oneOf": [
{
"type": "object",
"patternProperties": {
".+": {
"type": ["string", "number", "null"]
}
},
"additionalProperties": false
},
{"type": "array", "items": {"type": "string"}, "uniqueItems": true}
]
},
"constraints": {
"service": {
"id": "#/definitions/constraints/service",
"anyOf": [
{"required": ["build"]},
{"required": ["image"]}
],
"properties": {
"build": {
"required": ["context"]
}
}
}
}
}
}

View File

@ -46,6 +46,25 @@ func TestValidateAllowsXTopLevelFields(t *testing.T) {
assert.NoError(t, err)
}
func TestValidateSecretConfigNames(t *testing.T) {
config := dict{
"version": "3.5",
"configs": dict{
"bar": dict{
"name": "foobar",
},
},
"secrets": dict{
"baz": dict{
"name": "foobaz",
},
},
}
err := Validate(config, "3.5")
assert.NoError(t, err)
}
func TestValidateInvalidVersion(t *testing.T) {
config := dict{
"version": "2.1",
@ -84,3 +103,16 @@ func TestValidatePlacement(t *testing.T) {
assert.NoError(t, Validate(config, "3.3"))
}
func TestValidateIsolation(t *testing.T) {
config := dict{
"version": "3.5",
"services": dict{
"foo": dict{
"image": "busybox",
"isolation": "some-isolation-value",
},
},
}
assert.NoError(t, Validate(config, "3.5"))
}

View File

@ -55,6 +55,7 @@ type ConfigFile struct {
// ConfigDetails are the details about a group of ConfigFiles
type ConfigDetails struct {
Version string
WorkingDir string
ConfigFiles []ConfigFile
Environment map[string]string
@ -125,6 +126,7 @@ type ServiceConfig struct {
User string
Volumes []ServiceVolumeConfig
WorkingDir string `mapstructure:"working_dir"`
Isolation string `mapstructure:"isolation"`
}
// BuildConfig is a type for build
@ -215,8 +217,24 @@ type Resources struct {
// Resource is a resource to be limited or reserved
type Resource struct {
// TODO: types to convert from units and ratios
NanoCPUs string `mapstructure:"cpus"`
MemoryBytes UnitBytes `mapstructure:"memory"`
NanoCPUs string `mapstructure:"cpus"`
MemoryBytes UnitBytes `mapstructure:"memory"`
GenericResources []GenericResource `mapstructure:"generic_resources"`
}
// GenericResource represents a "user defined" resource which can
// only be an integer (e.g: SSD=3) for a service
type GenericResource struct {
DiscreteResourceSpec *DiscreteGenericResource `mapstructure:"discrete_resource_spec"`
}
// DiscreteGenericResource represents a "user defined" resource which is defined
// as an integer
// "Kind" is used to describe the Kind of a resource (e.g: "GPU", "FPGA", "SSD", ...)
// Value is used to count the resource (SSD=5, HDD=3, ...)
type DiscreteGenericResource struct {
Kind string
Value int64
}
// UnitBytes is the bytes type
@ -277,7 +295,8 @@ type ServiceVolumeVolume struct {
NoCopy bool `mapstructure:"nocopy"`
}
type fileReferenceConfig struct {
// FileReferenceConfig for a reference to a swarm file object
type FileReferenceConfig struct {
Source string
Target string
UID string
@ -286,10 +305,10 @@ type fileReferenceConfig struct {
}
// ServiceConfigObjConfig is the config obj configuration for a service
type ServiceConfigObjConfig fileReferenceConfig
type ServiceConfigObjConfig FileReferenceConfig
// ServiceSecretConfig is the secret configuration for a service
type ServiceSecretConfig fileReferenceConfig
type ServiceSecretConfig FileReferenceConfig
// UlimitsConfig the ulimit configuration
type UlimitsConfig struct {
@ -300,6 +319,7 @@ type UlimitsConfig struct {
// NetworkConfig for a network
type NetworkConfig struct {
Name string
Driver string
DriverOpts map[string]string `mapstructure:"driver_opts"`
Ipam IPAMConfig
@ -343,14 +363,16 @@ type CredentialSpecConfig struct {
Registry string
}
type fileObjectConfig struct {
// FileObjectConfig is a config type for a file used by a service
type FileObjectConfig struct {
Name string
File string
External External
Labels Labels
}
// SecretConfig for a secret
type SecretConfig fileObjectConfig
type SecretConfig FileObjectConfig
// ConfigObjConfig is the config for the swarm "Config" object
type ConfigObjConfig fileObjectConfig
type ConfigObjConfig FileObjectConfig

View File

@ -177,7 +177,7 @@ func (configFile *ConfigFile) Save() error {
return configFile.SaveToWriter(f)
}
// ParseProxyConfig computes proxy configuration by retreiving the config for the provided host and
// ParseProxyConfig computes proxy configuration by retrieving the config for the provided host and
// then checking this against any environment variables provided to the container
func (configFile *ConfigFile) ParseProxyConfig(host string, runOpts []string) map[string]*string {
var cfgKey string

View File

@ -127,7 +127,7 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo
}
// Skip configuration headers since request is not going to Docker daemon
modifiers := registry.DockerHeaders(userAgent, http.Header{})
modifiers := registry.Headers(userAgent, http.Header{})
authTransport := transport.NewTransport(base, modifiers...)
pingClient := &http.Client{
Transport: authTransport,
@ -299,7 +299,7 @@ type ImageRefAndAuth struct {
}
// GetImageReferencesAndAuth retrieves the necessary reference and auth information for an image name
// as a ImageRefAndAuth struct
// as an ImageRefAndAuth struct
func GetImageReferencesAndAuth(ctx context.Context, authResolver func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig, imgName string) (ImageRefAndAuth, error) {
ref, err := reference.ParseNormalizedNamed(imgName)
if err != nil {

View File

@ -3,7 +3,8 @@ package cli
// Default build-time variable.
// These values are overriding via ldflags
var (
Version = "unknown-version"
GitCommit = "unknown-commit"
BuildTime = "unknown-buildtime"
PlatformName = ""
Version = "unknown-version"
GitCommit = "unknown-commit"
BuildTime = "unknown-buildtime"
)

View File

@ -1,29 +0,0 @@
// +build !daemon
package main
import (
"fmt"
"runtime"
"strings"
"github.com/spf13/cobra"
)
func newDaemonCommand() *cobra.Command {
return &cobra.Command{
Use: "daemon",
Hidden: true,
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runDaemon()
},
}
}
func runDaemon() error {
return fmt.Errorf(
"`docker daemon` is not supported on %s. Please run `dockerd` directly",
strings.Title(runtime.GOOS))
}

View File

@ -1,17 +0,0 @@
// +build !daemon
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDaemonCommand(t *testing.T) {
cmd := newDaemonCommand()
cmd.SetArgs([]string{"--version"})
err := cmd.Execute()
assert.EqualError(t, err, "Please run `dockerd`")
}

View File

@ -1,33 +0,0 @@
// +build daemon
package main
import (
"io/ioutil"
"testing"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
func stubRun(cmd *cobra.Command, args []string) error {
return nil
}
func TestDaemonCommandHelp(t *testing.T) {
cmd := newDaemonCommand()
cmd.RunE = stubRun
cmd.SetArgs([]string{"--help"})
cmd.SetOutput(ioutil.Discard)
err := cmd.Execute()
assert.NoError(t, err)
}
func TestDaemonCommand(t *testing.T) {
cmd := newDaemonCommand()
cmd.RunE = stubRun
cmd.SetArgs([]string{"--containerd", "/foo"})
cmd.SetOutput(ioutil.Discard)
err := cmd.Execute()
assert.NoError(t, err)
}

View File

@ -1,79 +0,0 @@
// +build daemon
package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"syscall"
"github.com/spf13/cobra"
)
const daemonBinary = "dockerd"
func newDaemonCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "daemon",
Hidden: true,
Args: cobra.ArbitraryArgs,
DisableFlagParsing: true,
RunE: func(cmd *cobra.Command, args []string) error {
return runDaemon()
},
Deprecated: "and will be removed in Docker 17.12. Please run `dockerd` directly.",
}
cmd.SetHelpFunc(helpFunc)
return cmd
}
// CmdDaemon execs dockerd with the same flags
func runDaemon() error {
// Use os.Args[1:] so that "global" args are passed to dockerd
return execDaemon(stripDaemonArg(os.Args[1:]))
}
func execDaemon(args []string) error {
binaryPath, err := findDaemonBinary()
if err != nil {
return err
}
return syscall.Exec(
binaryPath,
append([]string{daemonBinary}, args...),
os.Environ())
}
func helpFunc(cmd *cobra.Command, args []string) {
if err := execDaemon([]string{"--help"}); err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
}
}
// findDaemonBinary looks for the path to the dockerd binary starting with
// the directory of the current executable (if one exists) and followed by $PATH
func findDaemonBinary() (string, error) {
execDirname := filepath.Dir(os.Args[0])
if execDirname != "" {
binaryPath := filepath.Join(execDirname, daemonBinary)
if _, err := os.Stat(binaryPath); err == nil {
return binaryPath, nil
}
}
return exec.LookPath(daemonBinary)
}
// stripDaemonArg removes the `daemon` argument from the list
func stripDaemonArg(args []string) []string {
for i, arg := range args {
if arg == "daemon" {
return append(args[:i], args[i+1:]...)
}
}
return args
}

View File

@ -39,10 +39,6 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
return command.ShowHelp(dockerCli.Err())(cmd, args)
},
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// daemon command is special, we redirect directly to another binary
if cmd.Name() == "daemon" {
return nil
}
// flags must be the top-level command flags, not cmd.Flags()
opts.Common.SetDefaultOptions(flags)
dockerPreRun(opts)
@ -64,7 +60,6 @@ func newDockerCommand(dockerCli *command.DockerCli) *cobra.Command {
setHelpFunc(dockerCli, cmd, flags, opts)
cmd.SetOutput(dockerCli.Out())
cmd.AddCommand(newDaemonCommand())
commands.AddCommands(cmd, dockerCli)
setValidateArgs(dockerCli, cmd, flags, opts)

View File

@ -833,14 +833,14 @@ __docker_complete_log_options() {
local common_options2="env env-regex labels"
# awslogs does not implement the $common_options2.
local awslogs_options="$common_options1 awslogs-create-group awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag"
local awslogs_options="$common_options1 awslogs-create-group awslogs-credentials-endpoint awslogs-datetime-format awslogs-group awslogs-multiline-pattern awslogs-region awslogs-stream tag"
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries tag"
local fluentd_options="$common_options1 $common_options2 fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries fluentd-sub-second-precision tag"
local gcplogs_options="$common_options1 $common_options2 gcp-log-cmd gcp-meta-id gcp-meta-name gcp-meta-zone gcp-project"
local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type tag"
local gelf_options="$common_options1 $common_options2 gelf-address gelf-compression-level gelf-compression-type gelf-tcp-max-reconnect gelf-tcp-reconnect-delay tag"
local journald_options="$common_options1 $common_options2 tag"
local json_file_options="$common_options1 $common_options2 max-file max-size"
local logentries_options="$common_options1 $common_options2 logentries-token tag"
local logentries_options="$common_options1 $common_options2 line-only logentries-token tag"
local splunk_options="$common_options1 $common_options2 splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag"
local syslog_options="$common_options1 $common_options2 syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag"
@ -892,12 +892,21 @@ __docker_complete_log_driver_options() {
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
awslogs-credentials-endpoint)
COMPREPLY=( $( compgen -W "/" -- "${cur##*=}" ) )
__docker_nospace
return
;;
fluentd-async-connect)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
fluentd-sub-second-precision)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
gelf-address)
COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) )
COMPREPLY=( $( compgen -W "tcp udp" -S "://" -- "${cur##*=}" ) )
__docker_nospace
return
;;
@ -909,6 +918,10 @@ __docker_complete_log_driver_options() {
COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) )
return
;;
line-only)
COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) )
return
;;
mode)
COMPREPLY=( $( compgen -W "blocking non-blocking" -- "${cur##*=}" ) )
return
@ -1430,11 +1443,14 @@ _docker_container_exec() {
__docker_complete_user_group
return
;;
--workdir|-w)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--detach -d --detach-keys --env -e --help --interactive -i --privileged -t --tty -u --user --workdir -w" -- "$cur" ) )
;;
*)
__docker_complete_containers_running
@ -1487,17 +1503,17 @@ _docker_container_kill() {
_docker_container_logs() {
case "$prev" in
--since|--tail)
--since|--tail|--until)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--details --follow -f --help --since --tail --timestamps -t --until" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag '--since|--tail')
local counter=$(__docker_pos_first_nonflag '--since|--tail|--until')
if [ "$cword" -eq "$counter" ]; then
__docker_complete_containers_all
fi
@ -1763,6 +1779,9 @@ _docker_container_run_and_create() {
--io-maxiops
--isolation
"
__docker_daemon_is_experimental && options_with_args+="
--platform
"
local boolean_options="
--disable-content-trust=false
@ -2467,7 +2486,15 @@ _docker_image_build() {
--quiet -q
--rm
"
__docker_daemon_is_experimental && boolean_options+="--squash"
if __docker_daemon_is_experimental ; then
options_with_args+="
--platform
"
boolean_options+="
--squash
--stream
"
fi
local all_options="$options_with_args $boolean_options"
@ -2679,12 +2706,21 @@ _docker_image_prune() {
}
_docker_image_pull() {
case "$prev" in
--platform)
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all-tags -a --disable-content-trust=false --help" -- "$cur" ) )
local options="--all-tags -a --disable-content-trust=false --help"
__docker_daemon_is_experimental && options+=" --platform"
COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
local counter=$(__docker_pos_first_nonflag --platform)
if [ "$cword" -eq "$counter" ]; then
for arg in "${COMP_WORDS[@]}"; do
case "$arg" in
@ -3305,6 +3341,7 @@ _docker_service_update_and_create() {
--health-start-period
--health-timeout
--hostname
--isolation
--label -l
--limit-cpu
--limit-memory
@ -3493,6 +3530,10 @@ _docker_service_update_and_create() {
__docker_nospace
return
;;
--isolation)
__docker_complete_isolation
return
;;
--log-driver)
__docker_complete_log_drivers
return
@ -4510,7 +4551,7 @@ _docker_system() {
info
prune
"
__docker_subcommands "$subcommands $aliases" && return
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
@ -4665,6 +4706,68 @@ _docker_tag() {
_docker_image_tag
}
_docker_trust() {
local subcommands="
revoke
sign
view
"
__docker_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_docker_trust_revoke() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --yes -y" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
fi
;;
esac
}
_docker_trust_sign() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help --local" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
fi
;;
esac
}
_docker_trust_view() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
local counter=$(__docker_pos_first_nonflag)
if [ "$cword" -eq "$counter" ]; then
__docker_complete_images
fi
;;
esac
}
_docker_unpause() {
_docker_container_unpause
}
@ -4892,6 +4995,7 @@ _docker() {
local experimental_commands=(
checkpoint
deploy
trust
)
local commands=(${management_commands[*]} ${top_level_commands[*]})

View File

@ -174,6 +174,7 @@ complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s d -l detach -d
complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -l help -d 'Print usage'
complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s i -l interactive -d 'Keep STDIN open even if not attached'
complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s t -l tty -d 'Allocate a pseudo-TTY'
complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -s w -l workdir -d 'Working directory inside the container'
complete -c docker -A -f -n '__fish_seen_subcommand_from exec' -a '(__fish_print_docker_containers running)' -d "Container"
# export

View File

@ -226,7 +226,7 @@ __docker_get_log_options() {
common_options=("max-buffer-size" "mode")
common_options2=("env" "env-regex" "labels")
awslogs_options=($common_options "awslogs-create-group" "awslogs-datetime-format" "awslogs-group" "awslogs-multiline-pattern" "awslogs-region" "awslogs-stream" "tag")
fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "tag")
fluentd_options=($common_options $common_options2 "fluentd-address" "fluentd-async-connect" "fluentd-buffer-limit" "fluentd-retry-wait" "fluentd-max-retries" "fluentd-sub-second-precision" "tag")
gcplogs_options=($common_options $common_options2 "gcp-log-cmd" "gcp-meta-id" "gcp-meta-name" "gcp-meta-zone" "gcp-project")
gelf_options=($common_options $common_options2 "gelf-address" "gelf-compression-level" "gelf-compression-type" "tag")
journald_options=($common_options $common_options2 "tag")
@ -745,6 +745,7 @@ __docker_container_subcommand() {
"($help)--privileged[Give extended Linux capabilities to the command]" \
"($help -t --tty)"{-t,--tty}"[Allocate a pseudo-tty]" \
"($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users" \
"($help -w --workdir)"{-w=,--workdir=}"[Working directory inside the container]:directory:_directories"
"($help -):containers:__docker_complete_running_containers" \
"($help -)*::command:->anycommand" && ret=0
case $state in
@ -1393,7 +1394,7 @@ __docker_nodes() {
# Names
if [[ $type = (names|all) ]]; then
for line in $lines; do
s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
s="${line[${begin[HOSTNAME]},${end[HOSTNAME]}]%% ##}"
nodes=($nodes $s)
done
fi
@ -1955,6 +1956,7 @@ __docker_service_subcommand() {
"($help)--health-retries=[Consecutive failures needed to report unhealthy]:retries:(1 2 3 4 5)"
"($help)--health-timeout=[Maximum time to allow one check to run]:time: "
"($help)--hostname=[Service container hostname]:hostname: " \
"($help)--isolation=[Service container isolation mode]:isolation:(default process hyperv)" \
"($help)*--label=[Service labels]:label: "
"($help)--limit-cpu=[Limit CPUs]:value: "
"($help)--limit-memory=[Limit Memory]:value: "
@ -2168,9 +2170,9 @@ __docker_stacks() {
end[${header[$i,$((j-1))]}]=-1
lines=(${lines[2,-1]})
# Service ID
# Service NAME
for line in $lines; do
s="${line[${begin[ID]},${end[ID]}]%% ##}"
s="${line[${begin[NAME]},${end[NAME]}]%% ##}"
stacks=($stacks $s)
done

View File

@ -10,7 +10,7 @@ CROSS_IMAGE_NAME = docker-cli-cross$(IMAGE_TAG)
VALIDATE_IMAGE_NAME = docker-cli-shell-validate$(IMAGE_TAG)
MOUNTS = -v "$(CURDIR)":/go/src/github.com/docker/cli
VERSION = $(shell cat VERSION)
ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT
ENVVARS = -e VERSION=$(VERSION) -e GITCOMMIT -e PLATFORM
# build docker image (dockerfiles/Dockerfile.build)
.PHONY: build_docker_image

View File

@ -1,3 +1,3 @@
FROM dockercore/golang-cross@sha256:8a347b3692ba925dcef753f2de289e11774410c1bc752b9d525cb05477a7697b
FROM dockercore/golang-cross@sha256:2e843a0e4d82b6bab34d2cb7abe26d1a6cda23226ecc3869100c8db553603f9b
ENV DISABLE_WARN_OUTSIDE_CONTAINER=1
WORKDIR /go/src/github.com/docker/cli

View File

@ -1,5 +1,5 @@
FROM golang:1.8.4-alpine3.6
FROM golang:1.9.2-alpine3.6
RUN apk add -U git make bash coreutils ca-certificates

View File

@ -1,4 +1,4 @@
FROM golang:1.8.4-alpine3.6
FROM golang:1.9.2-alpine3.6
RUN apk add -U git

View File

@ -81,7 +81,7 @@ The `filter` param to filter the list of image by reference (name or name:tag) i
### `docker daemon` subcommand
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
**Target For Removal In Release: v17.12**
**Removed In Release: v17.12**
The daemon is moved to a separate binary (`dockerd`), and should be used instead.

View File

@ -126,7 +126,7 @@ Config provides the base accessible fields for working with V0 plugin format
- **`propagatedMount`** *string*
path to be mounted as rshared, so that mounts under that path are visible to docker. This is useful for volume plugins.
This path will be bind-mounted outisde of the plugin rootfs so it's contents
This path will be bind-mounted outside of the plugin rootfs so it's contents
are preserved on upgrade.
- **`env`** *PluginEnv array*

View File

@ -65,7 +65,7 @@ The sections below provide an inexhaustive overview of available plugins.
| [Convoy plugin](https://github.com/rancher/convoy) | A volume plugin for a variety of storage back-ends including device mapper and NFS. It's a simple standalone executable written in Go and provides the framework to support vendor-specific extensions such as snapshots, backups and restore. |
| [DigitalOcean Block Storage plugin](https://github.com/omallo/docker-volume-plugin-dostorage) | Integrates DigitalOcean's [block storage solution](https://www.digitalocean.com/products/storage/) into the Docker ecosystem by automatically attaching a given block storage volume to a DigitalOcean droplet and making the contents of the volume available to Docker containers running on that droplet. |
| [DRBD plugin](https://www.drbd.org/en/supported-projects/docker) | A volume plugin that provides highly available storage replicated by [DRBD](https://www.drbd.org). Data written to the docker volume is replicated in a cluster of DRBD nodes. |
| [Flocker plugin](https://clusterhq.com/docker-plugin/) | A volume plugin that provides multi-host portable volumes for Docker, enabling you to run databases and other stateful containers and move them around across a cluster of machines. |
| [Flocker plugin](https://github.com/ScatterHQ/flocker) | A volume plugin that provides multi-host portable volumes for Docker, enabling you to run databases and other stateful containers and move them around across a cluster of machines. |
| [Fuxi Volume Plugin](https://github.com/openstack/fuxi) | A volume plugin that is developed as part of the OpenStack Kuryr project and implements the Docker volume plugin API by utilizing Cinder, the OpenStack block storage service. |
| [gce-docker plugin](https://github.com/mcuadros/gce-docker) | A volume plugin able to attach, format and mount Google Compute [persistent-disks](https://cloud.google.com/compute/docs/disks/persistent-disks). |
| [GlusterFS plugin](https://github.com/calavera/docker-volume-glusterfs) | A volume plugin that provides multi-host volumes management for Docker using GlusterFS. |

View File

@ -199,7 +199,7 @@ Request the path to the volume with the given `volume_name`.
```json
{
"Mountpoin": "/path/to/directory/on/host",
"Mountpoint": "/path/to/directory/on/host",
"Err": ""
}
```

View File

@ -765,7 +765,7 @@ type of documentation between the person who builds the image and the person who
runs the container, about which ports are intended to be published. To actually
publish the port when running the container, use the `-p` flag on `docker run`
to publish and map one or more ports, or the `-P` flag to publish all exposed
ports and map them to to high-order ports.
ports and map them to high-order ports.
To set up port redirection on the host system, see [using the -P
flag](run.md#expose-incoming-ports). The `docker network` command supports
@ -823,16 +823,23 @@ change them using `docker run --env <key>=<value>`.
ADD has two forms:
- `ADD <src>... <dest>`
- `ADD ["<src>",... "<dest>"]` (this form is required for paths containing
- `ADD [--chown=<user>:<group>] <src>... <dest>`
- `ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]` (this form is required for paths containing
whitespace)
> **Note**:
> The `--chown` feature is only supported on Dockerfiles used to build Linux containers,
> and will not work on Windows containers. Since user and group ownership concepts do
> not translate between Linux and Windows, the use of `/etc/passwd` and `/etc/group` for
> translating user and group names to IDs restricts this feature to only be viable for
> for Linux OS-based containers.
The `ADD` instruction copies new files, directories or remote file URLs from `<src>`
and adds them to the filesystem of the image at the path `<dest>`.
Multiple `<src>` resource may be specified but if they are files or
directories then they must be relative to the source directory that is
being built (the context of the build).
Multiple `<src>` resources may be specified but if they are files or
directories, their paths are interpreted as relative to the source of
the context of the build.
Each `<src>` may contain wildcards and matching will be done using Go's
[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. For example:
@ -854,7 +861,26 @@ named `arr[0].txt`, use the following;
ADD arr[[]0].txt /mydir/ # copy a file named "arr[0].txt" to /mydir/
All new files and directories are created with a UID and GID of 0.
All new files and directories are created with a UID and GID of 0, unless the
optional `--chown` flag specifies a given username, groupname, or UID/GID
combination to request specific ownership of the content added. The
format of the `--chown` flag allows for either username and groupname strings
or direct integer UID and GID in any combination. Providing a username without
groupname or a UID without GID will use the same numeric UID as the GID. If a
username or groupname is provided, the container's root filesystem
`/etc/passwd` and `/etc/group` files will be used to perform the translation
from name to integer UID or GID respectively. The following examples show
valid definitions for the `--chown` flag:
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
If the container root filesystem does not contain either `/etc/passwd` or
`/etc/group` files and either user or group names are used in the `--chown`
flag, the build will fail on the `ADD` operation. Using numeric IDs requires
no lookup and will not depend on container root filesystem content.
In the case where `<src>` is a remote file URL, the destination will
have permissions of 600. If the remote file being retrieved has an HTTP
@ -944,15 +970,23 @@ guide](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practi
COPY has two forms:
- `COPY <src>... <dest>`
- `COPY ["<src>",... "<dest>"]` (this form is required for paths containing
- `COPY [--chown=<user>:<group>] <src>... <dest>`
- `COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]` (this form is required for paths containing
whitespace)
> **Note**:
> The `--chown` feature is only supported on Dockerfiles used to build Linux containers,
> and will not work on Windows containers. Since user and group ownership concepts do
> not translate between Linux and Windows, the use of `/etc/passwd` and `/etc/group` for
> translating user and group names to IDs restricts this feature to only be viable for
> for Linux OS-based containers.
The `COPY` instruction copies new files or directories from `<src>`
and adds them to the filesystem of the container at the path `<dest>`.
Multiple `<src>` resource may be specified but they must be relative
to the source directory that is being built (the context of the build).
Multiple `<src>` resources may be specified but the paths of files and
directories will be interpreted as relative to the source of the context
of the build.
Each `<src>` may contain wildcards and matching will be done using Go's
[filepath.Match](http://golang.org/pkg/path/filepath#Match) rules. For example:
@ -974,7 +1008,26 @@ named `arr[0].txt`, use the following;
COPY arr[[]0].txt /mydir/ # copy a file named "arr[0].txt" to /mydir/
All new files and directories are created with a UID and GID of 0.
All new files and directories are created with a UID and GID of 0, unless the
optional `--chown` flag specifies a given username, groupname, or UID/GID
combination to request specific ownership of the copied content. The
format of the `--chown` flag allows for either username and groupname strings
or direct integer UID and GID in any combination. Providing a username without
groupname or a UID without GID will use the same numeric UID as the GID. If a
username or groupname is provided, the container's root filesystem
`/etc/passwd` and `/etc/group` files will be used to perform the translation
from name to integer UID or GID respectively. The following examples show
valid definitions for the `--chown` flag:
COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/
If the container root filesystem does not contain either `/etc/passwd` or
`/etc/group` files and either user or group names are used in the `--chown`
flag, the build will fail on the `COPY` operation. Using numeric IDs requires
no lookup and will not depend on container root filesystem content.
> **Note**:
> If you build using STDIN (`docker build - < somefile`), there is no
@ -1284,7 +1337,7 @@ consider the following Dockerfile snippet:
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
This Dockerfile results in an image that causes `docker run`, to
This Dockerfile results in an image that causes `docker run` to
create a new mount point at `/myvol` and copy the `greeting` file
into the newly created volume.
@ -1306,8 +1359,8 @@ Keep the following things in mind about volumes in the `Dockerfile`.
- **The host directory is declared at container run-time**: The host directory
(the mountpoint) is, by its nature, host-dependent. This is to preserve image
portability. since a given host directory can't be guaranteed to be available
on all hosts.For this reason, you can't mount a host directory from
portability, since a given host directory can't be guaranteed to be available
on all hosts. For this reason, you can't mount a host directory from
within the Dockerfile. The `VOLUME` instruction does not support specifying a `host-dir`
parameter. You must specify the mountpoint when you create or run the container.
@ -1322,9 +1375,20 @@ group (or GID) to use when running the image and for any `RUN`, `CMD` and
`ENTRYPOINT` instructions that follow it in the `Dockerfile`.
> **Warning**:
> When the user does doesn't have a primary group then the image (or the next
> When the user doesn't have a primary group then the image (or the next
> instructions) will be run with the `root` group.
> On Windows, the user must be created first if it's not a built-in account.
> This can be done with the `net user` command called as part of a Dockerfile.
```Dockerfile
FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick
```
## WORKDIR

View File

@ -512,7 +512,7 @@ The `--squash` option has a number of known limitations:
layers in tact, and one for the squashed version.
- While squashing layers may produce smaller images, it may have a negative
impact on performance, as a single layer takes longer to extract, and
downloading a single layer cannot be paralellized.
downloading a single layer cannot be parallelized.
- When attempting to squash an image that does not make changes to the
filesystem (for example, the Dockerfile only contains `ENV` instructions),
the squash step will fail (see [issue #33823](https://github.com/moby/moby/issues/33823)

View File

@ -217,7 +217,7 @@ For the `devicemapper`, `btrfs`, `windowsfilter` and `zfs` graph drivers,
user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the
backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
Under these conditions, user can pass any size less than the backing fs size.
### Specify isolation technology for container (--isolation)

View File

@ -72,6 +72,7 @@ Options:
--max-concurrent-uploads int Set the max concurrent uploads for each push (default 5)
--metrics-addr string Set default address and port to serve the metrics api on
--mtu int Set the containers network MTU
--node-generic-resources list Advertise user-defined resource
--no-new-privileges Set no-new-privileges by default for new containers
--oom-score-adjust int Set the oom_score_adj for the daemon (default -500)
-p, --pidfile string Path to use for daemon PID file (default "/var/run/docker.pid")
@ -393,7 +394,7 @@ $ sudo dockerd --storage-opt dm.thinp_autoextend_threshold=80
##### `dm.thinp_autoextend_percent`
Sets the value percentage value to increase the thin pool by when when `lvm`
Sets the value percentage value to increase the thin pool by when `lvm`
attempts to autoextend the available space [100 = disabled]
###### Example:
@ -1237,6 +1238,23 @@ Please note that this feature is still marked as experimental as metrics and met
names could change while this feature is still in experimental. Please provide
feedback on what you would like to see collected in the API.
#### Node Generic Resources
The `--node-generic-resources` option takes a list of key-value
pair (`key=value`) that allows you to advertise user defined resources
in a swarm cluster.
The current expected use case is to advertise NVIDIA GPUs so that services
requesting `NVIDIA-GPU=[0-16]` can land on a node that has enough GPUs for
the task to run.
Example of usage:
```json
{
"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"]
}
```
### Daemon configuration file
The `--config-file` option allows you to set any configuration option
@ -1325,6 +1343,7 @@ This is a full example of the allowed configuration options on Linux:
"no-new-privileges": false,
"default-runtime": "runc",
"oom-score-adjust": -500,
"node-generic-resources": ["NVIDIA-GPU=UUID1", "NVIDIA-GPU=UUID2"],
"runtimes": {
"cc-runtime": {
"path": "/usr/bin/cc-runtime"

View File

@ -29,6 +29,7 @@ Options:
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir Working directory inside the container
```
## Description
@ -39,7 +40,7 @@ The command started using `docker exec` only runs while the container's primary
process (`PID 1`) is running, and it is not restarted if the container is
restarted.
COMMAND will run in the default directory of the container. It the
COMMAND will run in the default directory of the container. If the
underlying image has a custom directory specified with the WORKDIR directive
in its Dockerfile, this will be used instead.
@ -86,6 +87,20 @@ This will create a new Bash session in the container `ubuntu_bash` with environm
variable `$VAR` set to "1". Note that this environment variable will only be valid
on the current Bash session.
By default `docker exec` command runs in the same working directory set when container was created.
```bash
$ docker exec -it ubuntu_bash pwd
/
```
You can select working directory for the command to execute into
```bash
$ docker exec -it -w /root ubuntu_bash pwd
/root
```
### Try to run `docker exec` on a paused container

View File

@ -47,7 +47,7 @@ describes all the details of the format.
The `docker inspect` command matches any type of object by either ID or name.
In some cases multiple type of objects (for example, a container and a volume)
exist with the same name, making the result ambigious.
exist with the same name, making the result ambiguous.
To restrict `docker inspect` to a specific type of object, use the `--type`
option.

View File

@ -25,6 +25,7 @@ Options:
-f, --follow Follow log output
--help Print usage
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--until string Show logs before timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
--tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
```
@ -66,3 +67,19 @@ that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap
seconds (aka Unix epoch or Unix time), and the optional .nanoseconds field is a
fraction of a second no more than nine digits long. You can combine the
`--since` option with either or both of the `--follow` or `--tail` options.
## Examples
### Retrieve logs until a specific point in time
In order to retrieve logs before a specific point in time, run:
```bash
$ docker run --name test -d busybox sh -c "while true; do $(echo date); sleep 1; done"
$ date
Tue 14 Nov 2017 16:40:00 CET
$ docker logs -f --until=2s
Tue 14 Nov 2017 16:40:00 CET
Tue 14 Nov 2017 16:40:01 CET
Tue 14 Nov 2017 16:40:02 CET
```

View File

@ -204,7 +204,7 @@ to create an externally isolated `overlay` network, you can specify the
You can create the network which will be used to provide the routing-mesh in the
swarm cluster. You do so by specifying `--ingress` when creating the network. Only
one ingress network can be created at the time. The network can be removed only
if no services depend on it. Any option available when creating a overlay network
if no services depend on it. Any option available when creating an overlay network
is also available when creating the ingress network, besides the `--attachable` option.
```bash

View File

@ -207,7 +207,7 @@ $ docker network inspect ingress
details such as the service's VIP and port mappings. It also shows IPs of service tasks,
and the IPs of the nodes where the tasks are running.
Following is an example output for a overlay network `ov1` that has one service `s1`
Following is an example output for an overlay network `ov1` that has one service `s1`
attached to. service `s1` in this case has three replicas.
```bash

View File

@ -240,7 +240,7 @@ For the `devicemapper`, `btrfs`, `windowsfilter` and `zfs` graph drivers,
user cannot pass a size less than the Default BaseFS Size.
For the `overlay2` storage driver, the size option is only available if the
backing fs is `xfs` and mounted with the `pquota` mount option.
Under these conditions, user can pass any size less then the backing fs size.
Under these conditions, user can pass any size less than the backing fs size.
### Mount tmpfs (--tmpfs)

View File

@ -33,6 +33,7 @@ Options:
--entrypoint command Overwrite the default ENTRYPOINT of the image
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
--generic-resource list User defined resources request
--group list Set one or more supplementary user groups for the container
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h)
@ -42,6 +43,7 @@ Options:
--help Print usage
--host list Set one or more custom host-to-IP mappings (host:ip)
--hostname string Container hostname
--isolation string Service container isolation mode
-l, --label list Service labels
--limit-cpu decimal Limit CPUs
--limit-memory bytes Limit Memory
@ -353,7 +355,7 @@ volumes in a service:
<li><tt>default</tt>: Equivalent to <tt>consistent</tt>.</li>
<li><tt>consistent</tt>: Full consistency. The container runtime and the host maintain an identical view of the mount at all times.</li>
<li><tt>cached</tt>: The host's view of the mount is authoritative. There may be delays before updates made on the host are visible within a container.</li>
<li><tt>delegated</tt>: The container runtime's view of the mount is authoritative. There may be delays before updates made in a container are are visible on the host.</li>
<li><tt>delegated</tt>: The container runtime's view of the mount is authoritative. There may be delays before updates made in a container are visible on the host.</li>
</ul>
</p>
</td>
@ -588,27 +590,27 @@ follows:
<tr>
<td><tt>node.id</tt></td>
<td>Node ID</td>
<td><tt>node.id == 2ivku8v2gvtg4</tt></td>
<td><tt>node.id==2ivku8v2gvtg4</tt></td>
</tr>
<tr>
<td><tt>node.hostname</tt></td>
<td>Node hostname</td>
<td><tt>node.hostname != node-2</tt></td>
<td><tt>node.hostname!=node-2</tt></td>
</tr>
<tr>
<td><tt>node.role</tt></td>
<td>Node role</td>
<td><tt>node.role == manager</tt></td>
<td><tt>node.role==manager</tt></td>
</tr>
<tr>
<td><tt>node.labels</tt></td>
<td>user defined node labels</td>
<td><tt>node.labels.security == high</tt></td>
<td><tt>node.labels.security==high</tt></td>
</tr>
<tr>
<td><tt>engine.labels</tt></td>
<td>Docker Engine's labels</td>
<td><tt>engine.labels.operatingsystem == ubuntu 14.04</tt></td>
<td><tt>engine.labels.operatingsystem==ubuntu 14.04</tt></td>
</tr>
</table>
@ -735,52 +737,76 @@ Containers on the same network can access each other using
### Publish service ports externally to the swarm (-p, --publish)
You can publish service ports to make them available externally to the swarm
using the `--publish` flag:
```bash
$ docker service create --publish <TARGET-PORT>:<SERVICE-PORT> nginx
```
For example:
using the `--publish` flag. The `--publish` flag can take two different styles
of arguments. The short version is positional, and allows you to specify the
target port and container port separated by a colon.
```bash
$ docker service create --name my_web --replicas 3 --publish 8080:80 nginx
```
When you publish a service port, the swarm routing mesh makes the service
accessible at the target port on every node regardless if there is a task for
the service running on the node. For more information refer to
There is also a long format, which is easier to read and allows you to specify
more options. The long format is preferred. You cannot specify the service's
mode when using the short format. Here is an example of using the long format
for the same service as above:
```bash
$ docker service create --name my_web --replicas 3 --publish target=8080,port=80 nginx
```
The options you can specify are:
<table>
<thead>
<tr>
<th>Option</th>
<th>Short syntax</th>
<th>Long syntax</th>
<th>Description</th>
</tr>
<tr>
<td>target and container port </td>
<td><tt></tt></td>
<td><tt></tt></td>
<td></td>
</tr>
<tr>
<td>protocol</td>
<td><tt>--publish 8080:80</tt></td>
<td><tt>--publish target=8080,port=80</tt></td>
<td><p>
The container port to publish and the target port to bind it to on the
routing mesh or directly on the node.
</p></td>
</tr>
<tr>
<td>mode</td>
<td>Not possible to set using short syntax.</td>
<td><tt>--publish target=8080,port=80,mode=host</tt></td>
<td><p>
The mode to use for binding the port, either `ingress` or `host`. Defaults
to `ingress` to use the routing mesh.
</p></td>
</tr>
<tr>
<td>protocol</td>
<td><tt>--publish 8080:80/tcp</tt></td>
<td><tt>--publish target=8080,port=80,protocol=tcp</tt></td>
<td><p>
The protocol to use, either `tcp` or `udp`. Defaults to `tcp`. To bind a
port for both protocols, specify the `-p` or `--publish` flag twice.
</p></td>
</tr>
</table>
When you publish a service port using `ingres` mode, the swarm routing mesh
makes the service accessible at the target port on every node regardless if
there is a task for the service running on the node. If you use `host` mode,
the port is only bound on nodes where the service is running, and a given port
on a node can only be bound once. You can only set the publication mode using
the long syntax. For more information refer to
[Use swarm mode routing mesh](https://docs.docker.com/engine/swarm/ingress/).
### Publish a port for TCP only or UDP only
By default, when you publish a port, it is a TCP port. You can
specifically publish a UDP port instead of or in addition to a TCP port. When
you publish both TCP and UDP ports, Docker 1.12.2 and earlier require you to
add the suffix `/tcp` for TCP ports. Otherwise it is optional.
#### TCP only
The following two commands are equivalent.
```bash
$ docker service create --name dns-cache -p 53:53 dns-cache
$ docker service create --name dns-cache -p 53:53/tcp dns-cache
```
#### TCP and UDP
```bash
$ docker service create --name dns-cache -p 53:53/tcp -p 53:53/udp dns-cache
```
#### UDP only
```bash
$ docker service create --name dns-cache -p 53:53/udp dns-cache
```
### Provide credential specs for managed service accounts (Windows only)
This option is only used for services using Windows containers. The
@ -875,6 +901,33 @@ $ docker inspect --format="{{.Config.Hostname}}" 2e7a8a9c4da2-wo41w8hg8qanxwjwsg
x3ti0erg11rjpg64m75kej2mz-hosttempl
```
### Specify isolation mode (Windows)
By default, tasks scheduled on Windows nodes are run using the default isolation mode
configured for this particular node. To force a specific isolation mode, you can use
the `--isolation` flag:
```bash
$ docker service create --name myservice --isolation=process microsoft/nanoserver
```
Supported isolation modes on Windows are:
- `default`: use default settings specified on the node running the task
- `process`: use process isolation (Windows server only)
- `hyperv`: use Hyper-V isolation
### Create services requesting Generic Resources
You can narrow the kind of nodes your task can land on through the using the
`--generic-resource` flag (if the nodes advertise these resources):
```bash
$ docker service create --name cuda \
--generic-resource "NVIDIA-GPU=2" \
--generic-resource "SSD=1" \
nvidia/cuda
```
## Related commands
* [service inspect](service_inspect.md)

View File

@ -41,6 +41,8 @@ Options:
--env-add list Add or update an environment variable
--env-rm list Remove an environment variable
--force Force update even if no changes require it
--generic-resource-add list Add an additional generic resource to the service's resources requirements
--generic-resource-rm list Remove a previously added generic resource to the service's resources requirements
--group-add list Add an additional supplementary user group to the container
--group-rm list Remove a previously added supplementary user group from the container
--health-cmd string Command to run to check health
@ -53,6 +55,7 @@ Options:
--host-rm list Remove a custom host-to-IP mapping (host:ip)
--hostname string Container hostname
--image string Service image tag
--isolation string Service container isolation mode
--label-add list Add or update a service label
--label-rm list Remove a label by its key
--limit-cpu decimal Limit CPUs
@ -174,6 +177,21 @@ $ docker service update --mount-rm /somewhere myservice
myservice
```
### Add or remove port mappings
Use the `--port-add` or `--port-rm` flags to add or remove port mappings to or
from a service. You can use the short or long syntax discussed in the
[docker service update](service_create/#attach-a-service-to-an-existing-network-network)
reference.
The following example adds a port mapping to an existing service.
```bash
$ docker service update \
--port-add port=80,target=8080 \
myservice
```
### Roll back to the previous version of a service
Use the `--rollback` option to roll back to the previous version of the service.
@ -258,6 +276,12 @@ $ docker service update \
Some flags of `service update` support the use of templating.
See [`service create`](./service_create.md#templating) for the reference.
### Specify isolation mode (Windows)
`service update` supports the same `--isolation` flag as `service create`
See [`service create`](./service_create.md) for the reference.
## Related commands
* [service create](service_create.md)

View File

@ -0,0 +1,364 @@
---
title: "trust inspect"
description: "The inspect command description and usage"
keywords: "view, notary, trust"
---
<!-- This file is maintained within the docker/cli GitHub
repository at https://github.com/docker/cli/. Make all
pull requests against that repo. If you see this file in
another repository, consider it read-only there, as it will
periodically be overwritten by the definitive file. Pull
requests which include edits to this file in other repositories
will be rejected.
-->
# trust inspect
```markdown
Usage: docker trust inspect IMAGE[:TAG] [IMAGE[:TAG]...]
Return low-level information about keys and signatures
```
## Description
`docker trust inspect` provides low-level JSON information on signed repositories.
This includes all image tags that are signed, who signed them, and who can sign
new tags.
`docker trust inspect` prints the trust information in a machine-readable format. Refer to
[`docker trust view`](trust_view.md) for a human-friendly output.
`docker trust inspect` is currently experimental.
## Examples
### Get low-level details about signatures for a single image tag
Use the `docker trust inspect` to get trust information about an image. The
following example prints trust information for the `alpine:latest` image:
```bash
$ docker trust inspect alpine:latest
[
{
"Name": "alpine:latest",
"SignedTags": [
{
"SignedTag": "latest",
"Digest": "d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Repository",
"Keys": [
{
"ID": "5a46c9aaa82ff150bb7305a2d17d0c521c2d784246807b2dc611f436a69041fd"
}
]
},
{
"Name": "Root",
"Keys": [
{
"ID": "a2489bcac7a79aa67b19b96c4a3bf0c675ffdf00c6d2fabe1a5df1115e80adce"
}
]
}
]
}
]
```
The `SignedTags` key will list the `SignedTag` name, its `Digest`, and the `Signers` responsible for the signature.
`AdministrativeKeys` will list the `Repository` and `Root` keys.
This format mirrors the output of `docker trust view`
If signers are set up for the repository via other `docker trust` commands, `docker trust inspect` includes a `Signers` key:
```bash
$ docker trust inspect my-image:purple
[
{
"Name": "my-image:purple",
"SignedTags": [
{
"SignedTag": "purple",
"Digest": "941d3dba358621ce3c41ef67b47cf80f701ff80cdf46b5cc86587eaebfe45557",
"Signers": [
"alice",
"bob",
"carol"
]
}
],
"Signers": [
{
"Name": "alice",
"Keys": [
{
"ID": "04dd031411ed671ae1e12f47ddc8646d98f135090b01e54c3561e843084484a3"
},
{
"ID": "6a11e4898a4014d400332ab0e096308c844584ff70943cdd1d6628d577f45fd8"
}
]
},
{
"Name": "bob",
"Keys": [
{
"ID": "433e245c656ae9733cdcc504bfa560f90950104442c4528c9616daa45824ccba"
}
]
},
{
"Name": "carol",
"Keys": [
{
"ID": "d32fa8b5ca08273a2880f455fcb318da3dc80aeae1a30610815140deef8f30d9"
},
{
"ID": "9a8bbec6ba2af88a5fad6047d428d17e6d05dbdd03d15b4fc8a9a0e8049cd606"
}
]
}
],
"AdminstrativeKeys": [
{
"Name": "Repository",
"Keys": [
{
"ID": "27df2c8187e7543345c2e0bf3a1262e0bc63a72754e9a7395eac3f747ec23a44"
}
]
},
{
"Name": "Root",
"Keys": [
{
"ID": "40b66ccc8b176be8c7d365a17f3e046d1c3494e053dd57cfeacfe2e19c4f8e8f"
}
]
}
]
}
]
```
If the image tag is unsigned or unavailable, `docker trust inspect` does not display any signed tags.
```bash
$ docker trust inspect unsigned-img
No signatures or cannot access unsigned-img
```
However, if other tags are signed in the same image repository, `docker trust inspect` reports relevant key information:
```bash
$ docker trust inspect alpine:unsigned
[
{
"Name": "alpine:unsigned",
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Repository",
"Keys": [
{
"ID": "5a46c9aaa82ff150bb7305a2d17d0c521c2d784246807b2dc611f436a69041fd"
}
]
},
{
"Name": "Root",
"Keys": [
{
"ID": "a2489bcac7a79aa67b19b96c4a3bf0c675ffdf00c6d2fabe1a5df1115e80adce"
}
]
}
]
}
]
```
### Get details about signatures for all image tags in a repository
If no tag is specified, `docker trust inspect` will report details for all signed tags in the repository:
```bash
$ docker trust inspect alpine
[
{
"Name": "alpine",
"SignedTags": [
{
"SignedTag": "3.5",
"Digest": "b007a354427e1880de9cdba533e8e57382b7f2853a68a478a17d447b302c219c",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "3.6",
"Digest": "d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "edge",
"Digest": "23e7d843e63a3eee29b6b8cfcd10e23dd1ef28f47251a985606a31040bf8e096",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "latest",
"Digest": "d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Repository",
"Keys": [
{
"ID": "5a46c9aaa82ff150bb7305a2d17d0c521c2d784246807b2dc611f436a69041fd"
}
]
},
{
"Name": "Root",
"Keys": [
{
"ID": "a2489bcac7a79aa67b19b96c4a3bf0c675ffdf00c6d2fabe1a5df1115e80adce"
}
]
}
]
}
]
```
### Get details about signatures for multiple images
`docker trust inspect` can take multiple repositories and images as arguments, and reports the results in an ordered list:
```bash
$ docker trust inspect alpine notary
[
{
"Name": "alpine",
"SignedTags": [
{
"SignedTag": "3.5",
"Digest": "b007a354427e1880de9cdba533e8e57382b7f2853a68a478a17d447b302c219c",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "3.6",
"Digest": "d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "edge",
"Digest": "23e7d843e63a3eee29b6b8cfcd10e23dd1ef28f47251a985606a31040bf8e096",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "integ-test-base",
"Digest": "3952dc48dcc4136ccdde37fbef7e250346538a55a0366e3fccc683336377e372",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "latest",
"Digest": "d6bfc3baf615dc9618209a8d607ba2a8103d9c8a405b3bd8741d88b4bef36478",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Repository",
"Keys": [
{
"ID": "5a46c9aaa82ff150bb7305a2d17d0c521c2d784246807b2dc611f436a69041fd"
}
]
},
{
"Name": "Root",
"Keys": [
{
"ID": "a2489bcac7a79aa67b19b96c4a3bf0c675ffdf00c6d2fabe1a5df1115e80adce"
}
]
}
]
},
{
"Name": "notary",
"SignedTags": [
{
"SignedTag": "server",
"Digest": "71f64ab718a3331dee103bc5afc6bc492914738ce37c2d2f127a8133714ecf5c",
"Signers": [
"Repo Admin"
]
},
{
"SignedTag": "signer",
"Digest": "a6122d79b1e74f70b5dd933b18a6d1f99329a4728011079f06b245205f158fe8",
"Signers": [
"Repo Admin"
]
}
],
"Signers": [],
"AdminstrativeKeys": [
{
"Name": "Root",
"Keys": [
{
"ID": "8cdcdef5bd039f4ab5a029126951b5985eebf57cabdcdc4d21f5b3be8bb4ce92"
}
]
},
{
"Name": "Repository",
"Keys": [
{
"ID": "85bfd031017722f950d480a721f845a2944db26a3dc084040a70f1b0d9bbb3df"
}
]
}
]
}
]
```

View File

@ -16,10 +16,14 @@ keywords: "sign, notary, trust"
# trust sign
```markdown
Usage: docker trust sign IMAGE:TAG
Usage: docker trust sign [OPTIONS] IMAGE:TAG
Sign an image
Options:
--help print usage
--local force the signing of a local image
```
## Description

View File

@ -4,6 +4,7 @@ import (
"fmt"
"testing"
"github.com/docker/cli/e2e/internal/fixtures"
shlex "github.com/flynn-archive/go-shlex"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/gotestyourself/gotestyourself/icmd"
@ -11,8 +12,6 @@ import (
"github.com/stretchr/testify/require"
)
const alpineImage = "registry:5000/alpine:3.6"
func TestRunAttachedFromRemoteImageAndRemove(t *testing.T) {
image := createRemoteImage(t)
@ -27,8 +26,8 @@ func TestRunAttachedFromRemoteImageAndRemove(t *testing.T) {
// TODO: create this with registry API instead of engine API
func createRemoteImage(t *testing.T) string {
image := "registry:5000/alpine:test-run-pulls"
icmd.RunCommand("docker", "pull", alpineImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", alpineImage, image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "push", image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success)
return image

View File

@ -0,0 +1,83 @@
package image
import (
"fmt"
"strings"
"testing"
"github.com/docker/cli/e2e/internal/fixtures"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/gotestyourself/gotestyourself/icmd"
"github.com/pkg/errors"
)
func TestBuildFromContextDirectoryWithTag(t *testing.T) {
dir := fs.NewDir(t, "test-build-context-dir",
fs.WithFile("run", "echo running", fs.WithMode(0755)),
fs.WithDir("data", fs.WithFile("one", "1111")),
fs.WithFile("Dockerfile", fmt.Sprintf(`
FROM %s
COPY run /usr/bin/run
RUN run
COPY data /data
`, fixtures.AlpineImage)))
defer dir.Remove()
result := icmd.RunCmd(
icmd.Command("docker", "build", "-t", "myimage", "."),
withWorkingDir(dir))
result.Assert(t, icmd.Expected{Err: icmd.None})
assertBuildOutput(t, result.Stdout(), map[int]lineCompare{
0: prefix("Sending build context to Docker daemon"),
1: equals("Step 1/4 : FROM\tregistry:5000/alpine:3.6"),
3: equals("Step 2/4 : COPY\trun /usr/bin/run"),
5: equals("Step 3/4 : RUN\t\trun"),
7: equals("running"),
8: prefix("Removing intermediate container "),
10: equals("Step 4/4 : COPY\tdata /data"),
12: prefix("Successfully built "),
13: equals("Successfully tagged myimage:latest"),
})
}
func withWorkingDir(dir *fs.Dir) func(*icmd.Cmd) {
return func(cmd *icmd.Cmd) {
cmd.Dir = dir.Path()
}
}
func assertBuildOutput(t *testing.T, actual string, expectedLines map[int]lineCompare) {
for i, line := range strings.Split(actual, "\n") {
cmp, ok := expectedLines[i]
if !ok {
continue
}
if err := cmp(line); err != nil {
t.Errorf("line %d: %s", i, err)
}
}
if t.Failed() {
t.Log(actual)
}
}
type lineCompare func(string) error
func prefix(expected string) func(string) error {
return func(actual string) error {
if strings.HasPrefix(actual, expected) {
return nil
}
return errors.Errorf("expected %s to start with %s", actual, expected)
}
}
func equals(expected string) func(string) error {
return func(actual string) error {
if expected == actual {
return nil
}
return errors.Errorf("got %s, expected %s", actual, expected)
}
}

View File

@ -2,23 +2,19 @@ package image
import (
"fmt"
"os"
"testing"
"github.com/docker/cli/e2e/internal/fixtures"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/gotestyourself/gotestyourself/icmd"
)
const notaryURL = "https://notary-server:4443"
const registryPrefix = "registry:5000"
const alpineImage = "registry:5000/alpine:3.6"
const busyboxImage = "registry:5000/busybox:1.27.2"
func TestPullWithContentTrust(t *testing.T) {
image := createMaskedTrustedRemoteImage(t, "trust", "latest")
result := icmd.RunCmd(icmd.Command("docker", "pull", image), withTrustNoPassphrase)
result := icmd.RunCmd(icmd.Command("docker", "pull", image), fixtures.WithTrust, fixtures.WithNotary)
result.Assert(t, icmd.Success)
golden.Assert(t, result.Stderr(), "pull-with-content-trust-err.golden")
golden.Assert(t, result.Stdout(), "pull-with-content-trust.golden")
@ -34,39 +30,19 @@ func createMaskedTrustedRemoteImage(t *testing.T, repo, tag string) string {
func createTrustedRemoteImage(t *testing.T, repo, tag string) string {
image := fmt.Sprintf("%s/%s:%s", registryPrefix, repo, tag)
icmd.RunCommand("docker", "pull", alpineImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", alpineImage, image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "pull", fixtures.AlpineImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", fixtures.AlpineImage, image).Assert(t, icmd.Success)
result := icmd.RunCmd(
icmd.Command("docker", "push", image),
withTrustAndPassphrase("root_password", "repo_password"))
fixtures.WithPassphrase("root_password", "repo_password"), fixtures.WithTrust, fixtures.WithNotary)
result.Assert(t, icmd.Success)
icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success)
return image
}
func createNamedUnsignedImageFromBusyBox(t *testing.T, image string) {
icmd.RunCommand("docker", "pull", busyboxImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", busyboxImage, image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "pull", fixtures.BusyboxImage).Assert(t, icmd.Success)
icmd.RunCommand("docker", "tag", fixtures.BusyboxImage, image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "push", image).Assert(t, icmd.Success)
icmd.RunCommand("docker", "rmi", image).Assert(t, icmd.Success)
}
func withTrustAndPassphrase(rootPwd, repositoryPwd string) func(cmd *icmd.Cmd) {
return func(cmd *icmd.Cmd) {
env := append(os.Environ(),
"DOCKER_CONTENT_TRUST=1",
"DOCKER_CONTENT_TRUST_SERVER="+notaryURL,
"DOCKER_CONTENT_TRUST_ROOT_PASSPHRASE="+rootPwd,
"DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE="+repositoryPwd,
)
cmd.Env = append(cmd.Env, env...)
}
}
func withTrustNoPassphrase(cmd *icmd.Cmd) {
env := append(os.Environ(),
"DOCKER_CONTENT_TRUST=1",
"DOCKER_CONTENT_TRUST_SERVER="+notaryURL,
)
cmd.Env = append(cmd.Env, env...)
}

Some files were not shown because too many files have changed in this diff Show More