Compare commits

..

767 Commits

Author SHA1 Message Date
cbc5bef54f Merge pull request #454 from seemethere/cherry_pick_packaging_88
[18.03] Fixes binary installation
2018-03-06 14:11:59 -08:00
88176d01f4 Fixes binary installation
Binary installation was broken after the
hack/dockerfile/install-binaries script was removed.

This remedies that.

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit 59164bedeab571029805a107e8e5a32fc9cd56b3)
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-03-06 21:50:00 +00:00
3e53917a28 Merge pull request #443 from jose-bigio/18.03_versionBump
[18.03]  Bump version to 18.03.0-ce-rc2
2018-03-06 13:05:52 -08:00
5613f516dd Merge pull request #440 from jose-bigio/18.03_changelog
[18.03] Updating Changelog for 18.03
2018-03-06 13:05:24 -08:00
7bc0502750 Updating Changelog for 18.03
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-03-06 11:30:36 -08:00
91bb2aeb67 Merge pull request #453 from thaJeztah/18.03-swarmkit-ingress-attach
[18.03] disallow attaching ingress network
2018-03-06 11:27:15 -08:00
5ba2b1a74d Merge pull request #452 from thaJeztah/18.03-backport-selansen-36247
[18.03] Fix to address regression caused by PR 30897
2018-03-06 10:04:37 -08:00
dbe2a19e83 CLI bump swarmkit to 11d7b06f48bc1d73fc6d8776c3552a4b11c94301
Contains no changes for the CLI, but keeps the version
in sync with engine

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-06 17:32:08 +01:00
2d690d4e87 Engine: bump swarmkit to 11d7b06f48bc1d73fc6d8776c3552a4b11c94301
Ingress network should not be attachable

Ingress network is a special network used only to expose
ports. For this reason the network cannot be explicitly
attached during service create or service update

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-06 17:31:43 +01:00
3ab4d93c66 Merge pull request #451 from andrewhsu/md
[18.03] vndr swarmkit to 49a9d7f
2018-03-06 07:39:11 -08:00
cb1018ea72 Merge pull request #449 from tonistiigi/layer-leak-fix
[18.03] builder: fix layer lifecycle leak
2018-03-06 07:37:26 -08:00
3310baba0f Fix to address regression caused by PR 30897
With the inclusion of PR 30897, creating service for host network
    fails in 18.02. Modified IsPreDefinedNetwork check and return
    NetworkNameError instead of errdefs.Forbidden to address this issue

Signed-off-by: selansen <elango.siva@docker.com>
(cherry picked from commit 7cf8b20762cc9491f52ff3f3d94c880378183696)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-06 13:42:37 +01:00
9dbc108a14 Merge pull request #441 from thaJeztah/18.03-backport-templated-configs-secrets
[18.03] Add --template-driver option for secrets/configs
2018-03-05 22:25:55 -08:00
977f2704b3 Merge pull request #450 from thaJeztah/18.03-backport-bump-runc-1.0-rc5
[18.03] Bump Runc to 1.0.0-rc5
2018-03-05 22:22:01 -08:00
1b39f8bd26 cli: vndr swarmkit 49a9d7f
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-03-06 01:45:21 +00:00
652953a81f engine: vndr swarmkit 49a9d7f
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-03-06 01:43:57 +00:00
7000ca4203 Merge pull request #447 from vdemeester/tests-fixes
[18.03] Fixes tests to have the ci green
2018-03-05 17:19:37 -08:00
5bc239fe16 bump containerd/console to 2748ece16665b45a47f884001d5831ec79703880
Fix runc exec on big-endian, causing:

    container_linux.go:265: starting container process caused "open /dev/pts/4294967296: no such file or directory"

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit aab5eaddccb8cb196fdb1e285890dfa94a071b14)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-05 23:56:22 +01:00
aca674de82 Bump Runc to 1.0.0-rc5 / 4fc53a81fb7c994640722ac585fa9ca548971871
Release notes: https://github.com/opencontainers/runc/releases/tag/v1.0.0-rc5

Possibly relevant changes included:

- chroot when no mount namespaces is provided
- fix systemd slice expansion so that it could be consumed by cAdvisor
- libcontainer/capabilities_linux: Drop os.Getpid() call
- Update console dependency to fix runc exec on BE (causing: `container_linux.go:265: starting container process caused "open /dev/pts/4294967296: no such file or directory"`)
- libcontainer: setupUserNamespace is always called (fixes: Devices are mounted with wrong uid/gid)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a2f5a1a5b2d77d694c5bd47798be15b3c0bcdf70)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-05 23:56:13 +01:00
c709b18bfd Split binary installers/commit scripts
Originally I worked on this for the multi-stage build Dockerfile
changes. Decided to split this out as we are still waiting for
multi-stage to be available on CI and rebasing these is pretty annoying.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit b529d1b0936b90ae14d584c73f7332919f8d76b7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-05 23:56:02 +01:00
6f6e5c5f2c builder: fix layer lifecycle leak
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 7ad41d53df94c4277574d14809211b42dca2becc)
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2018-03-05 14:11:22 -08:00
50c9a31b4c Fix --label behavior on run
Commit 2b17f4c8a8 fixed the way empty labels
are taken into account (i.e. not interpolated from environment variable),
but it created a regression.

`ValidateLabel` functions doesn't allow empty label value, but it has
always been possible to pass an empty label via the cli (`docker run --label foo`).

This fixes that by not validating the label flag.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 31dc5c0a9a)
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-03-02 10:21:53 +01:00
f8e0c47b29 Merge pull request #442 from thaJeztah/18.03-docs-cherry-picks
[18.03] docs cherry-picks
2018-02-28 13:32:40 -08:00
767a8f6227 Update run.md --restart to include unless-stopped
Update --restart option to include unless-stopped to be consistent with https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy

Signed-off-by: Lydell Manganti <lydell.manganti@gmail.com>
(cherry picked from commit d281b72a98)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-02-28 18:10:39 +01:00
36343864e2 Migrate some copy tests to integration
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 00d409f03ed825f623b6ef8ec5a3a91cd26194c2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-02-28 12:29:10 +01:00
7d395933ee Add more container cp tests
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 07cb69e9bc)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-02-28 11:16:23 +01:00
c70b6c9f35 Clean some docker_cli_build_tests that are cli-only
Remove TestBuildRenamedDockerfile and TestBuildDockerfileOutsideContext
that are cli-only tests (and already tested in the docker/cli
repository).

Also adds some comments on few tests that could be migrate to
docker/cli.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 894c213b3bd6f4d8f344837b5b5084360a013680)
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
2018-02-28 10:13:03 +01:00
dd1b760bad Bump version to 18.03.0-ce-rc2
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-02-27 09:34:44 -08:00
de4362e128 docs: mention sctp
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
(cherry picked from commit b85d87b8ab)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-02-26 11:40:06 +01:00
eda1e25f5c Add --template-driver option for secrets/configs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d11b5ccdfa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-02-26 11:34:23 +01:00
c160c73353 Merge pull request #438 from jose-bigio/18.03_changelog
[18.03] Changelog for 18.03
2018-02-21 18:31:04 -08:00
5c06a61da4 Merge pull request #437 from andrewhsu/t
[18.03] skip DockerTrustSuite tests for 18.03
2018-02-21 18:30:37 -08:00
9d7d57c20f Merge pull request #439 from andrewhsu/taad
[18.03] Fix TestAttachAfterDetach to work with latest client
2018-02-21 18:30:27 -08:00
138ca8c7ad Deleted the delete section and the triage sections
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-02-21 17:50:55 -08:00
9dd6df6ee4 Fix TestAttachAfterDetach to work with latest client
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 847b610620a8b8294d61c717d3c4aa13cb7a8b33)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-02-21 17:50:33 -08:00
9d4514861f 18.03 Changelog
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-02-21 17:33:48 -08:00
d5f8753b88 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>
(cherry picked from commit d256539bf4)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
(cherry picked from commit 5742bd3ccf)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
(cherry picked from commit 1a2098cecf)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-02-21 16:23:44 -08:00
a720337d2e 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>
(cherry picked from commit fbfecebc0a)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
(cherry picked from commit e3571070d5)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
(cherry picked from commit 9d7b9c23f5)
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-02-21 16:23:44 -08:00
5ff63c0239 Bump version to 18.03.0-ce-rc1
Signed-off-by: GordonTheTurtle <engine-team@docker.com>
2018-02-21 23:59:01 +00:00
2afc089041 Merge component 'engine' from git@github.com:moby/moby master 2018-02-21 23:57:52 +00:00
66d22efd1f Merge component 'cli' from git@github.com:docker/cli master 2018-02-21 23:32:37 +00:00
02638eae1b Merge pull request #36209 from dnephin/fix-image-prune-mapping
Remove broken container check from image prune
Upstream-commit: 05c751b1be6785b4f8a42c412e858508b137c10e
Component: engine
2018-02-21 18:22:51 -05:00
acea77d537 Merge pull request #843 from sepich/docs-for-pr33130
Document long form of --network and --network-add
Upstream-commit: 84c7dd6057
Component: cli
2018-02-21 23:26:39 +01:00
f1a4158236 Merge pull request #36370 from thaJeztah/update-authors
Update authors
Upstream-commit: f0f41bae5f0f2579784dfa551643b85286d8c899
Component: engine
2018-02-21 21:29:10 +01:00
706ded458f Merge pull request #897 from thaJeztah/update-authors2
Update authors
Upstream-commit: 50b229f533
Component: cli
2018-02-21 21:28:36 +01:00
c3a24a0fbd Update authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: fb005971c2bd82de482d1cfe924f2f4ec60c60ae
Component: engine
2018-02-21 21:12:31 +01:00
da1330b479 Update authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ec92c08874
Component: cli
2018-02-21 20:53:40 +01:00
f8157dd468 Merge pull request #884 from shin-/update_3.6_schema_id
Fix typo in 3.6 schema ID
Upstream-commit: 0e81cddd95
Component: cli
2018-02-21 14:49:43 -05:00
86c5b9760f Fix typo in 3.6 schema ID
Signed-off-by: Joffrey F <joffrey@docker.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 56f26d1134
Component: cli
2018-02-21 19:55:12 +01:00
ff7653434c Merge pull request #36368 from justincormack/maskkeys
Add /proc/keys to masked paths
Upstream-commit: 8f6a40a3f126ae1dc0a74dc612a3f7b14de4e7f6
Component: engine
2018-02-21 13:48:19 -05:00
da2e766ea9 Merge pull request #824 from ethan-haynes/820-bind-mount-source-missing-error
added check for empty source in bind mount
Upstream-commit: cea4d37bca
Component: cli
2018-02-21 13:33:24 -05:00
6e4091ce84 Merge pull request #894 from thaJeztah/update-moby
Bump moby to 0ede01237c9ab871f1b8db0364427407f3e46541
Upstream-commit: a160ad89c9
Component: cli
2018-02-21 13:15:58 -05:00
8878228a1f Merge pull request #895 from vdemeester/simplify-yaml-marshal
Simplify the marshaling of compose types.Config
Upstream-commit: 88ee1a67f4
Component: cli
2018-02-21 19:02:04 +01:00
8254c65c9b Bump moby to 0ede01237c9ab871f1b8db0364427407f3e46541
Includes:

- [client] Remove duplicate NewClient functions
- Add API support for templated secrets and configs
- Adjust minimum API version for templated configs/secrets

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 60930d309c
Component: cli
2018-02-21 18:48:42 +01:00
239936c7e1 Simplify the marshaling of compose types.Config
- Add `Version` to `types.Config`
- Add a new `Services` types (that is just `[]ServiceConfig`) and add
  `MarshalYAML` method on it.
- Clean other top-level custom marshaling as `Services` is the only one
  required.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: cf86a4d922
Component: cli
2018-02-21 18:47:10 +01:00
83cba78175 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-21 17:06:09 +00:00
b9bcfd701b Merge component 'engine' from git@github.com:moby/moby master 2018-02-21 17:06:03 +00:00
912355fce6 Merge pull request #891 from vdemeester/k8s-loader-make-sure-version
Make sure we marshall version too…
Upstream-commit: 939938b976
Component: cli
2018-02-21 11:45:14 -05:00
e106425236 Merge pull request #36366 from thaJeztah/update-api-version-check
Adjust minimum API version for templated configs/secrets
Upstream-commit: 0ede01237c9ab871f1b8db0364427407f3e46541
Component: engine
2018-02-21 11:44:50 -05:00
3bdf2c5c9a Merge component 'cli' from git@github.com:docker/cli master 2018-02-21 16:41:14 +00:00
87cd2bf7ea Add /proc/keys to masked paths
This leaks information about keyrings on the host. Keyrings are
not namespaced.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
Upstream-commit: de23cb939858a66829d5b75057c7ac664c5acda5
Component: engine
2018-02-21 16:23:34 +00:00
3ed0ebb0b5 Make sure we marshall version too…
… otherwise the k8s controller might fail to parse the file as it will
think it's version 1.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 9f9f1c8515
Component: cli
2018-02-21 15:36:51 +01:00
e09ff74ed5 Adjust minimum API version for templated configs/secrets
Also adds a note to the API version history

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a3efeaad529b945ce5af78c4b08a6ed47399f8d5
Component: engine
2018-02-21 15:23:00 +01:00
40a7a5b6d7 Bump default API version to 1.37
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 453f2b8b40b923862ce1c08c11531ff5042770f1
Component: engine
2018-02-21 15:22:40 +01:00
a196815f55 Merge pull request #33702 from aaronlehmann/templated-secrets-and-configs
Templated secrets and configs
Upstream-commit: 0076343b29f508a5deb06861c0d85748659f8881
Component: engine
2018-02-21 13:39:10 +01:00
0308ec9c17 Merge pull request #34899 from dnephin/fix-duplicate-new-client
[client] Remove duplicate NewClient functions
Upstream-commit: 466cc981433e2e1815a64ee714b1c8c083765785
Component: engine
2018-02-21 12:59:42 +01:00
ad01430349 Merge pull request #35829 from cpuguy83/no_private_mount_for_plugins
Perform plugin mounts in the runtime
Upstream-commit: 20028325daab4fcbee9c8e28f43dbfb2b1c5d568
Component: engine
2018-02-21 12:28:13 +01:00
692373dbbd Merge pull request #35898 from javabrett/docs-contributing-test
test.md improvements and corrections
Upstream-commit: 9f68f20faecfc084343dc1a6cbd7de1db616e7e0
Component: engine
2018-02-21 09:32:15 +01:00
53fd7b9026 Merge pull request #278 from ishidawataru/sctp
Support SCTP port mapping
Upstream-commit: 64f92fd07c
Component: cli
2018-02-21 09:29:36 +01:00
894af8d548 Support SCTP port mapping
Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Upstream-commit: 995006c164
Component: cli
2018-02-21 12:19:38 +09:00
d7eb6e8c90 Merge pull request #36361 from kolyshkin/pr36326-followup
integration/TestUpdateMemory: fix false failure
Upstream-commit: e3831a62a3052472d7252049bc59835d5d7dc8bd
Component: engine
2018-02-20 16:10:59 -08:00
10bf273bff Remove explicit DOCKER_API_VERSION from integration env setup
Use the default version because it is used by the client package

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: e73d742cd7deee396eac3c97664b40264ee358cb
Component: engine
2018-02-20 17:27:28 -05:00
49adb54d71 Remove duplicate calls for getting an APIClient
Remove request.SockRequest
Remove request.SockRequestHijack
Remove request.SockRequestRaw()
Remove deprecated ParseHost
Deprecate and unexport more helpers

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 0a91ba2d8cfe16df0ba37c1e283c8e3dbbb086d4
Component: engine
2018-02-20 17:27:24 -05:00
4b504a390c Merge pull request #874 from dnephin/replace-go-bindata
Replace go-bindata with esc
Upstream-commit: 5730ef8ea0
Component: cli
2018-02-20 17:00:22 -05:00
e0869be245 Cleanup volume plugin test with bad assumptions
Test made some bad assumptions about on-disk state of volume data.
This updates the test to only test based on what the volume API is
designed to provide.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 0df654f3d61d8691ee113a8429bcc8ef65786bc7
Component: engine
2018-02-20 16:57:20 -05:00
088ad71eb5 integration/testUpdateCPUQuota: fix name
The function name should be TestUpdateCPUQuota and not TestUpdateCPUQUota.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 31825081d4c5e643a150b515547cb2a2ea223de4
Component: engine
2018-02-20 13:36:27 -08:00
133cf88cac integration/TestUpdateMemory: fix false failure
This fixes the following test failure:

> --- FAIL: TestUpdateMemory (0.53s)
>  	assertions.go:226:
>	Error Trace:	update_linux_test.go:52
>	Error:      	Not equal:
>	            	expected: int(524288000)
>	            	received: int64(524288000)

Fixes: 0f9da07b569f0d9
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: cc866470981a1e6a839004f24eb30bb708078068
Component: engine
2018-02-20 13:31:03 -08:00
180ce35066 Improve docstrings and small cleanup in client
Use client instead of helpers for TLS in integration test

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: a68ae4a2d95b1ff143025a435195af0f1ab30ace
Component: engine
2018-02-20 15:15:02 -05:00
9a83d9fd53 Use gotestyourself env patching
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 2b445a53c17ae6526c11a729cb6d1d1dc57490ff
Component: engine
2018-02-20 15:15:02 -05:00
1b01bb68a9 Merge pull request #87 from corbin-coleman/remove-zesty
Remove ubuntu-zesty from the default DOCKER_BUILD_PKGS in Makefile
Upstream-commit: 2ab6d8ab3a9da8917ef52b87943e3de83a1092a5
Component: packaging
2018-02-20 14:10:25 -06:00
18043a7a58 Remove ubuntu-zesty from the default BUILD_PKGS in Makefile
Zesty is EOL and doesn't even have a subdirectory in the `deb` directory of this repo. There's no need to have it as a default.

Signed-off-by: Corbin <corbin.coleman@docker.com>
Upstream-commit: 9b3e8f85f039dfe7391512de6143ef213574973a
Component: packaging
2018-02-20 11:29:11 -08:00
c2d1fda268 Merge pull request #886 from thaJeztah/dockerfile-outside-context
Allow Dockerfile from outside build-context
Upstream-commit: 82a8085885
Component: cli
2018-02-20 19:56:16 +01:00
4f56c06e93 Merge pull request #892 from thaJeztah/bump-moby-vendor
Bump moby vendor and dependencies
Upstream-commit: 02e8dc6bfc
Component: cli
2018-02-20 18:54:55 +01:00
81f2f8b4a0 Merge pull request #885 from thaJeztah/node-engine-version
Add Engine version to docker node ls
Upstream-commit: 1e8530bc34
Component: cli
2018-02-20 18:45:36 +01:00
8439f579a2 Bump swarmkit to f74983e7c015a38a81c8642803a78b8322cf7eac
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 3c24e5ce12
Component: cli
2018-02-20 18:07:28 +01:00
5a987db87c Merge component 'engine' from git@github.com:moby/moby master 2018-02-20 17:05:31 +00:00
d34627d1e8 Update github.com/containerd/continuity
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 58e29ec11e
Component: cli
2018-02-20 18:03:37 +01:00
7a139c4f49 bump runc to 6c55f98695e902427906eed2c799e566e3d3dfb5
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: e17a680f01
Component: cli
2018-02-20 17:58:11 +01:00
6e43a54340 Update go-connections to 7beb39f0b969b075d1325fecb092faf27fd357b6
- Support parsing SCTP port mapping

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 88874b5eff
Component: cli
2018-02-20 17:45:42 +01:00
112f17c68b Merge component 'cli' from git@github.com:docker/cli master 2018-02-20 16:42:03 +00:00
434d9d7ac3 update golang.org/x/sys for OpenBSD
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d9f5fa8124
Component: cli
2018-02-20 17:40:06 +01:00
c6e3764db6 Merge pull request #264 from thaJeztah/carry-moby-32803
Update docker kill reference docs
Upstream-commit: bbe7f84540
Component: cli
2018-02-20 11:19:59 -05:00
a964103223 Bump docker/docker to 079ed017b61eb819b8184b90013ce89465d3aaba
- Add API support for SCTP port mapping
- Add canonical import path
- Add `REMOVE` and `ORPHANED` to TaskState
- Fix TLS from environment variables in client
- Introduce NewClientWithOpts func to build custom client easily
- Wrap response errors for container copy methodsto fix error detection using
  `IsErrNotFound` and `IsErrNotImplemented` for `ContainerStatPath`,
  `CopyFromContainer`, and `CopyToContainer` methods.
- Produce errors when empty ids are passed into inspect calls

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: aaa7a7cb95
Component: cli
2018-02-20 17:17:49 +01:00
dbebd52548 Merge pull request #36326 from kolyshkin/integration-exec
Add/use container.Exec() to integration
Upstream-commit: ee9abc212032353e19e5b0f5e6410ad67a0cc9b1
Component: engine
2018-02-20 17:16:09 +01:00
6899375641 Merge pull request #33922 from ishidawataru/sctp
Support SCTP port mapping (bump up API to v1.37)
Upstream-commit: 079ed017b61eb819b8184b90013ce89465d3aaba
Component: engine
2018-02-20 17:00:13 +01:00
c93b94f9bd Allow Dockerfile from outside build-context
Historically, the Dockerfile had to be insde the build-context, because it was
sent as part of the build-context.

3f6dc81e10
added support for passing the Dockerfile through stdin, in which case the
contents of the Dockerfile is injected into the build-context.

This patch uses the same mechanism for situations where the location of the
Dockerfile is passed, and its path is outside of the build-context.

Before this change:

    $ mkdir -p myproject/context myproject/dockerfiles && cd myproject
    $ echo "hello" > context/hello
    $ echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > dockerfiles/Dockerfile
    $ docker build --no-cache -f $PWD/dockerfiles/Dockerfile $PWD/context

    unable to prepare context: the Dockerfile (/Users/sebastiaan/projects/test/dockerfile-outside/myproject/dockerfiles/Dockerfile) must be within the build context

After this change:

    $ mkdir -p myproject/context myproject/dockerfiles && cd myproject
    $ echo "hello" > context/hello
    $ echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > dockerfiles/Dockerfile
    $ docker build --no-cache -f $PWD/dockerfiles/Dockerfile $PWD/context

    Sending build context to Docker daemon  2.607kB
    Step 1/3 : FROM busybox
     ---> 6ad733544a63
    Step 2/3 : COPY /hello /
     ---> 9a5ae1c7be9e
    Step 3/3 : RUN cat /hello
     ---> Running in 20dfef2d180f
    hello
    Removing intermediate container 20dfef2d180f
     ---> ce1748f91bb2
    Successfully built ce1748f91bb2

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a1048523d2
Component: cli
2018-02-20 16:50:49 +01:00
1cf28cd5dc Merge pull request #890 from silvin-lubecki/fix-kube-stack-marshaling
Fix stack marshaling for Kubernetes
Upstream-commit: 7d41d18b43
Component: cli
2018-02-20 16:50:45 +01:00
6362580899 Fix stack marshaling for Kubernetes
Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 9b27e92903
Component: cli
2018-02-20 16:43:24 +01:00
bf0c1bd1d9 Update docker kill reference docs
- explain the either "name" or "id" can be used to reference a container
- explain that signals can be sent by name or number

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 0c085c2a77
Component: cli
2018-02-20 14:58:55 +01:00
74fad1551d Merge pull request #888 from trapier/completion-swarm-event-filter-types
Add swarm types to bash completion event type filter
Upstream-commit: e34ca9740e
Component: cli
2018-02-20 10:13:25 +01:00
ded970f96e Merge pull request #36107 from cpuguy83/cleanup_daemon_root_mount
Ensure daemon root is unmounted on shutdown
Upstream-commit: eb033c11753872c6269304d8127dbfe7315e476f
Component: engine
2018-02-20 10:04:41 +01:00
0c0ee07b87 Merge pull request #36330 from vdemeester/migrate-container-list-tests
test: clean/migrate some docker ps cli-only integration tests 
Upstream-commit: 7060a40addd71605862b668c1ec2b889e3540233
Component: engine
2018-02-20 08:44:17 +01:00
ed5d3f9cce Support SCTP port mapping (bump up API to v1.37)
Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Upstream-commit: 8e435b8279f2af3e0cebd73fa9e25ca1bb26004e
Component: engine
2018-02-20 11:15:36 +09:00
df67d5ea13 Removed root@... PS1 from in-container root prompts, retaining #.
Signed-off-by: Brett Randall <javabrett@gmail.com>
Upstream-commit: bef0cd70a62eff156d99ddd15933b658a1af8893
Component: engine
2018-02-20 11:29:02 +11:00
f4580247c7 test.md improvements and corrections:
- Mentioned integration-cli test-suite deprecation.
- Removed mentions of removed in-container hack/make.sh
  target test-unit, replaced with hack/test/unit.

Signed-off-by: Brett Randall <javabrett@gmail.com>
Upstream-commit: acaa53bc35ab8fa97d75e90da393d39204a86a15
Component: engine
2018-02-20 11:21:03 +11:00
57f5f76274 integration/TestUpdateMemory: simplify
1. Use integration/internal/exec, removing the getContainerSysFSValue().

2. Avoid repeating magic numbers, use a variable for those.

3. Fix order of arguments to assert.Equal (first "expected", then "actual").

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 0f9da07b569f0d9cbe574db3af3951b4d5c968c0
Component: engine
2018-02-19 11:25:27 -08:00
0582099de6 integration/TestUpdateCPUQUota: use exec
An implementation of exec in TestUpdateCPUQUota had a few issues,
including resource leaking and calling both ContainerExecAttach and
ContainerExecRun. The last one makes the test flaky:

	update_linux_test.go:136: expected cgroup value 20000, got: Error: Exec
	command f923baf709525f6b38f6511126addc5d9bb88fb477eeca1c22440551090fa2bb
	is already running

Fix by using the integration/internal/exec package.

While at it, use require/assert to further improve code readability.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 8a7d6143fca69623e2f5d409328c97603843ccb6
Component: engine
2018-02-19 11:25:27 -08:00
b08746e15a integration: add container.Exec()
Some test cases might need an ability to execute a command inside a
container (in order to analyse its output and/or exit code). It is a bit
complicated operation to do so using engine API. The function provided
aims to hide this complexity, making exec almost as simple as 'docker
exec'.

NOTE that the exec is synchronous, and command's stdin is closed.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 01143afe54f1be7308c5663a0cc110740626c62b
Component: engine
2018-02-19 11:25:11 -08:00
5539b125fe Add swarm types to bash completion event type filter
Signed-off-by: Trapier Marshall <trapier.marshall@docker.com>
Upstream-commit: fb80101ca7
Component: cli
2018-02-19 13:46:23 -05:00
39cad2aa10 Merge pull request #36256 from wcwxyz/fix-refcounter-memory-leak
graphdriver: Fix RefCounter memory leak
Upstream-commit: 733ed2ddd3c621dadafbb74feb7b80d20fd3fd6f
Component: engine
2018-02-19 10:32:14 -08:00
c6e83a026f Merge component 'engine' from git@github.com:moby/moby master 2018-02-19 17:05:16 +00:00
7ff06bec92 Merge component 'cli' from git@github.com:docker/cli master 2018-02-19 16:41:15 +00:00
157ffc1e2f Merge pull request #845 from vdemeester/stack-load-the-same
[compose] Share the compose loading code between swarm and k8s stack deploy
Upstream-commit: f56265ae3e
Component: cli
2018-02-19 15:28:40 +01:00
36a89bcfdd Merge pull request #36329 from tonistiigi/tar-cache-fix
builder: fix wrong cache hits building from tars
Upstream-commit: 8cf42d3ad805467be407962f902156a3834062ff
Component: engine
2018-02-19 12:01:20 +01:00
4d022ca109 Merge pull request #880 from vdemeester/container-list-unit-tests
Add unit tests to docker container ls
Upstream-commit: 8900d77a0b
Component: cli
2018-02-19 11:42:10 +01:00
07a8b9380b Add unit tests to docker container ls
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 581b8d9d72
Component: cli
2018-02-19 11:22:36 +01:00
c2407fa324 Clean some cli-only integration tests
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 641c73d211d7efe15255ae36ab2362cef3584260
Component: engine
2018-02-19 11:19:19 +01:00
e46642afe1 Merge pull request #35510 from ripcurld0/fix_35500
Display a warn message when there is binding ports and net mode is host
Upstream-commit: 35d69f10a9ac7479095f39358abb78ee6d3ab65f
Component: engine
2018-02-19 08:57:36 +01:00
da22cbc58d Display a warn message when there is binding ports and net mode is host
When a container is created if "--network" is set to "host" all the
ports in the container are bound to the host.
Thus, adding "-p" or "--publish" to the command-line is meaningless.

Unlike "docker run" and "docker create", "docker service create" sends
an error message when network mode is host and port bindings are given

This patch however suggests to send a warning message to the client when
such a case occurs.

The warning message is added to "warnings" which are returned from
"verifyPlatformContainerSettings".

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Upstream-commit: 6e78fdb790d2e1dbf95a1733cab9395b1b936622
Component: engine
2018-02-18 13:28:44 +00:00
60fb0a3d93 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-17 17:05:04 +00:00
c523bda1bb Merge component 'engine' from git@github.com:moby/moby master 2018-02-17 17:04:57 +00:00
7cf04c3e9b Merge component 'cli' from git@github.com:docker/cli master 2018-02-17 16:41:15 +00:00
de6daa450d Merge pull request #36339 from thaJeztah/bump-continuity
Update containerd/continuity to fix ARM 32-bit builds
Upstream-commit: c5e7537d2305c1855f95422f08ca844d05a17aa2
Component: engine
2018-02-17 15:18:08 +09:00
3657332c34 Add Engine version to docker node ls
This adds the Engine version to `docker node ls`, and `.EngineVersion` as a
template option.

With this patch applied:

    docker node ls
    ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
    wp9231itoqsh4rqceojqo01vp *   linuxkit-025000000001   Ready               Active              Leader              18.01.0-ce

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: e888dd711f
Component: cli
2018-02-17 02:58:05 +01:00
75d038d03f Update containerd/continuity to fix ARM 32-bit builds
This updates the containerd/continuity package to d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
which fixes builds failing on ARM 32-bit, after this dependency was added in
b3aab5e31faf04d8a29f17be55562e4d0c0cb364

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: f0947a541866ca05b030afe07dd659887a655e3e
Component: engine
2018-02-17 00:42:10 +01:00
dcede7a976 Merge pull request #36303 from dnephin/cleanup-in-daemon-unix
Cleanup unnecessary and duplicate functions in `daemon_unix.go`
Upstream-commit: 747c163a65365933c5d6d7f0740f2ac8e3775287
Component: engine
2018-02-16 14:55:18 -08:00
37bb2f6b53 Merge pull request #883 from anusha-ragunathan/set_default_timeout
Set a non-zero timeout for HTTP client communication with plugin backend.
Upstream-commit: a0044ba3a7
Component: cli
2018-02-16 16:46:55 -05:00
69a82cc567 Merge pull request #75 from seemethere/add_libseccomp_dependency
Add libseccomp requirement for CentOS 7
Upstream-commit: c64bed235096ded43782dfdbd72ca499b04457c0
Component: packaging
2018-02-16 12:09:35 -08:00
8bdc8e0190 Set a non-zero timeout for HTTP client communication with plugin
backend.

Currently, the timeout is set to 0, which means no timeout. Set it to a
sane default timeout of 30 seconds.

Signed-off-by: Anusha Ragunathan <anusha.ragunathan@docker.com>
Upstream-commit: f1e2030ce8
Component: cli
2018-02-16 12:00:58 -08:00
fbcb172e80 Merge pull request #36144 from emil2k/node-id-required
Produce errors when empty ids are passed into inspect calls. 
Upstream-commit: db360995df97f9d9bcb4eb6a34a5c35a2711795b
Component: engine
2018-02-16 10:18:47 -08:00
b7ea2ca28b Merge component 'engine' from git@github.com:moby/moby master 2018-02-16 17:06:31 +00:00
3e970eb963 Merge component 'cli' from git@github.com:docker/cli master 2018-02-16 16:41:21 +00:00
e537ce0b31 Error out on secret/config templates for older API
Makes sure if the user specifies an older API version that we don't pass
through templating options for versions that templating was not
supported.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: a407761e483d9c5ea425a6fd5e55fec03a90485c
Component: engine
2018-02-16 11:25:14 -05:00
f68c84b9a0 Merge configs/secrets in unix implementation
On unix, merge secrets/configs handling. This is important because
configs can contain secrets (via templating) and potentially a config
could just simply have secret information "by accident" from the user.
This just make sure that configs are as secure as secrets and de-dups a
lot of code.
Generally this makes everything simpler and configs more secure.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: c02171802b788fb2d4d48bebcee2a57c8eabeeaa
Component: engine
2018-02-16 11:25:14 -05:00
850e2bff8c Always mount configs with tmpfs
This makes configs and secrets behavior identical.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 8e8f5f4457d8e1b02031576dbc18c903be4bcfb6
Component: engine
2018-02-16 11:25:14 -05:00
40e1524cb3 daemon: Check return value of createSecretDir
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: 426f4e48e3e53b2445835585d7957043a5fe6ab3
Component: engine
2018-02-16 11:25:14 -05:00
599f92e497 Store configs that contain secrets on tmpfs
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: cd3d0486a6f62afac50f2cf74e2b9d8728848c97
Component: engine
2018-02-16 11:25:14 -05:00
82ebb2a6fd integration-cli: Add secret/config templating tests
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: cdd2e6efdbf402c629844cb20955f160327917b9
Component: engine
2018-02-16 11:25:13 -05:00
fc6a93f926 api: Add Templating parameter to SecretSpec and ConfigSpec
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: c5df7235f6a4811f26b37441db401f6b04858504
Component: engine
2018-02-16 11:25:13 -05:00
a6e6cffaed executor: Use a TemplatedDependencyGetter to support template expansion
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: 56da5fd7d31c9a627fc6a3c482cb0bf0ffb2d26e
Component: engine
2018-02-16 11:25:13 -05:00
dd73a093e4 Merge pull request #564 from thaJeztah/fix-yaml-examples
Fix leading characters being stripped from example sections in YAML
Upstream-commit: 847cc4bdc0
Component: cli
2018-02-16 11:22:24 -05:00
8a28d41c4f Merge pull request #36335 from thaJeztah/sync-libnetwork-commits
Sync binary commits with vndr
Upstream-commit: 302e584b78db16ea39aca7d7c1612370c50d20f5
Component: engine
2018-02-16 16:12:53 +01:00
44b01cd383 Merge pull request #840 from dekkagaijin/master
GetAll -> Get to retrieve credentials from credential helpers
Upstream-commit: 69432c48db
Component: cli
2018-02-16 15:38:53 +01:00
0a0d1f70a0 Update tomlv for MIT License
The BurntSushi/toml code is now re-licensed as MIT. While
the vendored package was already updated, the tomlv binary
used was still using the old license type.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 508d5a0bc00400fb41395223cb4c8be3d9b74ade
Component: engine
2018-02-16 13:42:27 +01:00
3806697c36 Sync version of userland-proxy with libnetwork vendor
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: dcf9e7ee1a6f1b840e05e88aeb1aaf2415af38ad
Component: engine
2018-02-16 13:41:13 +01:00
d4bbb49d5c Add notes about keeping versions in sync
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 02ca7dc6e91931d6d418cbfa006c0bcf67861ae5
Component: engine
2018-02-16 13:38:45 +01:00
b38d6149be Merge pull request #36306 from cpuguy83/fix_logopt_validator_plugins
Move log validator logic after plugins are loaded
Upstream-commit: 04d97267b6b57987030862c0d355c9a49eb0e445
Component: engine
2018-02-16 11:52:23 +01:00
4a4ea266a9 Merge pull request #828 from thaJeztah/update-authors
Update authors
Upstream-commit: cb85d55e8d
Component: cli
2018-02-16 11:38:58 +01:00
ff398aa5c7 Merge pull request #34900 from dnephin/send-codecov-report
Create and send codecov report
Upstream-commit: 01bfb6d27c6a4b12c777a11c58830a5ef83379a9
Component: engine
2018-02-16 11:36:51 +01:00
d3ed73b92e Update authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: f8da04a510
Component: cli
2018-02-16 11:20:05 +01:00
d2ece4f9f2 Merge pull request #536 from thaJeztah/update-gitignore
Update gitignore
Upstream-commit: 2001500c6e
Component: cli
2018-02-16 10:26:58 +01:00
92f3e5322f Merge pull request #372 from jphuynh/completion-zsh-event-filter
Update event filter zsh completion with `disable`, `enable`, `install…
Upstream-commit: c6a7046674
Component: cli
2018-02-16 10:16:40 +01:00
bc08869249 builder: fix wrong cache hits building from tars
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: f6c8266afddcf24a2eb629af3b8e924e9c78ce73
Component: engine
2018-02-15 23:42:42 -08:00
d9b7b3fed0 Document service --network long form
Signed-off-by: Alexander Ryabov <i@sepa.spb.ru>
Upstream-commit: 94ecd2ba73
Component: cli
2018-02-16 09:34:42 +03:00
694d72e031 Merge pull request #36323 from iporsut/remove-getOffsetToReader
Remove unused method from multireader package
Upstream-commit: 89ce4209bd1fed97e30843f7ce1d4b9866ad2ca6
Component: engine
2018-02-15 21:12:41 -05:00
963b00a076 Ensure daemon root is unmounted on shutdown
This is only for the case when dockerd has had to re-mount the daemon
root as shared.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 487c6c7e73dbb7871e80d75f176dd2a3539a2947
Component: engine
2018-02-15 15:58:20 -05:00
cc3e819977 Merge pull request #36304 from Microsoft/jjh/dontrestoreimageformissinglayer
Don't restore image if layer does not exist
Upstream-commit: b1a1234c60cf87048814aa37da523b03a7b0d344
Component: engine
2018-02-15 14:48:36 -05:00
a4ed28f439 Merge pull request #36274 from thaJeztah/bump-swarmkit
Bump SwarmKit to f74983e7c015a38a81c8642803a78b8322cf7eac
Upstream-commit: 1474ec1ecf56a2ec711e42f008cbea4e8287503d
Component: engine
2018-02-15 18:40:09 +01:00
c900fb9923 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-15 17:07:08 +00:00
481715cd83 Merge component 'engine' from git@github.com:moby/moby master 2018-02-15 17:07:01 +00:00
fec234b5f1 Merge pull request #878 from adshmh/add-unit-tests-to-plugin-package
Add unit tests to plugin create/remove/enable/disable commands
Upstream-commit: 4bc27c68ac
Component: cli
2018-02-15 18:02:36 +01:00
b4446f4926 Move log validator logic after plugins are loaded
This ensures that all log plugins are registered when the log validator
is run.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: b0b9a25e7e60abbe143e149ccaaf4dfb62044016
Component: engine
2018-02-15 11:53:11 -05:00
25714179da Merge pull request #36322 from thaJeztah/fix-build
Fix import path
Upstream-commit: 7d8fa84e11154bf31644b41c50daaac79f463ad5
Component: engine
2018-02-15 11:52:38 -05:00
1ef968a6d2 Merge component 'cli' from git@github.com:docker/cli master 2018-02-15 16:41:17 +00:00
78ec305ac2 Remove unused method from multireader package
Signed-off-by: Weerasak Chongnguluam <singpor@gmail.com>
Upstream-commit: 6e5fba98a53a832dc1654d87637df14c5b9ab2f1
Component: engine
2018-02-15 23:10:56 +07:00
e8ddf74a02 Test invalid filter and move validation on top
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 05e7f2cf58bdd6c1aaf3da9a92ebcd54cdde6d09
Component: engine
2018-02-15 16:24:26 +01:00
664a0689f9 Fix import path
The utils package was moved to "internal" in commit
af306d149e76b100e08972cda364647bd7bcfe1e

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ce35439015e4d2190bd82a3b6dfec98f7a12ac90
Component: engine
2018-02-15 15:29:45 +01:00
2b13e6eda3 Merge pull request #36318 from yongtang/02152018-docker-py
Update docker-py to 5e28dcaace5f7b70cbe44c313b7a3b288fa38916
Upstream-commit: 1690103906f3e0554a0a9f7ebaadd86363b212f7
Component: engine
2018-02-15 15:15:23 +01:00
66a715574f Merge pull request #36055 from cpuguy83/slave_mounts_for_root
Use rslave propagation for mounts from daemon root
Upstream-commit: ea34f827112b3837e5349827f6309a37217854cb
Component: engine
2018-02-15 12:57:25 +01:00
7fad1f8a1a Merge pull request #36320 from yongtang/02142018-diff-tests
Migrate container diff tests in integration-cli to api tests.
Upstream-commit: 6f8af32f224c986367bc341df8d4abc1a7b6e018
Component: engine
2018-02-15 03:53:21 -08:00
f2f9da3776 add tests to plugin create/remove/enable/disable commands. Part of work on #37
Signed-off-by: Arash Deshmeh <adeshmeh@ca.ibm.com>
Upstream-commit: 0a914da708
Component: cli
2018-02-15 06:20:26 -05:00
90c87d3cd7 Migrate container diff tests in integration-cli to api tests.
This fix migreates container diff tests in integration-cli
to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9537498cedc4e28ee0c8c26ba3d9e59ebb59fcad
Component: engine
2018-02-15 01:03:29 -08:00
1903b720b8 Remove docker_cli_diff_test.go from integration-cli
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: f19bea20c91e1cd5a748aa241e7083e8c6246634
Component: engine
2018-02-15 01:03:29 -08:00
bb78e86790 Merge pull request #36298 from arm64b/fix-internal-network-mode
Fix `DockerNetworkInternalMode` issue
Upstream-commit: e3102d5055995a43b090dbc29342a1846a39edae
Component: engine
2018-02-15 09:49:15 +01:00
f91bc41f1e Merge pull request #36308 from thaJeztah/bump-containerd-1.0.2
Bump containerd to 1.0.2 (cfd04396dc68220d1cecbe686a6cc3aa5ce3667c)
Upstream-commit: 41bed9e6d55c39abac701db7a8492026886a95d5
Component: engine
2018-02-15 09:12:55 +01:00
28ab1221fd Merge pull request #36315 from dnephin/move-commit-to-container-api
Move commit to container backend
Upstream-commit: d6ac79be3454a3ba34672290218ea5a53b1201a2
Component: engine
2018-02-15 09:10:52 +01:00
d80026fd7e Update docker-py to 5e28dcaace5f7b70cbe44c313b7a3b288fa38916
This fix updates docker-py:
```
-ENV DOCKER_PY_COMMIT 1d6b5b203222ba5df7dedfcd1ee061a452f99c8a
+ENV DOCKER_PY_COMMIT 5e28dcaace5f7b70cbe44c313b7a3b288fa38916
```

The updated docker-py includes https://github.com/docker/docker-py/pull/1909
which is required to have #36292 pass the tests.

Full diff is in 1d6b5b2032...5e28dcaace.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9d9af83b0fd70ff6a7faa15cf8746669f0f3b588
Component: engine
2018-02-15 07:43:44 +00:00
98a1f0698b Merge pull request #86 from eiais/newPackages
Update readme to supported packages
Upstream-commit: a54da87b1f51743d9b750a8f1d4997e332faa903
Component: packaging
2018-02-14 17:04:13 -08:00
b741266882 Update readme to supported packages
Signed-off-by: Kyle Spiers <kyle@spiers.me>
Upstream-commit: a82d3959676cf185fb7a0511edb036983cedbf21
Component: packaging
2018-02-14 15:21:31 -08:00
0e750709d3 Move commit to container backend
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: e574c5ae73f2f54c47319e5e4a17b16bd93213be
Component: engine
2018-02-14 16:06:12 -05:00
c82207f253 Add libseccomp requirement for CentOS 7
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 86f76496ce33bd6eff1737348bc44add4723ddd2
Component: packaging
2018-02-14 19:17:32 +00:00
a592702237 Remove duplicate rootFSToAPIType
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 4ceea53b5e6a86c39122e99f6ffbc1142d28a174
Component: engine
2018-02-14 11:59:18 -05:00
9e1c0d7187 Remove unnecessary getLayerInit
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: c502bcff33e10be55f15366e123b25574016a9af
Component: engine
2018-02-14 11:59:10 -05:00
8bb8847f9c Merge pull request #36237 from cpuguy83/zfs_do_not_unmount
Do not recursive unmount on cleanup of zfs/btrfs
Upstream-commit: 68c3201626439d5be5c24d14d4fe7e27fe93954d
Component: engine
2018-02-14 09:49:17 -05:00
e156b95318 Merge pull request #35892 from javabrett/dockerfile-on-docker-build-comments
Updated docker-on-docker build-notes.
Upstream-commit: 62c433cd922a9dbd2b989d098fe331c939fe6b71
Component: engine
2018-02-14 09:26:59 -05:00
86dfabe9b6 Share the compose loading code between swarm and k8s stack deploy
To ensure we are loading the composefile the same wether we are pointing
to swarm or kubernetes, we need to share the loading code between both.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 570ee9cb54
Component: cli
2018-02-14 14:07:48 +01:00
1d51022fe8 Updated docker-on-docker build-notes.
These are now more in-line with wiki instructions. Also removes
broken/deprecated make target test-unit.

Signed-off-by: Brett Randall <javabrett@gmail.com>
Upstream-commit: ba49e8c49830b69c833edff3c393716da20f897a
Component: engine
2018-02-14 22:08:37 +11:00
9ab4ce343a Merge pull request #36305 from cpuguy83/35370_fix_logs_eof
Fix log tail with empty logs
Upstream-commit: e698b6e098ac696daa1a7a80d4bdac08b305b328
Component: engine
2018-02-14 16:41:22 +09:00
d88a6732e6 Merge pull request #35749 from thaJeztah/change-swagger-install
Update go-swagger installation steps in Dockerfile
Upstream-commit: 0f6dc962a5ad650dcb3b5a72ce4eb831deacda7b
Component: engine
2018-02-14 08:20:06 +01:00
4d4ce758aa Merge pull request #876 from vdemeester/maintainers-clean
Remove some maintainers 👼
Upstream-commit: 3e5f2f29ad
Component: cli
2018-02-14 08:10:04 +01:00
16fed85531 Merge pull request #36301 from vdemeester/clean-maintainers
Remove some maintainers 👼
Upstream-commit: 72d89c25c0c8d5e0e61f3eec92765c2078924ab2
Component: engine
2018-02-14 08:09:29 +01:00
b660bf165d Unify the frozen images to the multi-arch version
Update and unify the `busybox` images on all arches to the `glibc` multi-arch
version and remove the temp workaround on amd64 which uses the old version
busybox (v1.26) before this PR to bypass the failure of those network related
test cases. Also, this PR will fix all the network related issues with `glibc`
version `busybox` image.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 3a971009763387856bb7f162accdf6714100e39b
Component: engine
2018-02-14 03:59:04 +00:00
0fb8610c54 Fix log tail with empty logs
When tailing a container log, if the log file is empty it will cause the
log stream to abort with an unexpected `EOF`.
Note that this only applies to the "current" log file as rotated files
cannot be empty.

This fix just skips adding the "current" file the log tail if it is
empty.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: f40860c5f3d3575629d4a932207e866c1fea625d
Component: engine
2018-02-13 21:33:05 -05:00
c38f2d0ac2 Merge pull request #869 from mistyhacks/3343-swarm-network-plugins
Clarify network plugins and swarm mode
Upstream-commit: 9a264be221
Component: cli
2018-02-13 21:05:44 -05:00
281df74045 Update containerd dependencies to match 1.0.2
- ed1cbe1fc3...4f6e87ae04
- 29da22c617...c0710c92e8
- runc (already ahead)
- 76e68349ad...d452837986

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 175cfdcfb521aa83f6a1441b0a4b99cb159f058d
Component: engine
2018-02-14 02:13:07 +01:00
6d509c76c4 Bump containerd to 1.0.2 (cfd04396dc68220d1cecbe686a6cc3aa5ce3667c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: c2fb6db55be08da95b15bee730a191094f846577
Component: engine
2018-02-14 01:35:22 +01:00
25813b19fa Merge pull request #36269 from Microsoft/jjh/remove-lcow-api-platform-if-omitted
Remove interim env var LCOW_API_PLATFORM_IF_OMITTED
Upstream-commit: 04cb98e6b5e5bd9dac0b92fcc13966498053aa7e
Component: engine
2018-02-13 15:12:18 -08:00
f914512cd5 Merge pull request #36271 from dnephin/use-tag-image-in-commit
Use TagImage in Commit
Upstream-commit: 060893ab5d97d6582770224db3623ad1b3bdb6e1
Component: engine
2018-02-13 16:40:17 -05:00
0f7a16334c Merge pull request #36222 from yongtang/02062018-runc
Update runc to 6c55f98695e902427906eed2c799e566e3d3dfb5
Upstream-commit: 5eb2f98a352de1fb9a32b1795a9f16e6e73bc8db
Component: engine
2018-02-13 12:40:35 -08:00
ea40d8289f Merge pull request #36290 from cpuguy83/use_c8d_fs_pkg
Use continuity fs package for volume copy
Upstream-commit: fc1f95bdb777c59d84e31d56a7a345af92bfe0d8
Component: engine
2018-02-13 15:22:17 -05:00
39948932b1 Don't restore image if layer does not exist
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 6903ca89af71d40aeaa0277dab13d3dc6dd801a7
Component: engine
2018-02-13 11:51:01 -08:00
069181a5f7 Merge pull request #36294 from yongtang/02122018-update
Update api tests to use container.Run/Create in helper package
Upstream-commit: bbd9b7ffdf924de8444b5cbc7c41deb604acc8b7
Component: engine
2018-02-13 13:21:49 -05:00
f29b55d081 Merge component 'engine' from git@github.com:moby/moby master 2018-02-13 17:04:05 +00:00
b624ca41cd Merge component 'cli' from git@github.com:docker/cli master 2018-02-13 16:41:09 +00:00
e04d07e253 Merge pull request #36291 from yongtang/02052018-configs-test
Migrates several swarm configs tests from integration-cli to api tests
Upstream-commit: 82d1aedf5325aadcb35e6fd0bfe2008fe37ac88e
Component: engine
2018-02-13 17:24:26 +01:00
65db1dafe3 Update runc to 6c55f98695e902427906eed2c799e566e3d3dfb5
This fix is related to 36219

This fix updates runc to:
```
-RUNC_COMMIT=9f9c96235cc97674e935002fc3d78361b696a69e
+RUNC_COMMIT=6c55f98695e902427906eed2c799e566e3d3dfb5

-github.com/opencontainers/runc 9f9c96235cc97674e935002fc3d78361b696a69e
+github.com/opencontainers/runc 6c55f98695e902427906eed2c799e566e3d3dfb5
```

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: d644050db2a2e341726df49b7a43fc37c05d554a
Component: engine
2018-02-13 15:56:44 +00:00
366c7398c0 Add WithNetworkMode, WithExposedPorts, WithTty, WithWorkingDir to container helper functions
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: eaa1a0c218454c7f102a1a56c657e806e30d1b1b
Component: engine
2018-02-13 15:45:40 +00:00
7ebcfdf8bd Update api tests to use container.Run/Create in helper package
This fix is a sync up with 36266 so that relevant api tests
use the newly added container.Run/Create in helper package

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9fcd2a05106af98e6ffd6efb9f124d64426956e4
Component: engine
2018-02-13 14:54:31 +00:00
cd33455198 Clean some maintainers 👼
albers, aluzzardi, ehazlett, icecrime, lk4d4, mavenugo 🤗

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: de664ac749ed25271e6b498aa5b7735dd2f1e026
Component: engine
2018-02-13 14:42:50 +01:00
7f25d42388 Clean some maintainers 👼
aluzzardi, anusha, crosbymichael, ehazlett, johnstep, mavenugo, mlaventure 🤗

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 2a56ebddcb
Component: cli
2018-02-13 11:32:54 +01:00
e6e5d18154 Merge pull request #36299 from liubin/fix-typo-pkg
Fix typo and incorrect return value in pkg
Upstream-commit: 95ce998c10ac407ee0a07c92f14969b573df478e
Component: engine
2018-02-13 01:23:58 -05:00
4efb1e07a3 Merge pull request #875 from kolyshkin/man
Improve man pages
Upstream-commit: 4519c83d44
Component: cli
2018-02-13 00:29:28 +01:00
5f5ee4bd87 Merge pull request #36268 from Microsoft/jjh/rs3-bump
Windows: Bump to final RS3 build number
Upstream-commit: bf1345d0b6d91f24e06d05e741897bc83cf8bab4
Component: engine
2018-02-12 14:49:33 -08:00
f825ac0204 Update integration test to account for SwarmKit change
The PKCS8 changes updated the encryption on the keys so that the
`x509.IsEncryptedPEMBlock` may no longer return true because it cannot
parse the PEM block. The `keyutils` module in SwarmKit can tell whether
it is encrypted either way.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ed7d7b9b0577895e8305e87816cb52fc4e2a0b92
Component: engine
2018-02-12 23:25:51 +01:00
f0113d4e5a Use continuity fs package for volume copy
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: b3aab5e31faf04d8a29f17be55562e4d0c0cb364
Component: engine
2018-02-12 16:43:51 -05:00
85207ef75c man/docker-run.1.md: --restart, --ipc, --network options
Describe the possible values for `--restart`, `--ipc`, and `--network`
options. While at it, improve formatting for `--name` options arguments.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 0d9bd33bab
Component: cli
2018-02-12 12:43:24 -08:00
bd1e6937cb Bump cpuguy83/go-md2man to v1.0.8
The biggest motivation for this is proper table rendering; in the
old version it was broken so tables were not rendered at al
(i.e. anything that was put into table was lost, for example,
description of LOG_* log levels in dockerd(8) page).

This also fixes lists, including nested lists. This fixes the
description of behavior in docker-cp(1) which is rendered as a tree:

BEFORE:

```
      Assuming a path separator of /, a first argument of SRC_PATH and second
       argument of DEST_PATH, the behavior is as follows:

       · SRC_PATH specifies a file

       · DEST_PATH does not exist

       · the file is saved to a file created at DEST_PATH

       · DEST_PATH does not exist and ends with /

       · Error condition: the destination directory must exist.

...
```

AFTER:
```
      Assuming a path separator of /, a first argument of SRC_PATH and second
       argument of DEST_PATH, the behavior is as follows:

              · SRC_PATH specifies a file

                · DEST_PATH does not exist

                  · the file is saved to a file created at DEST_PATH

                · DEST_PATH does not exist and ends with /

                  · Error condition: the destination directory must exist.

...
```

Manually checking the diff between the man pages generated by the old
and the new version, there are no changes other than the indentation
(.RS/.RE) for lists, and proper formatting for tables. Formatted man
pages also look decent, nothing seems broken.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 6566f5ff2c
Component: cli
2018-02-12 12:01:20 -08:00
c28bbfe97a Migrates several swarm configs tests from integration-cli to api tests
This fix migrates several swarm configs tests from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 63bd2425fd5ec0dd17aad830652c1b0c5515a31c
Component: engine
2018-02-12 19:38:56 +00:00
f06f7f1849 Remove docker_api_swarm_config_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 31301769106f53a86d194ad68ff02642204a60cf
Component: engine
2018-02-12 19:33:17 +00:00
51450d870a Replace go-bindata with esc
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: b127b8d927
Component: cli
2018-02-12 14:23:19 -05:00
228b4fffc0 Merge pull request #36246 from sirreal/fix/swagger-buildargs-type
Fix string type for buildargs API definition
Upstream-commit: 9cbe066e2709cb98ff44b687c2fba1956ff95872
Component: engine
2018-02-12 11:21:42 -08:00
ac895d7e08 Merge pull request #36284 from yongtang/02112018-update-tests
Migrate some update restart tests to api tests
Upstream-commit: 919be92823f970bcf26a64bc4002723baac8cb32
Component: engine
2018-02-12 11:21:21 -08:00
86aa3ea787 Merge pull request #36261 from yongtang/02082018-oom-killed
Migrate docker_cli_oom_killed_test.go to api tests
Upstream-commit: 1bb389121d985affeb2a572bc48d3f2cd38582ed
Component: engine
2018-02-12 09:50:26 -08:00
37a1758a61 Merge pull request #36234 from yongtang/02042018-config-ls
Migrate config list tests from integration-cli to api tests
Upstream-commit: 848cf75f1f3cf45ede5817201fd6febe7225c764
Component: engine
2018-02-12 18:36:14 +01:00
134f46c1e9 Merge pull request #36270 from dperny/fix-client-tls
Fix TLS from environment variables in client
Upstream-commit: bc17d0724a2b7843ada42425453517c549472777
Component: engine
2018-02-12 18:35:55 +01:00
53e6b2eab2 Merge pull request #36283 from yongtang/02052018-secrets-tests
Migrates several swarm secrets from integration-cli to api tests
Upstream-commit: 54d56bbcf454435822d6a696fd7477e31aec9f27
Component: engine
2018-02-12 18:34:29 +01:00
be7cd20cb8 Merge component 'engine' from git@github.com:moby/moby master 2018-02-12 17:05:46 +00:00
119c362758 Merge pull request #872 from nogoegst/fix-unsupported-default-credential-store
Fix compilation of defaultCredentialStore() on unsupported platforms
Upstream-commit: dcd62981c4
Component: cli
2018-02-12 11:51:18 -05:00
e286c9f54e Merge component 'cli' from git@github.com:docker/cli master 2018-02-12 16:42:18 +00:00
8b434386b4 Merge pull request #36279 from yongtang/36266-follow-up
Update api tests to use the newly added container helper package
Upstream-commit: 5d26170cfdb16586d8cd1069a0111930499025a6
Component: engine
2018-02-12 08:24:12 -08:00
4d79f94efe Migrate some update restart tests to api tests
This fix migrates some update restart tests in
integration-cli to api tests in integration.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 5b65cee9150b343c97606adc525cf680fb330642
Component: engine
2018-02-12 16:23:08 +00:00
7f1e764c34 Merge pull request #36285 from yongtang/02112018-session-tests
Migrates session tests in integration-cli to api tests
Upstream-commit: 945b786c140b037822c3f1792c3a05a1c16c9a4b
Component: engine
2018-02-12 11:04:49 -05:00
5c9e151bc4 Merge pull request #841 from vdemeester/e2e-kill-test
Add e2e container kill test
Upstream-commit: 85f9fb56b3
Component: cli
2018-02-12 15:14:41 +01:00
4816de08ce Add example buildargs usage
Signed-off-by: Jon Surrell <jon.surrell@gmail.com>
Upstream-commit: 344c73ac672cd4d4f70a08b5a41b6835d9873926
Component: engine
2018-02-12 14:09:37 +01:00
535cb21e7e Reformat to multi-line
Signed-off-by: Jon Surrell <jon.surrell@gmail.com>
Upstream-commit: de2b2b5e4ba0cb297d47a7b05614190fa44f54a2
Component: engine
2018-02-12 14:09:31 +01:00
a6f0fffe6c Merge pull request #36249 from cpuguy83/36145_fix_container_reload
Fix container cleanup on daemon restart
Upstream-commit: 812592d911146791500efc1fb46c3429d9d645b2
Component: engine
2018-02-12 11:36:18 +01:00
afc39de469 Merge pull request #36273 from yongtang/02092018-pause_test
Migrate container pause tests to api tests
Upstream-commit: 5f9570c7ac1775debec250e8b53ff2ff42f36a74
Component: engine
2018-02-12 02:32:52 -08:00
3b4c1991cb Merge pull request #871 from vdemeester/stack-deploy-update-ref
Update reference docs for docker stack deploy
Upstream-commit: 3e344ae425
Component: cli
2018-02-12 11:08:21 +01:00
15d857c4ce Merge pull request #36275 from liubin/fix-daemon
Fix typos in daemon directory
Upstream-commit: 84bde485d754248565b86d2873728da2717e46b9
Component: engine
2018-02-12 09:18:01 +01:00
b61dd8e57f Migrate container pause tests to api tests
This fix migrates container pause tests from integration-cli
to api tests in integration/.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: ea2f076ca986038c48af37feaba6524f32761406
Component: engine
2018-02-12 01:24:43 +00:00
5d80bc453f Migrates session tests in integration-cli to api tests
This fix migrates session tests in integration-cli to
api tests in integration.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 1d40c6a8999bdddbb57c199c2cf6e5d103153e69
Component: engine
2018-02-11 23:14:39 +00:00
46e07309bd Migrates several swarm secrets from integration-cli to api tests
This fix migrates several swarm secrets from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: f955d2e2042cabaeac8a451b83a507b76e606d33
Component: engine
2018-02-11 21:17:44 +00:00
4571efe6b5 Remove docker_api_swarm_secret_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 3499557c9b3aa728cb52402c1bb4302f80ab4721
Component: engine
2018-02-11 21:17:25 +00:00
e2c834a1a9 Migrate docker_cli_oom_killed_test.go to api tests
This fix migrates tests in integration-cli/docker_cli_oom_killed_test.go
to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 3c21274b76323883e8ffb146fb989850c4de221a
Component: engine
2018-02-11 20:09:32 +00:00
bf8ec4c4d2 Migrate config list tests from integration-cli to api tests
This fix migrates config list tests from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 246f450ac4fcaff15f36874475f15f435ab03a15
Component: engine
2018-02-11 19:39:56 +00:00
dd36e40493 Remove integration-cli/docker_cli_config_ls_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 955a2b81940181ef51b31feacbf234dab98e56d1
Component: engine
2018-02-11 19:26:39 +00:00
401e32ece2 Merge component 'engine' from git@github.com:moby/moby master 2018-02-11 17:05:14 +00:00
e3241636cf Merge pull request #36257 from arm64b/fix-inspect-network-timeout
Fix timeout issue of `InspectNetwork` on AArch64
Upstream-commit: 178ebca0b9fdf41d473cd6dd52ff6607bed28fd7
Component: engine
2018-02-11 20:50:08 +09:00
fd34f2aedf Merge pull request #36276 from nogoegst/update-vendor-x-sys
Update golang.org/x/sys vendor
Upstream-commit: 52a65f6e34261158007d6b85fb90ebe65cfa73af
Component: engine
2018-02-11 17:08:15 +09:00
9bb3c2d897 Update api tests to use the newly added container helper package
This fix is a follow up to 36266 to update some api tests
to use the newly added container helper package.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e9f19df6a9d8ba682f3c9dcdaffed2ac4e0c6189
Component: engine
2018-02-10 23:30:40 +00:00
1d4b488828 Remove integration-cli/docker_cli_pause_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 6453d49d05a020aef1426c1676d9cc73217c8ff2
Component: engine
2018-02-10 23:03:55 +00:00
396aa8a139 Merge pull request #36266 from vdemeester/integration-container-helper
Add an integration/internal/container helper package 
Upstream-commit: d07d3e71171ea3125d4462e8e509170f7c3e3370
Component: engine
2018-02-10 12:57:58 -08:00
e1e478d6bf Merge component 'engine' from git@github.com:moby/moby master 2018-02-10 17:03:59 +00:00
defd7909c5 Add an integration/internal/container helper package
To help creating/running/… containers using the client for test integration.
This should make test more readable and reduce duplication a bit.

Usage example

```
// Create a default container named foo
id1 := container.Create(t, ctx, client, container.WithName("foo"))
// Run a default container with a custom command
id2 := container.Run(t, ctx, client, container.WithCmd("echo", "hello world"))
```

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 0bb7d42b03bfb125cd50ab50dabe99726e66ab71
Component: engine
2018-02-10 17:29:38 +01:00
3927eb596e Update golang.org/x/sys vendor to 37707fdb30a5b38865cfb95e5aab41707daec7fd
Signed-off-by: Ivan Markin <sw@nogoegst.net>
Upstream-commit: 6f66ccaf507e58f3031a88ec85a84a77c0c3b928
Component: engine
2018-02-10 15:58:20 +00:00
6f3d7b05d2 Fix compilation of defaultCredentialStore() on unsupported platforms
Signed-off-by: Ivan Markin <sw@nogoegst.net>
Upstream-commit: 57c51c8af3
Component: cli
2018-02-10 15:30:32 +00:00
3ca395f582 Merge pull request #36265 from vdemeester/rename-integration-util-to-internal
Rename integration/util to integration/internal
Upstream-commit: 3053006679aa7b6427286f94c3922412ed99f354
Component: engine
2018-02-10 14:25:28 +01:00
6a659ff498 Fix typos in pkg
Signed-off-by: bin liu <liubin0329@gmail.com>
Upstream-commit: 7a7a8a33a4a79e7ea1e67f8a77b4060f95e936ea
Component: engine
2018-02-10 19:43:13 +08:00
4adc380b90 Fix typos in daemon
Signed-off-by: bin liu <liubin0329@gmail.com>
Upstream-commit: b00a67be6e3d3f241879110bd342abaa8e23cbac
Component: engine
2018-02-10 19:42:54 +08:00
1c3e1e8db6 Rename integration/util to integration/internal
Both names have no real sense, but one allows to make sure these packages
aren't used outside of `integration`.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: af306d149e76b100e08972cda364647bd7bcfe1e
Component: engine
2018-02-10 09:16:32 +01:00
7179b03d8b Bump SwarmKit to f74983e7c015a38a81c8642803a78b8322cf7eac
- Replace EC Private Key with PKCS#8 PEMs
- Fix IP overlap with empty EndpointSpec
- Add support for Support SCTP port mapping (depends on changes in libnetwork)
- [orchestrator/updater] Do not reschedule tasks if only placement constraints change and are satisfied by the assigned node
- Ensure task reaper stopChan is closed no more than once
- [manager/dispatcher] Synchronization fixes

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 191324b8f1e1a2b2dbe692f869bfbf525d150ade
Component: engine
2018-02-09 18:39:49 -08:00
81a9d51f50 Merge pull request #36242 from kolyshkin/rwlayer-nil-deref
c.RWLayer: check for nil before use
Upstream-commit: ab3ea81376441e93311c94910be78ac42292c496
Component: engine
2018-02-09 18:13:03 -08:00
8382b77c1c Use TagImage in Commit
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: afb3eda697efebf18d8ac3bbcfd911a5968081e3
Component: engine
2018-02-09 20:53:39 -05:00
d92fe4f6a1 Fix TLS from environment variables in client
A recent change accidently caused any TLS configuration in FromEnv to be
ignored. This change alters WithHost to create a new http client only if
one doesn't already exist, and otherwise applies the logic to the
transport on the existing client. This preserves the TLS configuration
that might already be on the client.

Signed-off-by: Drew Erny <drew.erny@docker.com>
Upstream-commit: 80904e9571e7724328160c97ede6a71864f3c06a
Component: engine
2018-02-09 15:29:32 -08:00
cd579fc565 defaultIndexserver -> defaultIndexServer
Signed-off-by: Jake Sanders <jsand@google.com>
Upstream-commit: e1b607a351
Component: cli
2018-02-09 13:48:01 -08:00
e42b22c770 Merge pull request #36259 from yongtang/02082018-kill_test
Migrate TestKillDifferentUserContainer to api test
Upstream-commit: 2d97f5e7800b43a7ea9106c3c95200c6f4404930
Component: engine
2018-02-09 13:47:35 -08:00
2f849b7e23 Merge pull request #36260 from yongtang/02082018-inspect_test
Migrate docker_api_inspect_unix_test.go to integration api test
Upstream-commit: 5589e9cad1107eb9cf030b73d9375e9a7c84cc47
Component: engine
2018-02-09 13:33:51 -08:00
663c468cfb Merge pull request #36221 from yongtang/02032018-secret_ls
Migrate secret list tests from integration-cli to api tests
Upstream-commit: 9d55eefc1b4553260785c1c09772ccd9660b075f
Component: engine
2018-02-09 13:29:19 -08:00
d3c6f2e0ef Remove interim env var LCOW_API_PLATFORM_IF_OMITTED
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: c111fec758770a37e8674cac312e528e85d89428
Component: engine
2018-02-09 12:05:07 -08:00
0a75e5196f Windows: Bump to final RS3 build number
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: c04504383a913c1af9868b23880c6401651c71b1
Component: engine
2018-02-09 11:39:57 -08:00
5d3102854b Fix container cleanup on daemon restart
When the daemon restores containers on daemon restart, it syncs up with
containerd to determine the existing state. For stopped containers it
then removes the container metadata from containerd.

In some cases this is not handled properly and causes an error when
someone attempts to start that container again.
In particular, this case is just a bad error check.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: c0d56ab71701ba47ca6066c7952e724f4f5977c0
Component: engine
2018-02-09 14:36:36 -05:00
89a07f6033 c.RWLayer: check for nil before use
Since commit e9b9e4ace294230c6b8eb has landed, there is a chance that
container.RWLayer is nil (due to some half-removed container). Let's
check the pointer before use to avoid any potential nil pointer
dereferences, resulting in a daemon crash.

Note that even without the abovementioned commit, it's better to perform
an extra check (even it's totally redundant) rather than to have a
possibility of a daemon crash. In other words, better be safe than
sorry.

[v2: add a test case for daemon.getInspectData]
[v3: add a check for container.Dead and a special error for the case]

Fixes: e9b9e4ace294230c6b8eb
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 195893d38160c0893e326b8674e05ef6714aeaa4
Component: engine
2018-02-09 11:24:09 -08:00
4db928a87d Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-09 17:07:11 +00:00
13f81c44a2 Merge component 'engine' from git@github.com:moby/moby master 2018-02-09 17:07:05 +00:00
610cac270f Merge component 'cli' from git@github.com:docker/cli master 2018-02-09 16:41:15 +00:00
20c1120c88 Migrate TestKillDifferentUserContainer to api test
This fix migrates TestKillDifferentUserContainer to api test

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 0855922cd3cd1e9d846fd85ef968653ff8649a44
Component: engine
2018-02-09 13:40:32 +00:00
ffb77fa93a Update reference docs for docker stack deploy
`docker stack deploy` now support multiple composefil. This updates the
reference doc to take that fact into account.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 4c50007496
Component: cli
2018-02-09 14:22:45 +01:00
a75949cd5f Migrate docker_api_inspect_unix_test.go to integration api test
This fix migrates docker_api_inspect_unix_test.go to integration api test

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8197529ca2fabc95b9fc4a7e3ff643740b1f4388
Component: engine
2018-02-09 12:56:07 +00:00
fd856e7e70 Merge pull request #36226 from yongtang/36198-follow-up
Add description to TestContainerNetworkMountsNoChown
Upstream-commit: 7e7f8160fcccce94a45596b4fd41f7ddcf9d910f
Component: engine
2018-02-09 04:39:56 -08:00
b582c47758 Fix timeout issue of InspectNetwork on AArch64
Service of inspect network can't be finished within 10s on AArch64 platform,
so we need to adjust the timeout value avoid to paper cover the real issue, plus
to make the integreation test can continue while not terminate with below error:

> === RUN   TestInspectNetwork
> --- FAIL: TestInspectNetwork (27.65s)
>         daemon.go:285: [de79880f4ed4a] waiting for daemon to start
>         daemon.go:317: [de79880f4ed4a] daemon started
>         inspect_test.go:57: timeout hit after 10s: waiting for tasks to enter run state
>         daemon.go:275: [de79880f4ed4a] exiting daemon
> FAIL
> ---> Making bundle: .integration-daemon-stop (in bundles/test-integration)
> Removing test suite binaries
> Makefile:171: recipe for target 'test-integration' failed

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 8f5c1841a8bffb4a7e33f51174177b7ad0182969
Component: engine
2018-02-09 03:20:14 +00:00
9914b54ec0 Merge pull request #36213 from yongtang/02052018-rename_test
Migrate rename tests in integration-cli to api tests
Upstream-commit: afbc9c4cfc5d6f812e3c11c0b0bae8be41f380f7
Component: engine
2018-02-08 18:38:02 -08:00
f74751654b graphdriver: Fix RefCounter memory leak
Signed-off-by: WANG Chao <chao.wang@ucloud.cn>
Upstream-commit: 9015a05606a9bb80f0d8d2e3d43b0b682ca53db4
Component: engine
2018-02-09 10:26:06 +08:00
5072bc0df8 Migrate secret list tests from integration-cli to api tests
This fix migrates secret list tests from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9349c035831e09057bd039b8f677fa19d3354f73
Component: engine
2018-02-09 00:45:22 +00:00
62e1fa1243 Remove docker_cli_secret_ls_test.go from integration-cli
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 42465784dcc61aa69b8fcefe4669d20422471fea
Component: engine
2018-02-09 00:45:08 +00:00
f5f60f4ad4 Migrate rename tests in integration-cli to api tests
This fix migrates rename tests in integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: be24a6b11e36b542d37cf168f6d198d5445803a5
Component: engine
2018-02-08 23:27:14 +00:00
a0a24043be Remove broken container check from image prune
The imageRefs map was being popualted with containerID, and accessed
with an imageID which would never match.

Remove this broken code because: 1) it hasn't ever worked so isn't
necessary, and 2) because at best it would be racy

ImageDelete() should already handle preventing of removal of used
images.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 3aa4f7f0d71f04c5cc93d5e80cbdd47b0b5fdb7f
Component: engine
2018-02-08 18:10:46 -05:00
158c963b62 Merge pull request #36241 from yongtang/02072018-create-tests
Migrate TestCreateTmpfsMountsTarget test to api test
Upstream-commit: 15001f83bdb268ce3d4c0191eab39f443cc6ea5c
Component: engine
2018-02-08 14:58:06 -08:00
95ee01fa37 Merge pull request #85 from thaJeztah/bump-golang-1.9.4
Bump Golang to 1.9.4
Upstream-commit: 522d35bf0b10fa675ce18587e5ff766d021dbd82
Component: packaging
2018-02-08 14:56:16 -08:00
4415397c48 Clarify network plugins and swarm mode
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 16d29b3cd6
Component: cli
2018-02-08 14:08:31 -08:00
8aa2823503 Merge pull request #36140 from vdemeester/integration-container-kill
Migrate some kill integration cli test to api tests
Upstream-commit: 21c9e5701bef4687847adb9c26ac42583a57c174
Component: engine
2018-02-08 09:55:28 -08:00
085b7dfcd2 Merge pull request #36235 from yongtang/02072018-info-api-test
Migrates docker info tests to integration api tests
Upstream-commit: 12ff002eedb602f6c8c36d41876dae15e1587849
Component: engine
2018-02-08 09:55:08 -08:00
7a31f33f22 Merge pull request #868 from thaJeztah/bump-golang-1.9.4
Bump golang to 1.9.4
Upstream-commit: a9ecf823ff
Component: cli
2018-02-08 08:06:52 -08:00
61559bd9ba Migrate TestCreateTmpfsMountsTarget test to api test
This fix migrates TestCreateTmpfsMountsTarget test to api test,
and removed integration-cli/docker_cli_create_unix_test.go

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: f601bc16d555238c86dad1cc0a67bcfcf36a3301
Component: engine
2018-02-08 15:59:12 +00:00
82570b7d22 Migrate some calls to new client function
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 6977f468bbcf43864a5acf6c89c331a9180169e5
Component: engine
2018-02-08 16:21:45 +01:00
c00977eb44 Merge pull request #867 from sungwonh/prune
Clarify description of volume prune command
Upstream-commit: 704d37db8f
Component: cli
2018-02-08 09:56:15 -05:00
8991a8a5bd Merge pull request #36220 from dnephin/support-proxy-in-splunk-driver
Support a proxy in splunk log driver
Upstream-commit: f653485e57a36518085868dcb48b4d924a520877
Component: engine
2018-02-08 15:32:19 +01:00
9887b96613 Move some kill integration cli to api tests
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 2227c8ad5ee2bd2f636651efd4ef70e56c082f85
Component: engine
2018-02-08 15:26:24 +01:00
0590bb4b31 Introduce NewClientWithOpts func to build custom client easily
This allows to create a client with default values and override those
using functors. As an example, `NewEnvClient()` becomes
`NewClientWithOpts(FromEnv)` ; and if you want a different api version
for this client : `NewClientWithOpts(FromEnv, WithVersion("1.35"))`

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 772edd020cc784913973387b00c4d0c526a10a26
Component: engine
2018-02-08 15:26:24 +01:00
83ccee96c3 Merge pull request #36173 from cpuguy83/fix_containerd_crash_spin
Refresh containerd remotes on containerd restarted
Upstream-commit: 384ff69f2f97c0cf0ee2b863bd4d90a82e1cc1a4
Component: engine
2018-02-08 06:19:29 -08:00
d7f3bf126b Merge pull request #36243 from thaJeztah/bump-golang-1.9.4
Bump Golang to 1.9.4
Upstream-commit: 6f33b5a2ab29f3e5db40ed5d958a54e731adca59
Component: engine
2018-02-08 06:17:35 -08:00
e09b72af21 Merge pull request #36224 from dnephin/refactor-commit
Refactor Daemon.Commit()
Upstream-commit: 9769ef333f2af24b30fed0dd7b00384b2df3b953
Component: engine
2018-02-08 21:02:30 +09:00
8ea0c8eb22 Fix string type for buildargs API definition
Signed-off-by: Jon Surrell <jon.surrell@gmail.com>
Upstream-commit: f281358ba2de6204a61cdb062fa67a8b7134739c
Component: engine
2018-02-08 13:00:24 +01:00
940ea8083a Bump golang to 1.9.4
This fixes a vulnerability in `go get` (CVE-2018-6574, http://golang.org/issue/23672),
but shouldn't really affect our code, but it's good to keep in sync.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: b32599761f
Component: cli
2018-02-08 00:56:12 -08:00
909b58836c Remove workaround for Nano server TP5
This workaround for golang/go#15286 was added for Nano server TP5 in
fa82c0aa10cfac8c6d5e2446876dc79b2b0c1bf9, and should no longer be
needed

Due to a security fix in Go 1.9.4/1.8.7, loading the .dll is no longer
allowed, and produces an error:

   .\docker_windows.go:9:3: //go:cgo_import_dynamic main.dummy CommandLineToArgvW%2 "shell32.dll" only allowed in cgo-generated code

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 250193387c98a4ad69a6591d5fe5a39c1409ffba
Component: engine
2018-02-07 23:38:14 -08:00
770eb4a40c Clarify description of volume prune command
volume prune command removes only local volumes
not used by at least one container.

Signed-off-by: Sungwon Han <sungwon.han@navercorp.com>
Upstream-commit: 34504d0a1e
Component: cli
2018-02-08 15:33:07 +09:00
a076c21e0c Remove integration-cli/docker_cli_create_unix_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8331a1a5cf1f7f751fdb011cb9e1aa4b0642c1e5
Component: engine
2018-02-08 00:21:29 +00:00
06e15263e9 Bump Golang to 1.9.4
This fixes a vulnerability in `go get` (CVE-2018-6574, http://golang.org/issue/23672),
but shouldn't really affect our code, but it's good to keep in sync.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6263b1254b179af81ff4ef97563fe2e1a053993a
Component: packaging
2018-02-07 15:15:37 -08:00
72d7f12462 Bump Golang to 1.9.4
This fixes a vulnerability in `go get` (CVE-2018-6574, http://golang.org/issue/23672),
but shouldn't really affect our code, but it's good to keep in sync.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: caeab268430a033fedd27c53be16758ac1a0f71e
Component: engine
2018-02-07 14:49:51 -08:00
fd90b16ff5 Merge pull request #36194 from dnephin/add-canonical-import
Add canonical import path
Upstream-commit: 3a633a712c8bbb863fe7e57ec132dd87a9c4eff7
Component: engine
2018-02-07 13:06:45 -08:00
32c5b53960 Make sure plugin mounts are cleaned up
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: e6f784e3df2095366fd99fd42ab5a2d0b451bd07
Component: engine
2018-02-07 15:54:52 -05:00
eb861a7ae9 Revert "Make plugins dir private."
This reverts commit 0c2821d6f2de692d105e50a399daa65169697cca.

Due to other changes this is no longer needed and resolves some other
issues with plugins.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 37d7b7ddc332541f516d0c41d9ad30b28f2d3e22
Component: engine
2018-02-07 15:48:27 -05:00
90450b2044 Ensure plugin returns correctly scoped paths
Before this change, volume management was relying on the fact that
everything the plugin mounts is visible on the host within the plugin's
rootfs. In practice this caused some issues with mount leaks, so we
changed the behavior such that mounts are not visible on the plugin's
rootfs, but available outside of it, which breaks volume management.

To fix the issue, allow the plugin to scope the path correctly rather
than assuming that everything is visible in `p.Rootfs`.
In practice this is just scoping the `PropagatedMount` paths to the
correct host path.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 0e5eaf8ee32662182147f5f62c1bfebef66f5c47
Component: engine
2018-02-07 15:48:27 -05:00
3928c278e5 Plugins perform propagated mount in runtime spec
Setting up the mounts on the host increases chances of mount leakage and
makes for more cleanup after the plugin has stopped.
With this change all mounts for the plugin are performed by the
container runtime and automatically cleaned up when the container exits.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: a53930a04fa81b082aa78e66b342ff19cc63cc5f
Component: engine
2018-02-07 15:48:27 -05:00
c932e5d2a5 Use runtime spec modifier for metrics plugin hook
Currently the metrics plugin uses a really hackish host mount with
propagated mounts to get the metrics socket into a plugin after the
plugin is alreay running.
This approach ends up leaking mounts which requires setting the plugin
manager root to private, which causes some other issues.

With this change, plugin subsystems can register a set of modifiers to
apply to the plugin's runtime spec before the plugin is ever started.
This will help to generalize some of the customization work that needs
to happen for various plugin subsystems (and future ones).

Specifically it lets the metrics plugin subsystem append a mount to the
runtime spec to mount the metrics socket in the plugin's mount namespace
rather than the host's and prevetns any leaking due to this mount.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 426e610e43179d58b29c496bc79a53f410a4b1e1
Component: engine
2018-02-07 15:48:26 -05:00
4ec1fd107e Refactor commit
The goal of this refactor is to make it easier to integrate buildkit
and containerd snapshotters.

Commit is used from two places (api and build), each calls it
with distinct arguments. Refactored to pull out the common commit
logic and provide different interfaces for each consumer.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: daff039049aea6e19a4bda1df2834d14b4198bc0
Component: engine
2018-02-07 15:09:06 -05:00
33ddc6d172 Do not recursive unmount on cleanup of zfs/btrfs
This was added in #36047 just as a way to make sure the tree is fully
unmounted on shutdown.

For ZFS this could be a breaking change since there was no unmount before.
Someone could have setup the zfs tree themselves. It would be better, if
we really do want the cleanup to actually the unpacked layers checking
for mounts rather than a blind recursive unmount of the root.

BTRFS does not use mounts and does not need to unmount anyway.
These was only an unmount to begin with because for some reason the
btrfs tree was being moutned with `private` propagation.

For the other graphdrivers that still have a recursive unmount here...
these were already being unmounted and performing the recursive unmount
shouldn't break anything. If anyone had anything mounted at the
graphdriver location it would have been unmounted on shutdown anyway.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 2fe4f888bee52b1f256d6fa5e20f9b061d30221c
Component: engine
2018-02-07 15:08:17 -05:00
f68b87fd47 Support a proxy in splunk log driver
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 3c4537d5b33d951237ea5e4cc123953eda7a37e7
Component: engine
2018-02-07 14:52:32 -05:00
3257e049e6 update vendor
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 7d296522f68a80d540b20753ea0648171ee12825
Component: engine
2018-02-07 14:46:24 -05:00
49c61840e2 Use rslave propagation for mounts from daemon root
By default, if a user requests a bind mount it uses private propagation.
When the source path is a path within the daemon root this, along with
some other propagation values that the user can use, causes issues when
the daemon tries to remove a mountpoint because a container will then
have a private reference to that mount which prevents removal.

Unmouting with MNT_DETATCH can help this scenario on newer kernels, but
ultimately this is just covering up the problem and doesn't actually
free up the underlying resources until all references are destroyed.

This change does essentially 2 things:

1. Change the default propagation when unspecified to `rslave` when the
source path is within the daemon root path or a parent of the daemon
root (because everything is using rbinds).
2. Creates a validation error on create when the user tries to specify
an unacceptable propagation mode for these paths...
basically the only two acceptable modes are `rslave` and `rshared`.

In cases where we have used the new default propagation but the
underlying filesystem is not setup to handle it (fs must hvae at least
rshared propagation) instead of erroring out like we normally would,
this falls back to the old default mode of `private`, which preserves
backwards compatibility.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 589a0afa8cbe39b6512662fd1705873e2d236dd0
Component: engine
2018-02-07 14:27:09 -05:00
b2efbde0e3 Migrates docker info tests to integration api tests
This fix migrates docker info tests in integration-cli
to integration tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 68d9beedbe0994af5c91022874daa271b657be8c
Component: engine
2018-02-07 18:26:01 +00:00
e1fe1c5e0c Merge component 'engine' from git@github.com:moby/moby master 2018-02-07 17:06:12 +00:00
1e3931f923 Refresh containerd remotes on containerd restarted
Before this patch, when containerd is restarted (due to a crash, or
kill, whatever), the daemon would keep trying to process the event
stream against the old socket handles. This would lead to a CPU spin due
to the error handling when the client can't connect to containerd.

This change makes sure the containerd remote client is updated for all
registered libcontainerd clients.

This is not neccessarily the ideal fix which would likely require a
major refactor, but at least gets things to a working state with a
minimal patch.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 400126f8698233099259da967378c0a76bc3ea31
Component: engine
2018-02-07 11:53:00 -05:00
c599863a52 Merge component 'cli' from git@github.com:docker/cli master 2018-02-07 16:41:16 +00:00
3122cc53fa Produce errors when empty ids are passed into inspect calls.
If a blank nodeID was previously passed in it resulted in a node list
request. The response would then fail to umarshal into a `Node`
type returning a JSON error.

This adds an extra validation to all inspect calls to check that the ID
that is required is provided and if not return an error.

Signed-off-by: Emil Davtyan <emil2k@gmail.com>
Upstream-commit: 3e6bbefd268f51755be5af0644995297a71a05d7
Component: engine
2018-02-07 14:05:14 +01:00
0919d8f13e Merge pull request #36201 from arm64b/oom-kill-disable-fixing
Daemon: passdown the `--oom-kill-disable` option to containerd
Upstream-commit: 2e8ccbb49e21b8696ad4c39185036a8b7e50402f
Component: engine
2018-02-06 21:39:43 -08:00
9e9ebf27ff Merge pull request #36223 from yongtang/02062018-clean
Combine runSimpleContainer with runContainer for rename test
Upstream-commit: 4ba4b4b283162c4917d773bf49f8d2c7f5de6b3c
Component: engine
2018-02-06 17:26:49 -08:00
d2876760b0 Add description to TestContainerNetworkMountsNoChown
This fix is a follow up to 36198 by adding description
to TestContainerNetworkMountsNoChown so that it is clear
about the purpose of the test for ownership.

This fix is related to comment in 36198.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 28a2187ea7f0484ce515e7ae1662d778dcf94720
Component: engine
2018-02-07 00:19:38 +00:00
f496025a99 Merge pull request #36198 from yongtang/02042018-mount-tests
Migrates TestContainersAPINetworkMountsNoChown to api tests
Upstream-commit: 382c9593bfc73a0bf967557c98a560413c537b42
Component: engine
2018-02-06 14:08:35 -08:00
d3b2389f2d Merge pull request #35414 from madhanrm/hotadd1
Enable HotAdd for Windows
Upstream-commit: e62d36bcad6ef1b1beafb15411f927b25f52c3d1
Component: engine
2018-02-06 10:40:39 -08:00
5007511cdb Merge pull request #863 from WTFKr0/tls-env-var
Add DOCKER_TLS environment variable for --tls option
Upstream-commit: b5df4f69db
Component: cli
2018-02-06 10:24:38 -08:00
20243d6421 Combine runSimpleContainer with runContainer for rename test
As there is already a  runSimpleContainer, I think it makes
sense to combine runSimpleContainer with runContainer for rename test
to reduce code duplication.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 203d871658104b00099d818425b25f4cd1eff55b
Component: engine
2018-02-06 17:11:39 +00:00
64efe2121e Merge component 'engine' from git@github.com:moby/moby master 2018-02-06 17:05:01 +00:00
b4ccef5824 Merge component 'cli' from git@github.com:docker/cli master 2018-02-06 16:41:14 +00:00
607349c14f Migrates TestContainersAPINetworkMountsNoChown to api tests
This fix migrates TestContainersAPINetworkMountsNoChown from
integration-cli to api tests in integration.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: c028da3557cc0e9f80aee9b08118e9947e1fa57a
Component: engine
2018-02-06 15:56:20 +00:00
4056ff9d7d Merge pull request #36188 from yongtang/02012018-TestSecretInspect
Migrate TestSecretInspect from integration-cli to api tests
Upstream-commit: 30a8c6c1094aca87f62f321ea1420865565f1d04
Component: engine
2018-02-06 15:19:08 +01:00
5421c51a06 Merge pull request #569 from vdemeester/compose-multiple-version-mergo
Add support for multiple composefile when deploying
Upstream-commit: 25e969c854
Component: cli
2018-02-06 00:41:43 -08:00
3bb4e932f7 Add DOCKER_TLS environment variable
Signed-off-by: WTFKr0 <thomas.kovatchitch@gmail.com>
Upstream-commit: 42fa3ef7d8
Component: cli
2018-02-06 09:27:05 +01:00
ac13dc6ce4 Use Get rather than GetAll to retrieve credentials from credential helpers.
Signed-off-by: Jake Sanders <jsand@google.com>
Upstream-commit: 1d0a37c460
Component: cli
2018-02-05 20:31:46 -08:00
8e79d4b5b1 Merge pull request #860 from mistyhacks/explain-netio-blockio
Explain the columns shown in docker stats
Upstream-commit: e12f71a9b8
Component: cli
2018-02-05 18:47:24 -08:00
70566138f9 Merge pull request #858 from mistyhacks/add-registry-auth-example
Add an example for --with-registry-auth
Upstream-commit: ce985d04ce
Component: cli
2018-02-05 18:45:50 -08:00
be83c11fb0 Add canonical import comment
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 4f0d95fa6ee7f865597c03b9e63702cdcb0f7067
Component: engine
2018-02-05 16:51:57 -05:00
83bc700def Merge pull request #36192 from yongtang/02012018-docker_cli_nat_test
Migrate some of the nat tests in integration-cli to api tests
Upstream-commit: 090c5bf25a53c8656cddfed275874030a6109ec0
Component: engine
2018-02-05 10:54:43 -08:00
4d238fdd93 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-05 18:13:44 +00:00
74954408a8 Merge component 'engine' from git@github.com:moby/moby master 2018-02-05 18:13:38 +00:00
53cc069631 Merge pull request #84 from seemethere/fix_deb_dev
Re-add Git Commit time to deb dev builds
Upstream-commit: 17c691a2dfc4da67dddfb7c33537ba65b5623af3
Component: packaging
2018-02-05 09:46:25 -08:00
44aff4f98f Merge pull request #36191 from cpuguy83/fix_attachable_network_race
Fix race in attachable network attachment
Upstream-commit: 6987557e0cef9bd139128e62d86586a40cda6036
Component: engine
2018-02-05 09:41:35 -08:00
62488ecee8 Merge component 'engine' from git@github.com:moby/moby master 2018-02-05 17:04:33 +00:00
f013c316ca Merge pull request #36202 from AkihiroSuda/remove-wtf
vendor: update BurntSushi/toml for MIT license
Upstream-commit: 874539594333583ea6e3f8459bf9e93ccf19ef35
Component: engine
2018-02-05 09:21:59 +01:00
557565af45 vendor: update BurntSushi/toml for MIT license
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Upstream-commit: 6093b917c2fa4fc642ac691489ead1f175f1d6b7
Component: engine
2018-02-05 13:57:49 +09:00
fa06c65a30 Daemon: passdown the --oom-kill-disable option to containerd
Current implementaion of docke daemon doesn't pass down the
`--oom-kill-disable` option specified by the end user to the containerd
when spawning a new docker instance with help from `runc` component, which
results in the `--oom-kill-disable` doesn't work no matter the flag is `true`
or `false`.

This PR will fix this issue reported by #36090

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
Upstream-commit: 44b074d199de84b9af8cc94005fbed4f76bd9ab8
Component: engine
2018-02-05 03:25:59 +00:00
9f86cebf80 Migrate some of the nat tests in integration-cli to api tests
This fix migrates nat tests in docker_cli_nat_test.go
to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8fb933a30b7cb2f1726c1d73001266d520cf121d
Component: engine
2018-02-03 20:18:00 +00:00
1dc4d7c54e Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-02-03 17:04:27 +00:00
6a670e72e5 Merge component 'engine' from git@github.com:moby/moby master 2018-02-03 17:04:21 +00:00
1df01c41a2 Merge component 'cli' from git@github.com:docker/cli master 2018-02-03 16:41:09 +00:00
fd2998caea Merge pull request #36119 from cpuguy83/fix_plugin_scanner
Fix issue with plugin scanner going to deep
Upstream-commit: 6e5c2d639f67ae70f54d9f2285f3261440b074aa
Component: engine
2018-02-02 20:19:01 -08:00
51b800faf9 Merge pull request #36193 from dnephin/debug-swagger-gen-failures
Make it easier to debug swagger-gen flakes
Upstream-commit: 39fe5875407bd23a8da25951d7343c66e0cc4482
Component: engine
2018-02-02 19:54:30 -08:00
07e098a3c1 Merge pull request #36137 from fcrisciani/libnetwork-vendoring
Libnetwork revendoring
Upstream-commit: c2b27d5752e5f2b40e4925dd5f23f59313efa581
Component: engine
2018-02-02 21:27:27 -05:00
9640f78dbf Merge pull request #36190 from dnephin/fix-vendor-check
Fix vendor validation
Upstream-commit: a5f15c738a34746b0726d6d33ebab0dcd8d3df02
Component: engine
2018-02-02 16:24:57 -08:00
3443bd57ad Merge pull request #862 from dnephin/fix-vendor-validation
Fix vendor validation (and vendor)
Upstream-commit: 0c80cafe78
Component: cli
2018-02-02 15:34:09 -08:00
39892725fa Migrate usage of newSwarm in integration/service to use integration/utils/swarm.NewSwarm
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 1d40e9289913338eb15de8b8304bcdd329d8e497
Component: engine
2018-02-02 23:28:54 +00:00
b87196602b Re-add Git Commit time to deb dev builds
Dev builds for debian packages previously had system time inserted into
their packaging names while both static and rpm builds instead had the
git commit time.

This commit remedies that by pushing the generation of the debian
package version into a separate script to mirror what is being done in
static and rpm builds.

To give you an idea of what it looks like take the following examples:

```
❯ ./gen-deb-ver ~/work/docker-ce/components/engine/ $(cat ~/work/docker-ce/VERSION)
18.03.0~ce~dev~git20180202.170651.0.e232737
```

```
❯ ./gen-rpm-ver ~/work/docker-ce/components/engine $(cat ~/work/docker-ce/VERSION)
18.03.0.ce 0.0.dev.git20180202.170651.0.e232737 e232737
```

```
❯ ./gen-static-ver ~/work/docker-ce/components/engine/ $(cat ~/work/docker-ce/VERSION)
18.03.0-ce-dev-20180202.170651-e232737
```

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 23e3e42df6cb4e5cafd8648344ad37de25002971
Component: packaging
2018-02-02 23:27:19 +00:00
e73d8c24d7 Libnetwork revendoring
Diff:
5ab4ab8300...20dd462e0a

- Memberlist revendor (fix for deadlock on exit)
- Network diagnostic client
- Fix for ndots configuration

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Upstream-commit: ec86547244fa329148a096db56f9ade77a7ce7eb
Component: engine
2018-02-02 14:36:32 -08:00
041bf84c58 Migrate TestSecretInspect from integration-cli to api tests
This fix migrates TestSecretInspect from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 71c794d9126dc4b4626cf6ab90267a990c8923f6
Component: engine
2018-02-02 22:23:12 +00:00
1fa91ec1e6 Merge pull request #82 from seemethere/static_dev_versions
Static Dev builds should include date and sha
Upstream-commit: 015af2c71e77fb99a9882301828bf8eafe4b95df
Component: packaging
2018-02-02 14:20:31 -08:00
6347d30b6f Fix issue with plugin scanner going to deep
The plugin spec says that plugins can live in one of:

- /var/run/docker/plugins/<name>.sock
- /var/run/docker/plugins/<name>/<name>.sock
- /etc/docker/plugins/<name>.[json,spec]
- /etc/docker/plugins/<name>/<name>.<json,spec>
- /usr/lib/docker/plugins/<name>.<json,spec>
- /usr/lib/docker/plugins/<name>/<name>.<json,spec>

However, the plugin scanner which is used by the volume list API was
doing `filepath.Walk`, which will walk the entire tree for each of the
supported paths.
This means that even v2 plugins in
`/var/run/docker/plugins/<id>/<name>.sock` were being detected as a v1
plugin.
When the v1 plugin loader tried to load such a plugin it would log an
error that it couldn't find it because it doesn't match one of the
supported patterns... e.g. when in a subdir, the subdir name must match
the plugin name for the socket.

There is no behavior change as the error is only on the `Scan()` call,
which is passing names to the plugin registry when someone calls the
volume list API.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: b27f70d45a0fbb744c17dda02f597ffa6a47d4d9
Component: engine
2018-02-02 16:49:14 -05:00
99a67602d2 Merge pull request #36146 from yongtang/36142-TaskState
Add `REMOVE` and `ORPHANED` to TaskState
Upstream-commit: 3a6f8cfd5108aa3fac145525b7cd2f4f0439702d
Component: engine
2018-02-02 11:33:25 -08:00
1ccbec4ecc Make it easier to debug swgger-gen flakes
Sometimes this check fails, but git status doesn't give us enough information
to debug the failure.

Signed-off-by: Daniel Nephin <dnephin@gmail.com>
Upstream-commit: d80f25d079b84d8aa1e3233464c415e3b5d4480a
Component: engine
2018-02-02 11:07:40 -08:00
cb4ddc2058 Fix vendor validation
vendor/ must be removed first, otherwise files added to vendor/ but not vendor.conf
will not cause the validation to fail

Signed-off-by: Daniel Nephin <dnephin@gmail.com>
Upstream-commit: a6dedd1a12
Component: cli
2018-02-02 11:01:05 -08:00
08f32bbeb8 Remove integration-cli/docker_cli_nat_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: deae6a5c087eac564dc348fa1f46f57790ed2c84
Component: engine
2018-02-02 18:59:15 +00:00
9256f1dbc3 Fix vendor validation
Previously adding files to vendor/ without adding to vendor.conf would not fail the
validation.

Also be consistent with indentation and use tabs.

Signed-off-by: Daniel Nephin <dnephin@gmail.com>
Upstream-commit: 075fd7a9bee630f62f0fa0d7a0a26c660ed504ea
Component: engine
2018-02-02 10:49:57 -08:00
efc7d712c1 Fix race in attachable network attachment
Attachable networks are networks created on the cluster which can then
be attached to by non-swarm containers. These networks are lazily
created on the node that wants to attach to that network.

When no container is currently attached to one of these networks on a
node, and then multiple containers which want that network are started
concurrently, this can cause a race condition in the network attachment
where essentially we try to attach the same network to the node twice.

To easily reproduce this issue you must use a multi-node cluster with a
worker node that has lots of CPUs (I used a 36 CPU node).

Repro steps:

1. On manager, `docker network create -d overlay --attachable test`
2. On worker, `docker create --restart=always --network test busybox
top`, many times... 200 is a good number (but not much more due to
subnet size restrictions)
3. Restart the daemon

When the daemon restarts, it will attempt to start all those containers
simultaneously. Note that you could try to do this yourself over the API,
but it's harder to trigger due to the added latency from going over
the API.

The error produced happens when the daemon tries to start the container
upon allocating the network resources:

```
attaching to network failed, make sure your network options are correct and check manager logs: context deadline exceeded
```

What happens here is the worker makes a network attachment request to
the manager. This is an async call which in the happy case would cause a
task to be placed on the node, which the worker is waiting for to get
the network configuration.
In the case of this race, the error ocurrs on the manager like this:

```
task allocation failure" error="failed during network allocation for task n7bwwwbymj2o2h9asqkza8gom: failed to allocate network IP for task n7bwwwbymj2o2h9asqkza8gom network rj4szie2zfauqnpgh4eri1yue: could not find an available IP" module=node node.id=u3489c490fx1df8onlyfo1v6e
```

The task is not created and the worker times out waiting for the task.

---

The mitigation for this is to make sure that only one attachment reuest
is in flight for a given network at a time *when the network doesn't
already exist on the node*. If the network already exists on the node
there is no need for synchronization because the network is already
allocated and on the node so there is no need to request it from the
manager.

This basically comes down to a race with `Find(network) ||
Create(network)` without any sort of syncronization.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: c379d2681ffe8495a888fb1d0f14973fbdbdc969
Component: engine
2018-02-02 13:46:23 -05:00
b9a24cabc1 Merge pull request #36177 from yongtang/02012018-docker_api_resize_test
Migrate several resize tests from integration-cli to integration
Upstream-commit: 81e651c6d2e26df4ed210a5fd87142dcd7a94dd6
Component: engine
2018-02-02 10:27:24 -08:00
e232737f95 Merge component 'engine' from git@github.com:moby/moby master 2018-02-02 17:06:51 +00:00
a4a00c301a Merge component 'cli' from git@github.com:docker/cli master 2018-02-02 16:41:17 +00:00
08694d3da0 Migrate several resize tests from integration-cli to integration
This fix migrates several resize tests from integration-cli to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8f800c941570ffcd087c920c37d3a368a5a19e6d
Component: engine
2018-02-02 15:21:47 +00:00
c41074cd60 Merge pull request #36178 from yongtang/01302018-TestAPIStatsContainerGetMemoryLimit
Migrate TestAPIStatsContainerGetMemoryLimit from integration-cli to api tests
Upstream-commit: fd87db3769f111cdaf4ed09f0f36a254bf46fbbd
Component: engine
2018-02-01 22:01:05 -08:00
fe9238ad21 Migrate TestAPIStatsContainerGetMemoryLimit from integration-cli to api tests
This fix migrates TestAPIStatsContainerGetMemoryLimit from
integration-cli to api test.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: d5cbde514f4887f5655096bce05faa7b91068038
Component: engine
2018-02-01 22:07:06 +00:00
c38d4936f4 Merge pull request #682 from albers/completion-service-options
Fix and simplify bash completion for service env, mounts and labels
Upstream-commit: 26a2a45967
Component: cli
2018-02-01 14:02:51 -08:00
be8b7a4dfb Merge pull request #851 from mistyhacks/overlay-network-limits
Doc guidance to only use 256 IPs per overlay
Upstream-commit: 19e4389a72
Component: cli
2018-02-01 11:11:27 -08:00
62c3cc507d Merge component 'engine' from git@github.com:moby/moby master 2018-02-01 17:06:44 +00:00
6fbbcc8257 Merge component 'cli' from git@github.com:docker/cli master 2018-02-01 16:41:16 +00:00
02e1927cf7 Remove integration-cli/docker_api_resize_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e8d1f35718b3a9869778611b2cb11c2f4407350f
Component: engine
2018-02-01 16:37:01 +00:00
d25b4a3533 Merge pull request #859 from mistyhacks/quotes-around-format-strings
Add quotes around format template
Upstream-commit: 5bf0d76494
Component: cli
2018-01-31 21:40:08 -08:00
20111ede63 Explain the columns shown in docker stats
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 0219338781
Component: cli
2018-01-31 17:05:54 -08:00
2daf468e57 Add quotes around format template
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 0b6aeae007
Component: cli
2018-01-31 16:51:43 -08:00
4e10e192e9 Merge pull request #36160 from kolyshkin/layer-not-retained
daemon.cleanupContainer: nullify container RWLayer upon release
Upstream-commit: 53a58da551e961b3710bbbdfabbc162c3f5f30f6
Component: engine
2018-01-31 15:13:00 -08:00
096bbe0b3e Merge pull request #36166 from yongtang/01312018-TestAPIUpdateContainer
Migrate TestAPIUpdateContainer from integration-cli to api tests
Upstream-commit: 5772c4b8a25dfad869ecd83bb986e2b0d08b7a07
Component: engine
2018-01-31 15:02:00 -08:00
d30180eaf5 Merge pull request #857 from mistyhacks/5759_typo-in-builder
Fix doubled word in note
Upstream-commit: 3aac740478
Component: cli
2018-01-31 14:51:37 -08:00
dc47308ffd Add an example for --with-registry-auth
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 821452629c
Component: cli
2018-01-31 13:38:49 -08:00
0a7bda1a7c Fix doubled word in note
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: a2bb62683d
Component: cli
2018-01-31 13:05:58 -08:00
2fdf0e5bd3 Migrate TestAPIUpdateContainer from integration-cli to api tests
This fix migrates TestAPIUpdateContainer from integration-cli to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 490edd35829a7dd1144da50105fc377d41a52fc0
Component: engine
2018-01-31 20:02:55 +00:00
e0f0ab1bd4 Merge pull request #36150 from yongtang/36139-ContainerStatus
Fix issue of ExitCode and PID not show up in Task.Status.ContainerStatus
Upstream-commit: 231a4408f2d691838e4f821eedb7439c4e1b3f56
Component: engine
2018-01-31 11:59:53 -08:00
6bed3b4c11 Merge pull request #853 from thaJeztah/bump-go-connections
bump docker/go-connections to 98e7d807e5d804e4e42a98d74d1dd695321224ef
Upstream-commit: 3988d9cfd9
Component: cli
2018-01-31 10:22:41 -08:00
275df9bb2d Merge pull request #852 from thaJeztah/bump-version-18.03
Bump VERSION to 18.03.0-dev
Upstream-commit: 4a03f2a4ae
Component: cli
2018-01-31 10:21:54 -08:00
5aed35b37a Merge pull request #36163 from thaJeztah/bump-go-connections
bump docker/go-connections to 98e7d807e5d804e4e42a98d74d1dd695321224ef
Upstream-commit: e1f98e8ab3cb5ae5c0f452cdd81ac4a954279e62
Component: engine
2018-01-31 09:20:10 -08:00
0cabc3863b Merge component 'engine' from git@github.com:moby/moby master 2018-01-31 17:04:47 +00:00
eba76967d1 Merge component 'cli' from git@github.com:docker/cli master 2018-01-31 16:41:13 +00:00
6f8c4ca576 Remove docker_api_update_unix_test.go
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8786b09c81e4eed540924ef415ecdfb5f9affa01
Component: engine
2018-01-31 16:10:34 +00:00
877ec711a0 Fix issue of ExitCode and PID not show up in Task.Status.ContainerStatus
This fix tries to address the issue raised in 36139 where
ExitCode and PID does not show up in Task.Status.ContainerStatus

The issue was caused by `json:",omitempty"` in PID and ExitCode
which interprate 0 as null.

This is confusion as ExitCode 0 does have a meaning.

This fix removes  `json:",omitempty"` in ExitCode and PID,
but changes ContainerStatus to pointer so that ContainerStatus
does not show up at all if no content. If ContainerStatus
does have a content, then ExitCode and PID will show up (even if
they are 0).

This fix fixes 36139.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9247e09944a4c7f3c2f3f20f180c047a19fb6bae
Component: engine
2018-01-31 15:35:19 +00:00
e5e113b93d bump docker/go-connections to 98e7d807e5d804e4e42a98d74d1dd695321224ef
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: b7a9f027f3
Component: cli
2018-01-31 01:38:06 -08:00
aef7840d1c Bump VERSION to 18.03.0-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: beb0d08e48
Component: cli
2018-01-31 01:34:51 -08:00
6744cda526 bump docker/go-connections to 98e7d807e5d804e4e42a98d74d1dd695321224ef
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a6d35a822eed940260c74e2e7eea6455953ffabe
Component: engine
2018-01-31 01:30:56 -08:00
a0d42db1d4 Merge pull request #36156 from r2d4/move-shell-parser
Move dockerfile ENV shell parser functions into subpackage
Upstream-commit: 421664aba1753b4f9475d6f42b8d18f65950d5ab
Component: engine
2018-01-31 14:48:01 +09:00
d59bd66e1b daemon.cleanupContainer: nullify container RWLayer upon release
ReleaseRWLayer can and should only be called once (unless it returns
an error), but might be called twice in case of a failure from
`system.EnsureRemoveAll(container.Root)`. This results in the
following error:

> Error response from daemon: driver "XXX" failed to remove root filesystem for YYY: layer not retained

The obvious fix is to set container.RWLayer to nil as soon as
ReleaseRWLayer() succeeds.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: e9b9e4ace294230c6b8eb010eda564a2541c4564
Component: engine
2018-01-30 18:50:59 -08:00
3ea1f0df2c Move builder shell parser into subpackage
Moves builder/shell_parser and into its own subpackage at builder/shell since it
has no dependencies other than the standard library. This will make it
much easier to vendor for downstream libraries, without pulling all the
dependencies of builder/.

Fixes #36154

Signed-off-by: Matt Rickard <mrick@google.com>
Upstream-commit: a634526d14639c6b98c509a069ef29e2b69c0ef0
Component: engine
2018-01-30 17:54:39 -08:00
198448e674 Doc guidance to only use 256 IPs per overlay
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 6085b5d3aa
Component: cli
2018-01-30 15:41:53 -08:00
2cc4e9e5e9 Add e2e container kill test
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 42edad2fc7
Component: cli
2018-01-30 15:38:45 -08:00
090ffb4eb7 Merge pull request #36125 from thaJeztah/fix-plural-singular-node-generic-resources
Fix "--node-generic-resource" singular/plural
Upstream-commit: a80cd04eb5375f0eb7b648e820f694b45983cf2b
Component: engine
2018-01-30 14:38:50 -08:00
7de8b77c33 Merge pull request #848 from mistyhacks/fix-publish-table
Fix the network option table
Upstream-commit: bb9e5ab767
Component: cli
2018-01-30 14:32:32 -08:00
d0e1c8724c Fix the network option table
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: 773ccdec7b
Component: cli
2018-01-30 14:00:48 -08:00
30a8f2b39f Merge pull request #849 from mistyhacks/add-filter-label-example
Add examples of prune by label
Upstream-commit: 0aabbb09b6
Component: cli
2018-01-30 13:52:34 -08:00
835d51fadd Merge pull request #36148 from yongtang/01302018-TestLinksEtcHostsContentMatch
Migrate some integration-cli test to api tests
Upstream-commit: 5e7a245c3f63a29fb0eb96d8897238b9dd3cfc47
Component: engine
2018-01-30 13:38:15 -08:00
3c2369ae51 Merge pull request #36152 from yongtang/01302018-TestAuthAPI
Migrate TestAuthAPI from integration-cli to integration
Upstream-commit: 11ccbeb5c5ceeeaf6a57b766efe7e4701a740f56
Component: engine
2018-01-30 13:37:56 -08:00
b0db1afb21 Add examples of prune by label
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: bc28bf13f7
Component: cli
2018-01-30 11:29:45 -08:00
bbb554bc58 Migrate TestAuthAPI from integration-cli to integration
This fix migrates TestAuthAPI from integration-cli to integration

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: d9247557898d1d15a7349ecb0044b73d4a5a41a9
Component: engine
2018-01-30 19:15:06 +00:00
6d89c35e6e Migrate some integration-cli test to api tests
This fix migrate  TestLinksEtcHostsContentMatch
to api test.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e6bd20edcbf3b7a6f87a356ab0943714936c70e1
Component: engine
2018-01-30 18:52:48 +00:00
6c2db26f29 Merge component 'engine' from git@github.com:moby/moby master 2018-01-30 17:05:43 +00:00
fe18510901 Add REMOVE and ORPHANED to TaskState
This fix tries to address the issue raised in 36142 where
there are discrepancies between Swarm API and swagger.yaml.

This fix adds two recently added state `REMOVE` and `ORPHANED` to TaskState.

This fix fixes 36142.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: a40687f5ac7df27bc6c6c3a6f69513a397a1a05a
Component: engine
2018-01-30 16:46:05 +00:00
c1528c1357 Merge component 'cli' from git@github.com:docker/cli master 2018-01-30 16:41:38 +00:00
f0d03ada35 Merge pull request #35946 from joelwurtz/patch-2
Fix Volumes property definition in ContainerConfig
Upstream-commit: 40a9d5d24cda0d938f3c41dceef41b97b6b4e847
Component: engine
2018-01-29 20:57:09 -08:00
8c6b3bb86c Merge pull request #36141 from yongtang/01292018-stop_test
Migrate docker_cli_stop_test.go to api test
Upstream-commit: d98cdc490cca30b4928ad82668485111f9b800df
Component: engine
2018-01-29 19:31:01 -08:00
db1ce9af6b Merge pull request #838 from vdemeester/fix-label-file-behavior
Fix `--label-file` weird behavior
Upstream-commit: 9de1b162fa
Component: cli
2018-01-29 17:32:21 -08:00
4d611b9990 Add support for multiple composefile when deploying
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 1872bd802c
Component: cli
2018-01-29 17:27:25 -08:00
12f9c4b018 Migrate docker_cli_stop_test.go to api test
This fix migrate docker_cli_stop_test.go to api test

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 4f378124ff649b844de88c93f6ca70e6b3f5d7d7
Component: engine
2018-01-30 00:55:18 +00:00
f6b5291c4c Merge pull request #844 from tophj-ibm/bump-to-go-1-9-3
Bump Go to 1.9.3 (cont.)
Upstream-commit: 7da324a2f6
Component: cli
2018-01-29 16:17:28 -05:00
98a8916ad3 Merge pull request #36124 from crosbymichael/exec
Use proc/exe for reexec
Upstream-commit: 9d61e5c8c1d85f633643a8b9071393dc417d56dd
Component: engine
2018-01-29 11:41:08 -08:00
aea7a7fc73 Fix --label-file weird behavior
`--label-file` has the exact same behavior as `--env-file`, meaning any
placeholder (i.e. a simple key, no `=` sign, no value), it will get the
value from the environment variable.

For `--label-file` it should just add an empty label.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 2b17f4c8a8
Component: cli
2018-01-29 11:08:54 -08:00
27ced4316d Merge pull request #36131 from yongtang/01282018-swarmkit
Update swarmkit to 68a376dc30d8c4001767c39456b990dbd821371b
Upstream-commit: 9c5686fbd04cced838c601a4bf9583bd4b8b9700
Component: engine
2018-01-29 11:07:13 -08:00
33c438d7c6 Bump Go to 1.9.3
Signed-off-by: Christopher Jones <tophj@linux.vnet.ibm.com>
Upstream-commit: d89f5fa731
Component: cli
2018-01-29 13:43:59 -05:00
9bff0e7832 Merge pull request #36130 from yongtang/36042-secret-config-mode
Fix secret and config mode issue
Upstream-commit: d093aa0ec365e1ffd4db8a513c5b341b9a0d012e
Component: engine
2018-01-29 10:37:24 -08:00
6c313c03fe Merge pull request #36114 from Microsoft/jjh/fixdeadlock-lcowdriver-hotremove
LCOW: Graphdriver fix deadlock in hotRemoveVHDs
Upstream-commit: 03a1df95369ddead968e48697038904c84578d00
Component: engine
2018-01-29 09:57:43 -08:00
691eb859f4 Merge component 'engine' from git@github.com:moby/moby master 2018-01-29 17:04:44 +00:00
13e5898067 Merge pull request #34369 from cyphar/build-buildmode-pie
*: switch to -buildmode=pie
Upstream-commit: cd3c0057ac28b5601196424597d7fed226948386
Component: engine
2018-01-29 23:54:03 +09:00
a94b27c618 Merge pull request #36132 from yongtang/01282018-typo
Fix a typo in CONTRIBUTING.md
Upstream-commit: 4219df22fc138bc9d180ef81ab2838bb85d96ace
Component: engine
2018-01-28 12:21:46 -08:00
a1a0300f4c Merge component 'engine' from git@github.com:moby/moby master 2018-01-28 17:04:35 +00:00
b13e2a39e1 Add test cases for file mode with secret and config.
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 65ee7fff02111bf696bc2fec442d07c2957f4151
Component: engine
2018-01-28 16:48:10 +00:00
eac1cd59fb Merge component 'cli' from git@github.com:docker/cli master 2018-01-28 16:41:09 +00:00
7b9944fc04 Merge pull request #36074 from shutefan/master
Update API docs to show that /containers/{id}/kill returns HTTP 409
Upstream-commit: 958200970f4c52fd093aa913632d2d2b79ebf969
Component: engine
2018-01-28 08:32:35 -08:00
82bc59e5d6 Fix secret and config mode issue
This fix tries to address the issue raised in 36042
where secret and config are not configured with the
specified file mode.

This fix update the file mode so that it is not impacted
with umask.

Additional tests have been added.

This fix fixes 36042.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 3305221eefd18ba7712a308c1fb05d4eeeac2cc6
Component: engine
2018-01-28 16:21:41 +00:00
9d28e686ee Update swarmkit to 68a376dc30d8c4001767c39456b990dbd821371b
This fix updates swarmkit to 68a376dc30d8c4001767c39456b990dbd821371b:
```
-github.com/docker/swarmkit 713d79dc8799b33465c58ed120b870c52eb5eb4f
+github.com/docker/swarmkit 68a376dc30d8c4001767c39456b990dbd821371b
```

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: b9923d853076c4ce884246dc3e17955dcf851f16
Component: engine
2018-01-28 16:20:17 +00:00
9a7da567a7 Fix a typo in CONTRIBUTING.md
`seperate` -> `separate`

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: cce360c7b0136f91fdce6e15ec7fb83eb14153f2
Component: engine
2018-01-28 16:19:51 +00:00
b24e274bbe Merge pull request #36099 from thaJeztah/bump-libnetwork3
bump libnetwork to 5ab4ab830062fe8a30a44b75b0bda6b1f4f166a4
Upstream-commit: 9368e9dac3e7202d2b15a83427010db7b062033a
Component: engine
2018-01-27 21:47:29 -08:00
5e3cb1566c Merge pull request #34992 from allencloud/simplify-shutdowntimeout
simplify codes on calculating shutdown timeout
Upstream-commit: c9f1807abbc60236f5552f8dd25e6d484584f037
Component: engine
2018-01-27 18:26:54 -08:00
8f3ae07b6b Merge pull request #717 from albers/completion-images-2
Improve and fix bash completion for images
Upstream-commit: 4586609f71
Component: cli
2018-01-27 17:48:49 -08:00
8d2c67f10d Merge pull request #36095 from yongtang/36083-network-inspect-created-time
Fix issue where network inspect does not show Created time for networks in swarm scope
Upstream-commit: 924fb0e843930ca444e0f3a6632d7cb67a3da479
Component: engine
2018-01-26 17:18:30 -08:00
3d79cf83bd Merge pull request #35911 from ASMfreaK/Russian-Scientsists-addition-to-names-generator
Add more russian scientists in names-generator.go
Upstream-commit: c41c80026b1469d398edee0167ef33653ff82e93
Component: engine
2018-01-26 15:48:58 -08:00
7c5df03153 Fix "--node-generic-resource" singular/plural
Daemon flags that can be specified multiple times use
singlar names for flags, but plural names for the configuration
file.

To make the daemon configuration know how to correlate
the flag with the corresponding configuration option,
`opt.NewNamedListOptsRef()` should be used instead of
`opt.NewListOptsRef()`.

Commit 6702ac590e6148cb3f606388dde93a011cb14931 attempted
to fix the daemon not corresponding the flag with the configuration
file option, but did so by changing the name of the flag
to plural.

This patch reverts that change, and uses `opt.NewNamedListOptsRef()`
instead.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6e7715d65ba892a47d355e16bf9ad87fb537a2d0
Component: engine
2018-01-26 13:53:13 -08:00
37f71b34b7 Merge pull request #804 from thaJeztah/more-annotations
Annotate "stack" commands to be "swarm" and "kubernetes"
Upstream-commit: a46fa0759d
Component: cli
2018-01-26 15:12:09 -05:00
dce32bffba Use proc/exe for reexec
You don't need to resolve the symlink for the exec as long as the
process is to keep running during execution.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 59ec65cd8cec942cee6cbf2b8327ec57eb5078f0
Component: engine
2018-01-26 14:13:43 -05:00
db2a10168c Merge pull request #36047 from cpuguy83/graphdriver_improvements
Do not make graphdriver homes private mounts.
Upstream-commit: 2c05aefc99d33edde47b08e38978b6c2f4178648
Component: engine
2018-01-26 13:54:30 -05:00
5338e07ad9 Merge pull request #829 from thaJeztah/bump-moby
Bump moby and dependencies
Upstream-commit: 44e93ddd13
Component: cli
2018-01-26 10:42:14 -08:00
4e8a0d189e Simplify codes on calculating shutdown timeout
Signed-off-by: Allen Sun <shlallen1990@gmail.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: de68ac8393d32d2c2028dd11c5816430ad0d8d8b
Component: engine
2018-01-26 09:18:07 -08:00
62e8f8e9af Merge component 'engine' from git@github.com:moby/moby master 2018-01-26 17:03:45 +00:00
a002f8068e LCOW: Graphdriver fix deadlock
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: a44fcd3d27c06aaa60d8d1cbce169f0d982e74b1
Component: engine
2018-01-26 08:57:52 -08:00
b4eb2e9242 Merge pull request #34372 from cpuguy83/more_error_handling_for_pluginrm
Ignore exist/not-exist errors on plugin remove
Upstream-commit: 6d4d3c52ae7c3f910bfc7552a2a673a8338e5b9f
Component: engine
2018-01-25 20:45:17 -08:00
ffe64d412a Merge pull request #36108 from Microsoft/jjh/opengcsv0.3.6
Revendor Microsoft/opengcs @ v0.3.6
Upstream-commit: 3e416acf1d9e295b9d75dc222b7897ecfd22d26e
Component: engine
2018-01-25 16:42:35 -08:00
c49971b835 Merge pull request #36052 from Microsoft/jjh/no-overlay-off-only-one-disk
LCOW: Regular mount if only one layer
Upstream-commit: a8d0e36d0329063af9205b4848d1f5c09bd4c3be
Component: engine
2018-01-25 15:46:16 -08:00
b78f97f4d9 Merge pull request #36116 from yongtang/34655-follow-up
Update API version history for `Init` with `POST /containers/create`
Upstream-commit: 4b9b8d6278b594c26f396044a964a1dd1b32f0f7
Component: engine
2018-01-25 15:36:20 -08:00
96ed38b227 Merge pull request #35979 from emil2k/fix-container-copy-err
Wrap response errors for container copy methods.
Upstream-commit: 1d1845de5464d7ba8e7b735b0d221b1232851ab2
Component: engine
2018-01-25 13:48:49 -08:00
66b09830df Merge pull request #36105 from yongtang/01242018-golint
Golint fix with ro_layer.go
Upstream-commit: 7db39720b27e2028af88b8e692aa056ec0d273eb
Component: engine
2018-01-25 13:22:51 -08:00
2abfa99b63 Update API version history for Init with POST /containers/create
This is a follow up to
https://github.com/moby/moby/pull/34655#pullrequestreview-91096779

to update API version history for `Init` field.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 376658e41485c43de53391000ad52d1281f9c464
Component: engine
2018-01-25 19:05:22 +00:00
39f9f3f6e3 Merge pull request #34655 from nmeyerhans/document-init-api
Add Init API field documentation to swagger
Upstream-commit: 093a5402a041e9648d03d3e6545fa255e8fe96b2
Component: engine
2018-01-25 10:16:27 -08:00
aab82bfc9c Ignore exist/not-exist errors on plugin remove
During a plugin remove, docker performs an `os.Rename` to move the
plugin data dir to a new location before removing to acheive an atomic
removal.

`os.Rename` can return either a `NotExist` error if the source path
doesn't exist, or an `Exist` error if the target path already exists.
Both these cases can happen when there is an error on the final
`os.Remove` call, which is common on older kernels (`device or resource
busy`).

When calling rename, we can safely ignore these error types and proceed
to try and remove the plugin.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 93027b1ff2475b66b6321b5722009fad4def8187
Component: engine
2018-01-25 09:23:54 -08:00
ecf18b66ed Merge component 'engine' from git@github.com:moby/moby master 2018-01-25 17:06:29 +00:00
680f21a8d2 Merge component 'cli' from git@github.com:docker/cli master 2018-01-25 16:43:34 +00:00
32830b59ac Merge pull request #36100 from thaJeztah/update-authors
Update authors
Upstream-commit: a2445fee0cec27cb350c3b80169ec33716a1388e
Component: engine
2018-01-24 20:35:51 -08:00
4772ea5aec Revendor Microsoft/opengcs @ v0.3.6
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: ace588284dc17fc9c92c30e1697558d0b2cc1262
Component: engine
2018-01-24 16:09:58 -08:00
0a23b8e672 Merge pull request #35989 from dani-docker/orca-11380
verbose info is missing for partial overlay ID
Upstream-commit: 2b2265acbb7b1457cd6657a5e4e5503472b306d1
Component: engine
2018-01-24 16:01:31 -08:00
0532f832be Merge pull request #827 from thaJeztah/bump-go-1.9.3
Bump Go to 1.9.3
Upstream-commit: 819df0ebf6
Component: cli
2018-01-24 17:34:05 -05:00
077b817634 Bump Go to 1.9.3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: ffc7648322
Component: cli
2018-01-24 14:25:13 -08:00
e7e06ee745 Merge pull request #34379 from cpuguy83/mount_optimizations
Optimizations for recursive unmount
Upstream-commit: 59e86068e6b2c23f083bd30b9987fea3fe90ba18
Component: engine
2018-01-24 14:00:58 -08:00
1956fc58bd Merge pull request #36096 from cpuguy83/use_rshared_prop_for_daemon_root
Set daemon root to use shared propagation
Upstream-commit: 3ca99ac2f4a7196097d8f5d037ac10ebbcbb5c3c
Component: engine
2018-01-24 12:24:33 -08:00
f813e83349 Merge pull request #36078 from mixja/multiline-max-event-processing
awslogs - don't add new lines to maximum sized events
Upstream-commit: a636ed5ff473d69e9d0cda352fef0823518f016a
Component: engine
2018-01-24 12:06:49 -08:00
61c1474fc0 Merge pull request #35938 from yongtang/35931-filter-before-since
Fix `before` and `since` filter for `docker ps`
Upstream-commit: 25e56670cf7cd69e60c0d58ed25c33dbb21d3d8e
Component: engine
2018-01-24 12:06:19 -08:00
a0a9bd7e22 Merge pull request #36077 from yongtang/35752-verifyNetworking
Verify NetworkingConfig to make sure EndpointSettings is not nil
Upstream-commit: 914ce4fde798b41144ac931619f39a2c96eab261
Component: engine
2018-01-24 12:05:58 -08:00
13bb02e502 Merge pull request #398 from seemethere/bump_ver_18_03_dev
[master] bump version to 18.03.0-ce-dev
2018-01-24 11:39:43 -08:00
8f89082c26 bump version to 18.03.0-ce-dev
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-01-24 19:37:16 +00:00
0093346692 Merge pull request #831 from silvin-lubecki/fix-kubernetes-flags
Fix broken Kubernetes stack flags
Upstream-commit: f9039fe291
Component: cli
2018-01-24 10:45:45 -08:00
ef4aa7ebe5 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-01-24 18:36:44 +00:00
0851fa60de Merge component 'engine' from git@github.com:moby/moby master 2018-01-24 18:36:38 +00:00
4de8cf5f5e Golint fix with ro_layer.go
A small golint fix with ro_layer.go.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 19918b88b7b9fe6fc668847f31c94068c78ef2d1
Component: engine
2018-01-24 18:24:03 +00:00
a42cb7a60a Add Init API field documentation to swagger
Signed-off-by: Noah Meyerhans <nmeyerha@amazon.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 467ea71e5e2a0142c1456e3280d69a9538402fec
Component: engine
2018-01-24 09:46:12 -08:00
896e79bd00 bump libnetwork to 5ab4ab830062fe8a30a44b75b0bda6b1f4f166a4
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: e37374c0673bf56890e33afed112ad9e3a682203
Component: engine
2018-01-24 09:20:18 -08:00
4c8a9a1b98 Using Flags instead of PersistentFlags, as Kubernetes flags seem not to be defined in the "persistent space".
Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
Upstream-commit: 14fcadffb1
Component: cli
2018-01-24 09:17:08 -08:00
60e5b2e6f7 Merge pull request #36004 from cpuguy83/update_libnetwork
Update libnetwork commit
Upstream-commit: f909bf35906ae97c4729ced3e20645df1cc79166
Component: engine
2018-01-24 08:56:27 -08:00
4d4d834cb8 Merge pull request #83 from thaJeztah/bump-go-1.9.3
Update to go 1.9.3
Upstream-commit: 7ea33ac7993e2abfd2404e147d95a3b41a29ccbe
Component: packaging
2018-01-24 08:12:29 -08:00
62d42837f0 bump swarmkit to 713d79dc8799b33465c58ed120b870c52eb5eb4f
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a6a51aadcb
Component: cli
2018-01-24 02:13:53 -08:00
6e37587f1a Update runc and image-spec
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 8707bde082
Component: cli
2018-01-24 02:10:17 -08:00
dda53861be Bump go-winio to 0.4.6
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 2bf989e129
Component: cli
2018-01-24 02:04:09 -08:00
b5099bad79 Bump moby/moby to e11bf870a3170a1d2b1e177a0d7ccc66200bd643
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a3be7a6720
Component: cli
2018-01-24 02:01:24 -08:00
30c21da626 Update authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 5db971324794b5de65447919dfe5f456d0730199
Component: engine
2018-01-24 00:55:47 -08:00
6fc26d75dd Update to go 1.9.3
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 0e676c4bde1d429d21ea083a8bc9f40c0fc51269
Component: packaging
2018-01-24 00:20:18 -08:00
65d771b644 Merge pull request #36087 from thaJeztah/bump-go-1.9.3
Bump Go to 1.9.3
Upstream-commit: e11bf870a3170a1d2b1e177a0d7ccc66200bd643
Component: engine
2018-01-23 20:09:33 -05:00
f7ee7db603 Static Dev builds should include date and sha
Adds git date plus git commit sha to static builds if the version being
built for is a development version

Output is similar to: `docker-18.02.0-ce-dev-20180120.170357-fa4fb35.tgz`

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 8a86c3a6a54760b19cd67854bf68e408bd2a17fb
Component: packaging
2018-01-24 00:31:50 +00:00
3fe329a3ed Merge pull request #78 from kolyshkin/tasks-max
Uncomment TasksMax=unlimited for recent distros
Upstream-commit: 33325c8a2598c94bc5136a9fe7213e3ebe152dd7
Component: packaging
2018-01-23 16:05:04 -08:00
f46043cd6e Merge pull request #36056 from Microsoft/jjh/opengcsv0.3.5
Revendor Microsoft/opengcs @ v0.3.5
Upstream-commit: e60b68ad21ea47d02a125e7ab5a917331de22ea7
Component: engine
2018-01-23 18:12:02 -05:00
bb193d7289 Merge pull request #36097 from crosbymichael/runc-hang
Update runc to fix hang during start and exec
Upstream-commit: 1b9d1e80eb62e8e9b4bfc1588432314acb523bfc
Component: engine
2018-01-23 18:08:31 -05:00
91c8e6e25b Merge pull request #35966 from yongtang/33661-network-alias
Fix network alias issue with `network connect`
Upstream-commit: 70a0621f2558061b93ad24f04e9491bb5e0b8fdc
Component: engine
2018-01-23 14:56:28 -08:00
b1dfd77fa4 Set daemon root to use shared propagation
This change sets an explicit mount propagation for the daemon root.
This is useful for people who need to bind mount the docker daemon root
into a container.

Since bind mounting the daemon root should only ever happen with at
least `rlsave` propagation (to prevent the container from holding
references to mounts making it impossible for the daemon to clean up its
resources), we should make sure the user is actually able to this.

Most modern systems have shared root (`/`) propagation by default
already, however there are some cases where this may not be so
(e.g. potentially docker-in-docker scenarios, but also other cases).
So this just gives the daemon a little more control here and provides
a more uniform experience across different systems.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: a510192b86e7eb1e1112f3f625d80687fdec6578
Component: engine
2018-01-23 14:17:08 -08:00
4798645bfb Update runc to fix hang during start and exec
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: d10091c86e75fb78eaba96f433dc2cc06c0a54de
Component: engine
2018-01-23 15:02:31 -05:00
800ee6ea8f Merge pull request #36076 from yongtang/01202018-aws-vendor
Update aws-sdk-go and go-ini
Upstream-commit: 2cd52d074aba841d399bb98ee3a0880808ef4ef4
Component: engine
2018-01-23 11:37:55 -08:00
8dd7e2516b Fix issue where network inspect does not show Created time in swarm scope
This fix tries to address the issue raised in 36083 where
`network inspect` does not show Created time if the network is
created in swarm scope.

The issue was that Created was not converted from swarm api.
This fix addresses the issue.

An unit test has been added.

This fix fixes 36083.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 090c439fb8a863731cc80fcb9932ce5958d8166d
Component: engine
2018-01-23 18:26:51 +00:00
ae55d43f2e Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-01-23 17:04:13 +00:00
6c6e8038c9 Merge component 'engine' from git@github.com:moby/moby master 2018-01-23 17:04:07 +00:00
ad2946faa1 Merge component 'cli' from git@github.com:docker/cli master 2018-01-23 16:41:06 +00:00
1530820600 deb/common/rules: fix uncommenting TasksMax
Since systemd version 228, a new setting, `TasksMax`, has appeared,
which limits the number of tasks used by a service (via pids cgroup
controller). Unfortunately, a default for this setting, `DefaultTaskMax`,
is set to 512. In systemd version 231 it is changed to 15% which
practically is 4195, as the value from /proc/sys/kernel/pid_max is
treated like 100%).

Either 512 or 4195 is severily limited value for Docker Engine,
as it can run thousands of containers with thousands of tasks in each,
and the number of tasks limit should be set on a per-container basis
by the Docker user. So, the most reasonable setting for `TasksMax`
is `unlimited`.

Unfortunately, older versions of systemd warn about unknown `TasksMax`
parameter in `docker.service` file, and the warning is rather annoying,
therefore this setting is commented out by default, and is supposed
to be uncommented by the user.

The problem with that is, once the limit is hit, all sorts of bad things
happen and it's not really clear even to an advanced user that this
setting is the source of issues.

Now, `rules` file already contain a hack to check for the systemd
version (during build time) and in case the version is greater than 227,
uncomment the `TasksMax=unlimited` line. Alas, it does not work
during normal builds, the reason being systemd is not installed
into build environments.

An obvious fix would be to add systemd to the list of installed
packages in all Dockerfiles used to build debs. Fortunately,
there is a simpler way, as libsystemd-dev is installed, and
it's a subpackage of systemd built from the same source and
carrying the same version, so it can also be checked.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: d80738e4b4459816c64757a2a63e5d8058d0ccf4
Component: packaging
2018-01-22 21:31:09 -08:00
02b6af2e96 rpm/fedora-2x/spec: enable TasksMax in service file
Since systemd version 228, a new setting, `TasksMax`, has appeared, which
limits the number of tasks used by a service (via pids cgroup
controller). Unfortunately, a default for this setting, `DefaultTaskMax`,
is set to 512. In systemd version 231 it is changed to 15% which
practically is 4195, as the value from /proc/sys/kernel/pid_max is
treated like 100%).

Either 512 or 4195 is severily limited value for Docker Engine, as it
can run thousands of containers with thousands of tasks in each, and
the number of tasks limit should be set on a per-container basis by the
Docker user. So, the most reasonable setting for `TasksMax` is `unlimited`.

Unfortunately, older versions of systemd warn about unknown `TasksMax`
parameter in `docker.service` file, and the warning is rather annoying,
therefore this setting is commented out by default, and is supposed to
be uncommented by the user.

The problem with that is, once the limit is hit, all sorts of bad things
happen and it's not really clear even to an advanced user that this
setting is the source of issues.

As Fedora 25 ships systemd 231, it (and later Fedora releases) support
TasksMax, so it makes total sense to uncomment the setting, this is what
this commit does.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 9055832bb0725f05d518c3ebc9b7cc93a69420c7
Component: packaging
2018-01-22 21:31:09 -08:00
544ec9eef9 Merge pull request #36019 from thaJeztah/improve-config-reload
improve daemon config reload; log active configuration
Upstream-commit: 99cfb5f31ad82238573de3475bf5bb0435ac1ebc
Component: engine
2018-01-22 17:58:25 -08:00
d67508be5d Merge pull request #77 from sargun/master
Add pigz to recommended packages
Upstream-commit: a6543ceeff408dfa9cbb4e75d013bc05bda09c32
Component: packaging
2018-01-22 17:35:51 -08:00
dbb0b294c6 Merge pull request #81 from seemethere/add_dev_rpm
Add dev portion to RPM package version
Upstream-commit: 208ba254d788a0d7bfe4dde92b35b9f2f68aa1d6
Component: packaging
2018-01-22 17:35:16 -08:00
bb0dcf69f8 Add integration test for network connect with alias
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 50af4968911483b5a4e09c45a22f8e9153d81696
Component: engine
2018-01-23 01:04:39 +00:00
74da78f854 Fix network alias issue
This fix tries to address the issue raised in 33661 where
network alias does not work when connect to a network the second time.

This fix address the issue.

This fix fixes 33661.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: d63a5a1ff593f14957f3e0a9678633e8237defc9
Component: engine
2018-01-23 01:04:33 +00:00
9b8e792488 added check for empty source in bind mount
Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>

fixed error by removing punctuation

Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>

removed period

Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>

backtick string to escape double quotes in error messages

Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>

simplified test for bind no source error message

Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>
Upstream-commit: e76d8c9eae
Component: cli
2018-01-22 18:33:58 -06:00
2b99ce1d23 Merge pull request #816 from dnephin/binary-native
Add dockerfile for building on non-amd64 platforms
Upstream-commit: b6a628c295
Component: cli
2018-01-22 16:14:23 -08:00
9e00f0f8fa fix verbose for partial overlay ID
Signed-off-by: Dani Louca <dani.louca@docker.com>
Upstream-commit: 2e0990f1655d151b741e7f7f78ac55e14398339f
Component: engine
2018-01-22 18:50:49 -05:00
fe9a519a3b Annotate "stack" commands to be "swarm" and "kubernetes"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 93c36eb228
Component: cli
2018-01-22 15:44:47 -08:00
8c17001e4f Merge pull request #826 from dnephin/fix-lint-errors
Fix lint on master
Upstream-commit: f2529443a0
Component: cli
2018-01-22 15:16:38 -08:00
5cec7a6e2f Add dev portion to RPM package version
-dev was being removed, per legacy code, but we'd like to add it back
into the naming so that deb / rpm packages will look mostly the same
when compiled with a `-dev` version.

RPMS end up looking like:

docker-ce-18.02.0.ce-0.0.dev.git20180120.170357.0.fa4fb35.el7.centos.x86_64.rpm

Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 65e2c3cf9ff8c3130e628a455e3d02921876cdfc
Component: packaging
2018-01-22 23:10:48 +00:00
bc95dc9fb3 Fix merge conflict
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: ae03b006a6
Component: cli
2018-01-22 18:09:47 -05:00
50c6561a9e Merge pull request #35949 from yongtang/34248-carry
Carry #34248 Added tag log option to json-logger and use RawAttrs
Upstream-commit: ea74dbe907f534ba2f59c1173330987c3fa84208
Component: engine
2018-01-22 15:02:54 -08:00
928478219f Merge pull request #36013 from thaJeztah/improve-version-middleware-test
Improve API version-middleware test
Upstream-commit: fbed4eb8c72f56437f2a451f9cd9405814882e2a
Component: engine
2018-01-22 14:59:06 -08:00
e3d68b9fea Merge pull request #780 from thaJeztah/fix-network-add
Fix --network-add adding duplicate networks
Upstream-commit: fbb9de2cfc
Component: cli
2018-01-22 14:45:58 -08:00
e9f8cfe726 Bump Go to 1.9.3
release notes: https://golang.org/doc/devel/release.html#go1.9.minor

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 3cc13511f0c8d7f3aeb382f0444e37592a8b5e69
Component: engine
2018-01-22 13:40:19 -08:00
739f4e49fc Merge pull request #79 from seemethere/remove_f25_aarch64
Removes fedora 25 aarch64 Dockerfile
Upstream-commit: 44a1f4887d9ac3b6cbb08ab779c9e84109b906ba
Component: packaging
2018-01-22 12:15:43 -08:00
40f1f3c105 Removes fedora 25 aarch64 Dockerfile
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: 9f717788b588a48d494abe42d7c392bf8fe458d9
Component: packaging
2018-01-22 19:10:56 +00:00
a53f2c40a3 Verify NetworkingConfig to make sure EndpointSettings is not nil
This fix tries to address the issue raised in 35752
where container start will trigger a crash if EndpointSettings is nil.

This fix adds the validation to make sure EndpointSettings != nil

This fix fixes 35752.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 8d2f4cb24129d87674a13319ca48ce8636ee527a
Component: engine
2018-01-22 16:31:10 +00:00
362cc9aedc Don't append new line for maximum sized events
Signed-off-by: Justin Menga <justin.menga@gmail.com>
Upstream-commit: d3e2d55a3d84d41c331151c9633211f0fb6a3096
Component: engine
2018-01-21 14:29:55 +13:00
36e0e57cbe Log active configuration when reloading
When succesfully reloading the daemon configuration, print a message
in the logs with the active configuration:

    INFO[2018-01-15T15:36:20.901688317Z] Got signal to reload configuration, reloading from: /etc/docker/daemon.json
    INFO[2018-01-14T02:23:48.782769942Z] Reloaded configuration: {"mtu":1500,"pidfile":"/var/run/docker.pid","data-root":"/var/lib/docker","exec-root":"/var/run/docker","group":"docker","deprecated-key-path":"/etc/docker/key.json","max-concurrent-downloads":3,"max-concurrent-uploads":5,"shutdown-timeout":15,"debug":true,"hosts":["unix:///var/run/docker.sock"],"log-level":"info","swarm-default-advertise-addr":"","metrics-addr":"","log-driver":"json-file","ip":"0.0.0.0","icc":true,"iptables":true,"ip-forward":true,"ip-masq":true,"userland-proxy":true,"disable-legacy-registry":true,"experimental":false,"network-control-plane-mtu":1500,"runtimes":{"runc":{"path":"docker-runc"}},"default-runtime":"runc","oom-score-adjust":-500,"default-shm-size":67108864,"default-ipc-mode":"shareable"}

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 8378dcf46d017c70df97d6f851e0196b113b422e
Component: engine
2018-01-21 00:56:02 +01:00
c2b247fce6 Move reload-related functions to reload.go
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6121a8429b9d3a6d20e900c521c2f50fff5db406
Component: engine
2018-01-21 00:55:49 +01:00
d093175f6e Merge pull request #696 from mlaventure/attach-use-containerwait
attach: Use ContainerWait instead of Inspect
Upstream-commit: 44a1168ae5
Component: cli
2018-01-20 23:55:16 +01:00
8adbcf25d6 Update aws-sdk-go and go-ini
This fix updates aws-sdk-go and go-ini to recent versions.
The aws-sdk-go used to be `v1.4.22` which was more than a
year old, and go-ini used to be pre-1.0 release.

This fix updates aws-sdk-go to v1.12.66 and go-ini to v1.25.4:
```
github.com/aws/aws-sdk-go v1.12.66
github.com/go-ini/ini v1.25.4
```

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 79bedc4f46e7fe5870f7d53f27f05d05d0821697
Component: engine
2018-01-20 19:58:25 +00:00
c9b8ded195 Merge pull request #35919 from yongtang/35333-carry
Carry #35333: Devicemapper: ignore Nodata errors when delete thin device
Upstream-commit: db5c006bc8654ab1e4c24a1a9f460bbe4039686e
Component: engine
2018-01-20 18:47:16 +01:00
fa4fb352fe Merge component 'engine' from git@github.com:moby/moby master 2018-01-20 17:03:57 +00:00
5d42f5ba8b Update API docs to show that /containers/{id}/kill returns HTTP 409
Signed-off-by: Stephan Spindler <shutefan@gmail.com>
Upstream-commit: 3a1bb49b41901dd21ab9489937656ab935a690e0
Component: engine
2018-01-20 17:21:49 +01:00
dbd159de4c Merge pull request #36065 from Microsoft/jjh/bumprs3andlcowsupported
Bump to RS3 final build, and remove LCOW_SUPPORTED
Upstream-commit: ef3f7d18da40cda7f33858b787161773d7656714
Component: engine
2018-01-20 19:53:30 +09:00
bde2b4704d Merge pull request #35830 from cpuguy83/unbindable_shm
Make container shm parent unbindable
Upstream-commit: c162e8eb417bbc124c1f89f676aea081ebb6251f
Component: engine
2018-01-19 17:43:30 -08:00
946a37c1e4 Merge pull request #35744 from ndeloof/35702
closes #35702 introduce « exec_die » event
Upstream-commit: f97256cbf1811740cfa9a72f705c8a70195cd468
Component: engine
2018-01-19 15:03:50 -08:00
2859d16079 Merge pull request #35986 from thaJeztah/bump-containerd-1.0.1-rc1
Bump containerd to 1.0.1 (9b55aab90508bd389d7654c4baf173a981477d55)
Upstream-commit: 47a0dcbcd20aa2924c89a38a16a60907506ae4f2
Component: engine
2018-01-19 15:48:36 -05:00
30c97f4539 Merge pull request #36003 from pradipd/upgrade_fix
Fixing ingress network when upgrading from 17.09 to 17.12.
Upstream-commit: 949ee0e5297408e97c9b5444d500a2cecab06609
Component: engine
2018-01-19 15:46:50 -05:00
5e6be7b1c2 Bump RS3 final build, and remove LCOW_SUPPORTED
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 5b24976ad4046a9c071b75df31d9269ad2e84732
Component: engine
2018-01-19 12:22:56 -08:00
12ceea25e6 Merge pull request #36051 from Microsoft/jjh/remotefs-read-return-error
LCOW remotefs - return error in Read() implementation
Upstream-commit: 3c9d023af3428f49241a2e2385dae43151185466
Component: engine
2018-01-19 11:27:13 -08:00
621663ea5d Merge pull request #36061 from adampointer/36060-fix-name-clash
Alias container and network packages to stop name clashes 
Upstream-commit: 507b8be5b3c02d2b99393d5613a6a59071e13786
Component: engine
2018-01-19 09:53:06 -08:00
3cf8a0c442 Carry 34248 Added tag log option to json-logger and use RawAttrs
This fix carries PR 34248: Added tag log option to json-logger

This fix changes to use RawAttrs based on review feedback.

This fix fixes 19803, this fix closes 34248.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e77267c5a682e2c5aaa32469f2c83c2479d57566
Component: engine
2018-01-19 17:51:20 +00:00
9dd65d097b Added tag log option to json-logger
Fixes #19803
Updated the json-logger to utilize the common log option
'tag' that can define container/image information to include
as part of logging.

When the 'tag' log option is not included, there is no change
to the log content via the json-logger. When the 'tag' log option
is included, the tag will be parsed as a template and the result
will be stored within each log entry as the attribute 'tag'.

Update: Removing test added to integration_cli as those have been deprecated.
Update: Using proper test calls (require and assert) in jsonfilelog_test.go based on review.
Update: Added new unit test configs for logs with tag. Updated unit test error checking.
Update: Cleanup check in jsonlogbytes_test.go to match pending changes in PR #34946.
Update: Merging to correct conflicts from PR #34946.

Signed-off-by: bonczj <josh.bonczkowski@gmail.com>
Upstream-commit: 5f50f4f511cd84e79bf005817af346b1764df27f
Component: engine
2018-01-19 17:41:19 +00:00
3c3132fc24 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-01-19 17:04:04 +00:00
06609b9304 Merge component 'engine' from git@github.com:moby/moby master 2018-01-19 17:03:58 +00:00
c973e2ff26 Merge component 'cli' from git@github.com:docker/cli master 2018-01-19 16:41:06 +00:00
d00d4e32b9 Merge pull request #34859 from Microsoft/jjh/singleimagestore
LCOW: Coalesce daemon stores, allow dual LCOW and WCOW mode
Upstream-commit: bb6ce897378b4ebd0131fd835b01ad5f9af3ebb9
Component: engine
2018-01-19 11:38:30 -05:00
ed76e0e519 Alias container and network packages to stop name clashes
Signed-off-by: Adam Pointer <adam.pointer@gmx.com>
Upstream-commit: 7732ca94fc67a28cbd37c292dc29216255685eba
Component: engine
2018-01-19 10:26:41 +00:00
2cf544120b Revendor Microsoft/opengcs @ v0.3.5
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 042f53737cec84e2f1419e20fe37dd0eb1d5a9fa
Component: engine
2018-01-18 19:17:31 -08:00
fdf41db38c Update libnetwork commit
New Commit: fcf1c3b5e57833aaaa756ae3c4140ea54da00319

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: d23e8a7da58c119a8dda59484e9b180c6f25daed
Component: engine
2018-01-18 20:59:40 -05:00
ebd586c561 LCOW remotefs - return error in Read() implementation
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 6112ad6e7d5d7f5afc698447da80f91bdbf62720
Component: engine
2018-01-18 17:46:58 -08:00
58e2db872f Add pigz to docker-ce spec files
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
Upstream-commit: cee72837c3dd20296d436c48e48f30c3e7b17e7c
Component: packaging
2018-01-19 00:22:00 +00:00
0b18a391f5 Add pigz to recommended packages
This change is in response to https://github.com/moby/moby/pull/35697
It adds pigz to the recommended binaries that should be installed with
docker-ce.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: 1ca014b9440a92b46e2e03d879c03ddc5c51d4c0
Component: packaging
2018-01-18 15:51:57 -08:00
46bc3ffbc5 Merge pull request #817 from vdemeester/make-manifest-cmd-experimental
Mark docker-manifest command as experimental (cli)
Upstream-commit: da86425e9f
Component: cli
2018-01-18 17:46:15 -05:00
ac28efa249 Mark docker-manifest command as experimental (cli)
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Upstream-commit: 2d29732f40
Component: cli
2018-01-18 13:19:33 -08:00
e94c45a5c9 Merge pull request #138 from clnperez/manifest-cmd
Add manifest command
Upstream-commit: 11dfa23a5d
Component: cli
2018-01-18 22:15:49 +01:00
3ca8db9a46 Remove OS() from layer interface
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: c94d34f783944ff6586846ccd11e86925fcee171
Component: engine
2018-01-18 12:56:28 -08:00
676b242a5f Merge pull request #71 from ZeuAlex/rpm_build_aarch64
Aarch64 rpm support 
Upstream-commit: 4cc70e4be06cd19edfbcdab4619bc3c271a4a04c
Component: packaging
2018-01-18 12:55:53 -08:00
40b95b8e94 Address feedback from Tonis
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 0cba7740d41369eee33b671f26276325580bc07b
Component: engine
2018-01-18 12:30:39 -08:00
942fd3c62c LCOW: Regular mount if only one layer
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 420dc4eeb48b155e6b83fccf62f8727ce4bf5b21
Component: engine
2018-01-18 12:01:58 -08:00
9e8b44781f Merge pull request #35965 from thaJeztah/fix-volume-create-statuscode
Return 400 status instead of 500 for empty volume create body
Upstream-commit: 39377bb96d459d2ef59bd2bad75468638a7f86a3
Component: engine
2018-01-18 20:02:33 +01:00
b4c44961cf Merge pull request #36030 from cpuguy83/quota_update
Ensure CPU quota/period updates are sent to runc
Upstream-commit: 0fa3962b8d8d78020c7e636c4bcea14d618929e1
Component: engine
2018-01-18 19:54:10 +01:00
3fa889eb3f Add dockerfile for building on non-amd64 platforms
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 02ca1c8573
Component: cli
2018-01-18 13:16:58 -05:00
86ca16658d Merge component 'packaging' from git@github.com:docker/docker-ce-packaging master 2018-01-18 17:04:03 +00:00
3ee93da859 Merge component 'engine' from git@github.com:moby/moby master 2018-01-18 17:03:57 +00:00
dc08aa82a2 add manifest cmd cli doc
Signed-off-by: Christy Norman Perez <christy@linux.vnet.ibm.com>
Upstream-commit: 6c6ce22447
Component: cli
2018-01-18 10:53:09 -06:00
a654d0d2d6 Merge component 'cli' from git@github.com:docker/cli master 2018-01-18 16:41:08 +00:00
852153685d LCOW: Refactor to multiple layer-stores based on feedback
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: afd305c4b5682fbc297e1685e2b7a49628b7c7f0
Component: engine
2018-01-18 08:31:05 -08:00
33860da10b LCOW: Re-coalesce stores
Signed-off-by: John Howard <jhoward@microsoft.com>

The re-coalesces the daemon stores which were split as part of the
original LCOW implementation.

This is part of the work discussed in https://github.com/moby/moby/issues/34617,
in particular see the document linked to in that issue.
Upstream-commit: ce8e529e182bde057cdfafded62c210b7293b8ba
Component: engine
2018-01-18 08:29:19 -08:00
ce1ad508f6 Merge pull request #35960 from abhi/service
Disable service on release network
Upstream-commit: 6feae060033544985e548dcf1b9127f8f634fe2b
Component: engine
2018-01-18 11:19:47 -05:00
9b47a9d16f Do not make graphdriver homes private mounts.
The idea behind making the graphdrivers private is to prevent leaking
mounts into other namespaces.
Unfortunately this is not really what happens.

There is one case where this does work, and that is when the namespace
was created before the daemon's namespace.
However with systemd each system servie winds up with it's own mount
namespace. This causes a race betwen daemon startup and other system
services as to if the mount is actually private.

This also means there is a negative impact when other system services
are started while the daemon is running.

Basically there are too many things that the daemon does not have
control over (nor should it) to be able to protect against these kinds
of leakages. One thing is certain, setting the graphdriver roots to
private disconnects the mount ns heirarchy preventing propagation of
unmounts... new mounts are of course not propagated either, but the
behavior is racey (or just bad in the case of restarting services)... so
it's better to just be able to keep mount propagation in tact.

It also does not protect situations like `-v
/var/lib/docker:/var/lib/docker` where all mounts are recursively bound
into the container anyway.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 9803272f2db84df7955b16c0d847ad72cdc494d1
Component: engine
2018-01-18 09:34:00 -05:00
2096535fce Fixes for libcontainer changes
Libcontainer no longer provides placeholders for
unsupported platforms, which cause the Windows
builds to fail.

This patch moves features that are not supported
to platform-specific files.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d1c34831e930c1f6b3de28cab3f4a358845a79d5
Component: engine
2018-01-18 10:08:12 +01:00
8d6e00613b Bump runc to 7f24b40cc5423969b4554ef04ba0b00e2b4ba010
matching the version that's used by containerd 1.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: f58aa31075bf74ab8d2369dafb591ae43ed36ee6
Component: engine
2018-01-18 10:07:50 +01:00
c6678dac69 Bump containerd to 1.0.1 (9b55aab90508bd389d7654c4baf173a981477d55)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 9047f66b1edd4dffcafc34f9c7f3390ddd65d10b
Component: engine
2018-01-18 10:06:37 +01:00
2138e8ddb5 Merge pull request #73 from seemethere/remove_zesty
Remove Ubuntu Zesty
Upstream-commit: f8f8219caef8a92c6c87b92377d476af44d76b7c
Component: packaging
2018-01-17 15:12:34 -08:00
3e6e651fda Merge pull request #814 from dnephin/fix-builder-env-docs
Improve builder ENV docs
Upstream-commit: 4f550018bb
Component: cli
2018-01-17 23:26:42 +01:00
2b31b5d6e4 libnetwork vendor
Signed-off-by: abhi <abhi@docker.com>
Upstream-commit: dad093cc34497bb7912c769e469a3e79a0c2c63c
Component: engine
2018-01-17 14:20:04 -08:00
2012c45c5a Disable service on release network
This PR contains a fix for moby/moby#30321. There was a moby/moby#31142
PR intending to fix the issue by adding a delay between disabling the
service in the cluster and the shutdown of the tasks. However
disabling the service was not deleting the service info in the cluster.
Added a fix to delete service info from cluster and verified using siege
to ensure there is zero downtime on rolling update of a service.In order
to support it and ensure consitency of enabling and disable service knob
from the daemon, we need to ensure we disable service when we release
the network from the container. This helps in making the enable and
disable service less racy. The corresponding part of libnetwork fix is
part of docker/libnetwork#1824

Signed-off-by: abhi <abhi@docker.com>
Upstream-commit: a042e5a20a7801efc936daf7a639487bb37ca966
Component: engine
2018-01-17 14:19:51 -08:00
33df5a9f66 Update buidler ENV docs
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 01b521c002
Component: cli
2018-01-17 16:55:07 -05:00
d782361adb Merge pull request #36043 from Microsoft/jjh/fixopenfilecall
LCOW: Fix OpenFile parameters
Upstream-commit: ef3988a81f5dca972b129df527f3e4f8bba200b8
Component: engine
2018-01-17 12:03:11 -08:00
28df99f4fa Merge pull request #35697 from sargun/use-pgzip
Make image (layer) downloads faster by using pigz
Upstream-commit: 871afbb304422877e683cbafc0ebd0b029b85379
Component: engine
2018-01-17 11:18:20 -08:00
0986b8a32c Fixing ingress network when upgrading from 17.09 to 17.12.
Signed-off-by: Pradip Dhara <pradipd@microsoft.com>

Signed-off-by: Pradip Dhara <pradipd@microsoft.com>
Upstream-commit: 2d7a50e5855ad0571e76d29cd1ab9f8f3a48433b
Component: engine
2018-01-17 17:11:18 +00:00
b602be47f6 Merge component 'engine' from git@github.com:moby/moby master 2018-01-17 17:04:48 +00:00
1c449fb090 Merge component 'cli' from git@github.com:docker/cli master 2018-01-17 16:41:12 +00:00
5a20e1240c LCOW: Fix OpenFile parameters
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 141b9a74716c016029badf16aca21dc96975aaac
Component: engine
2018-01-17 07:58:18 -08:00
0e51141e24 Merge pull request #35441 from cpuguy83/plugin_timeout
Add timeouts for volume plugin ops
Upstream-commit: f0b0f2038d085066f340f24f3a9a9683bd4aa35f
Component: engine
2018-01-17 14:49:41 +01:00
19e1833a23 Merge pull request #36033 from cpuguy83/improve_zfs_debug_message
Improve zfs init log message for zfs
Upstream-commit: 1338fcf58aafed25c0da4952793fec1c4055c894
Component: engine
2018-01-16 21:03:53 -08:00
eaa41c5725 Merge pull request #36036 from kolyshkin/plugins
daemon.cleanupMetricsPlugins(): fix
Upstream-commit: 991d64eeb3ee97078a03b88185bee177c6551896
Component: engine
2018-01-17 13:54:46 +09:00
dede819b22 Merge pull request #36034 from dnephin/update-gty
update gotestyourself vendor
Upstream-commit: d84b8802b9fab72c0b66520e54a26c605ddee00b
Component: engine
2018-01-16 19:42:54 -08:00
a5a13dc0e0 Merge pull request #36035 from kolyshkin/gometalinter
gometalinter: fix --deadline option
Upstream-commit: 5488cce5d2effca1e9ae82d8d73d667cf878fd14
Component: engine
2018-01-17 12:04:01 +09:00
4a656e30d0 Improve zfs init log message for zfs
Signed-off-by: Drew Hubl <drew.hubl@gmail.com>
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 27b002f4a02e2d9f6eded9004b82cb81f121264f
Component: engine
2018-01-16 21:42:05 -05:00
7da3044682 Add timeouts for volume plugin ops
This protects the daemon from volume plugins that are slow or
deadlocked.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: b15f8d2d4f054a87052a7065c50441f7e8479fa9
Component: engine
2018-01-16 20:30:49 -05:00
d8a82d08f1 daemon.cleanupMetricsPlugins(): fix
A linter (vet) found the following bug in the code:

> daemon/metrics.go:124::error: range variable p captured by func literal (vet)

Here a variable p is used in an async fashion by goroutine, and most
probably by the time of use it is set to the last element of a range.

For example, the following code

```go
	for _, c := range []string{"here ", "we ", "go"} {
		go func() {
			fmt.Print(c)
		}()
	}
```

will print `gogogo` rather than `here we go` as one would expect.

Fixes: 0e8e8f0f31 ("Add support for metrics plugins")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 9db2c62488734a44a4f1bb9a0252c520b787acfe
Component: engine
2018-01-16 15:15:11 -08:00
374fd77d92 update gotestyourself
pickup changes which use t.Helper()

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 4ac4b690f78a645cc50030b81077fd5319b53501
Component: engine
2018-01-16 17:43:47 -05:00
cd6c81a6fb gometalinter: fix --deadline option
1. Add = between the option and the argument, otherwise the argument
   appears to be passed on to the linters directly, as in:

> DEBUG: [golint.8]: executing /home/kir/go/bin/golint
> -min_confidence 0.800000 ./10m ./api ./api/errdefs <...>

2. Fix setting the default for GOMETALINTER_OPTS -- the default
   was -deadline (rather than --deadline).

Fixes: b96093fa56a9 ("gometalinter: add per-platform configurable options")

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: c11508a5f405084da13c35ee7ab62f1670e4da39
Component: engine
2018-01-16 14:37:11 -08:00
837b878f9d Merge pull request #581 from thaJeztah/better-port-range-printing
Improve presentation of published port ranges
Upstream-commit: fab4762941
Component: cli
2018-01-16 17:16:45 -05:00
01a3b0d1ac Merge pull request #812 from thaJeztah/fix-builder-quote
Fix stray quote in builder.md
Upstream-commit: 44094b5219
Component: cli
2018-01-16 23:15:18 +01:00
42cf4bc867 Fix stray quote in builder.md
Signed-off-by: Taylor Brown <taylorb@microsoft.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 90cfa01889
Component: cli
2018-01-16 22:51:57 +01:00
c2691aeef9 Set git sha from parameter
Because we merge master into the branch before running tests, so the
actual git sha does not exist on any git remote.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: b2faf24925ea0f820db62e1f3d96ee347972f12a
Component: engine
2018-01-16 16:50:57 -05:00
f088309662 Add code coverage report and codecov config
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: e5cce50c7ea727c1c901b6e1443bd4291d62fce3
Component: engine
2018-01-16 16:50:56 -05:00
a19065e951 Make container resource mounts unbindable
It's a common scenario for admins and/or monitoring applications to
mount in the daemon root dir into a container. When doing so all mounts
get coppied into the container, often with private references.
This can prevent removal of a container due to the various mounts that
must be configured before a container is started (for example, for
shared /dev/shm, or secrets) being leaked into another namespace,
usually with private references.

This is particularly problematic on older kernels (e.g. RHEL < 7.4)
where a mount may be active in another namespace and attempting to
remove a mountpoint which is active in another namespace fails.

This change moves all container resource mounts into a common directory
so that the directory can be made unbindable.
What this does is prevents sub-mounts of this new directory from leaking
into other namespaces when mounted with `rbind`... which is how all
binds are handled for containers.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: eaa5192856c1ad09614318e88030554b96bb6e81
Component: engine
2018-01-16 15:09:05 -05:00
35c47edb0e Merge pull request #808 from ethan-haynes/698-tmpfs-mode-compose
added support for tmpfs-mode in compose file
Upstream-commit: 14c62f655a
Component: cli
2018-01-16 20:59:17 +01:00
1c29e89e9b Return 400 status instead of 500 for empty volume create body
The `POST /volumes/create` expects a request body to be provided.
If no body was provided, a 500 status was returned. A 500 status
is incorrect, because the request is invalid (it's not a server
error).

Before this change:

    $ curl --unix-socket /var/run/docker.sock -v -X POST http://localhost/volumes/create

    *   Trying /var/run/docker.sock...
    * Connected to localhost (/Users/sebastiaan/Library/Containers/com.dock) port 80 (#0)
    > POST /volumes/create HTTP/1.1
    > Host: localhost
    > User-Agent: curl/7.51.0
    > Accept: */*
    >
    < HTTP/1.1 500 Internal Server Error
    < Api-Version: 1.30
    < Content-Length: 18
    < Content-Type: application/json
    < Date: Wed, 19 Jul 2017 11:29:26 GMT
    < Docker-Experimental: true
    < Ostype: linux
    < Server: Docker/17.06.0-ce (linux)
    <
    {"message":"EOF"}
    * Curl_http_done: called premature == 0
    * Connection #0 to host localhost left intact

After this change:

    $ curl --unix-socket /var/run/docker.sock -v -X POST http://localhost/volumes/create

    *   Trying /var/run/docker.sock...
    * Connected to localhost (/var/run/docker.sock) port 80 (#0)
    > POST /volumes/create HTTP/1.1
    > Host: localhost
    > User-Agent: curl/7.52.1
    > Accept: */*
    >
    < HTTP/1.1 400 Bad Request
    < Api-Version: 1.36
    < Content-Type: application/json
    < Docker-Experimental: false
    < Ostype: linux
    < Server: Docker/dev (linux)
    < Date: Tue, 09 Jan 2018 15:00:13 GMT
    < Content-Length: 42
    <
    {"message":"no body provided in request"}
    * Curl_http_done: called premature == 0
    * Connection #0 to host localhost left intact

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 5ad1e4be6bd2fd1033bc2adb5be2fe821787b59c
Component: engine
2018-01-16 20:42:44 +01:00
fd6c5edde8 Merge pull request #755 from kolyshkin/wait
Show container wait error
Upstream-commit: 1620538c49
Component: cli
2018-01-16 14:40:36 -05:00
dec893af4f Add more russian scientists in names-generator.go
Signed-off-by: ASM <cpp.create@gmail.com>
Upstream-commit: e0c3fe7836af1b1648fd61b59bd28691f88cc70b
Component: engine
2018-01-16 21:09:17 +02:00
e9c2f9fe77 Make image (layer) downloads faster by using pigz
The Golang built-in gzip library is serialized, and fairly slow
at decompressing. It also only decompresses on demand, versus
pipelining decompression.

This change switches to using the pigz external command
for gzip decompression, as opposed to using the built-in
golang one. This code is not vendored, but will be used
if it autodetected as part of the OS.

This also switches to using context, versus a manually
managed channel to manage cancellations, and synchronization.
There is a little bit of weirdness around manually having
to cancel in the error cases.

Signed-off-by: Sargun Dhillon <sargun@sargun.me>
Upstream-commit: fd35494a251a497c359f706f61f33e689e2af678
Component: engine
2018-01-16 10:49:18 -08:00
fcc2e6e315 container.waitExitOrRemoved(): add a test case
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 85ddaee5af
Component: cli
2018-01-16 10:16:28 -08:00
2c0a4f1b1f Merge component 'engine' from git@github.com:moby/moby master 2018-01-16 17:04:06 +00:00
96cd62f939 added support for tmpfs-mode in compose file
Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>
Upstream-commit: cd69d082ea
Component: cli
2018-01-16 10:52:26 -06:00
6480a738eb adding tmpfs field to the compose 3.6v file spec and updating binary
Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>
Upstream-commit: b15362ce32
Component: cli
2018-01-16 10:50:40 -06:00
fe856d6a3e Ensure CPU quota/period updates are sent to runc
Fixes an issue where if cpu quota/period is sent via the update API, the
values are updated in the stored container data but not actually sent to
the running container.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 86ba63db82e87c943c9dee52559118e46f23defc
Component: engine
2018-01-16 11:50:14 -05:00
596eb2d73f adding config_schema_v3.6.json and updating binary
Signed-off-by: Ethan Haynes <ethanhaynes@alumni.harvard.edu>
Upstream-commit: 2b8cc52409
Component: cli
2018-01-16 10:44:08 -06:00
2d002babe5 Merge component 'cli' from git@github.com:docker/cli master 2018-01-16 16:41:10 +00:00
9ec0657065 Merge pull request #810 from akimd/rmi-eol
Remove: add missing eol when --force is passed
Upstream-commit: 3a69e5d265
Component: cli
2018-01-16 10:29:46 +01:00
a9d5589889 Merge pull request #36021 from yongtang/30897-follow-up
Rename FindUniqueNetwork to FindNetwork
Upstream-commit: be146652108f7145e902c275807f9ef71464b031
Component: engine
2018-01-16 09:38:16 +01:00
c4ee004968 Remove: add missing eol when --force is passed
Signed-off-by: Akim Demaille <akim.demaille@docker.com>
Upstream-commit: f83aa7b705
Component: cli
2018-01-16 09:29:53 +01:00
45b9f9df5c Merge pull request #35983 from yongtang/35980-Dockerfile.simple
Add required pkg-config for Dockerfile.simple
Upstream-commit: 3c7990fb63c546e0d0443e4c74a1ee15b16d005c
Component: engine
2018-01-16 02:41:36 +01:00
04ddd90677 Merge pull request #36025 from yongtang/01152018-golint
Fix golint error
Upstream-commit: 410e95d368cc03363472691bb2b228d3bd5c155a
Component: engine
2018-01-16 02:05:42 +01:00
69f6e83862 Fix golint error
PR #36011 fixed almost all of the golint issues though
there is still one golint error:
https://goreportcard.com/report/github.com/docker/docker#golint
```
Golint is a linter for Go source code.
docker/daemon/reload.go
Line 64: warning: redundant if ...; err != nil check, just return error instead. (golint)
```

This fix fixes the last one.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e02a3d9f5ba3bd9fa7f21596a6ee784bb58053f9
Component: engine
2018-01-15 21:35:30 +00:00
2802ca3c0e Merge pull request #36018 from thaJeztah/remove-deprecated-testenv-functions
Remove deprecated integration-cli/environment functions
Upstream-commit: 8c31aacebff68fe73f4203f86c5681a0fce648f1
Component: engine
2018-01-15 13:24:52 -08:00
d7084e8097 Merge pull request #35638 from cpuguy83/error_helpers2
Add helpers to create errdef errors
Upstream-commit: c36274da8326c59aaa12c48196671b41dcb89e5b
Component: engine
2018-01-15 10:56:46 -08:00
72b954bd11 Rename FindUniqueNetwork to FindNetwork
This fix is a follow up to 30397, with `FindUniqueNetwork`
changed to `FindNetwork` based on the review feedback.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: ccc2ed01894a1950eaf47db2ad0860ad87cd78d1
Component: engine
2018-01-15 17:34:40 +00:00
3c68801e6a Merge component 'engine' from git@github.com:moby/moby master 2018-01-15 17:03:57 +00:00
de86612508 Merge pull request #36011 from thaJeztah/golint-fixes
Golint and Ineffassign  fixes
Upstream-commit: a44274f1c033004f0aaaa225aa98c58c018623f6
Component: engine
2018-01-15 08:59:58 -08:00
d1c8c580ed Remove deprecated environment.DaemonPlatform()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 18a771a761654e241ae8d1e85aa0c0a6164c5d27
Component: engine
2018-01-15 15:32:06 +01:00
28a714b165 Remove deprecated environment.MinimalBaseImage()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: dfedc9ef6214500526c29fbf9a46aca9cecbeb57
Component: engine
2018-01-15 15:31:02 +01:00
d0afa0d404 Remove deprecated environment.ExperimentalDaemon()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: da8032d7d351a2073f54ec0121a796800b6b1a46
Component: engine
2018-01-15 15:30:05 +01:00
de027de052 Remove deprecated environment.DockerBasePath()
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 142b1f8bfb3a1459660a5877b48f2bd7d17ba5d6
Component: engine
2018-01-15 15:29:26 +01:00
1240c39efc Golint: don't use basic untyped string for context key
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: dfac74a9e48d1562ec41bc6de194f6593f0e639b
Component: engine
2018-01-15 12:49:14 +01:00
e0f1df2210 Merge pull request #35929 from arm64b/busybox-ls-compatible
Upgrade the frozen images to multi-arch ones
Upstream-commit: 947eb283dc86b67ea487ed3b7c02ede7b1fbbafd
Component: engine
2018-01-15 12:28:13 +01:00
03f0380721 Merge pull request #36009 from ripcurld0/small_nitpick
Small nitpick: create ErrVolumeTargetIsRoot in the volume package
Upstream-commit: fb13aeef0fc9bf8762643a0682df278544e4c933
Component: engine
2018-01-15 12:19:23 +01:00
02da0b9277 Improve API version-middleware test
Some improvements to the test;

- Combine tests to reduce duplicated code
- Add test-cases for empty version in request using the default version
- Add test for valid versions in request actually setting the version

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 63906d8fae8164c8ef00e1edc957a90b22908bcf
Component: engine
2018-01-15 11:50:30 +01:00
621388138c Golint: remove redundant ifs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: b4a63139696aea2c73ec361a9af8b36a118f0423
Component: engine
2018-01-15 00:42:25 +01:00
3b2e22c98e Small nitpick: create ErrVolumeTargetIsRoot in the volume package
Both lcow_parser.go and linux_parser.go are duplicating the error:
"invalid specification: destination can't be '/'"

This commit creates a new error called "ErrVolumeTargetIsRoot"
that is used by both linux_parser and lcow_parser and remove
the duplication in the code.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Upstream-commit: 62143af5437a29d4b95f971d1905cfef763b0847
Component: engine
2018-01-14 11:41:39 +00:00
4ab8a85d30 Merge component 'engine' from git@github.com:moby/moby master 2018-01-13 17:03:55 +00:00
f9646377ed Merge component 'cli' from git@github.com:docker/cli master 2018-01-13 16:41:07 +00:00
6303353f60 Merge pull request #807 from thaJeztah/golint-fixes
golint: remove redundant ifs
Upstream-commit: 1694921047
Component: cli
2018-01-13 14:55:14 +01:00
2c5689d728 ineffassign: fix unused variables
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 63a0e88e8a61b5c0d5f698d5baf37f568ee01d50
Component: engine
2018-01-13 13:35:10 +01:00
4db79d6583 golint: remove redundant ifs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: d845b4d36a
Component: cli
2018-01-13 13:16:34 +01:00
c3d475f697 Merge pull request #36000 from emil2k/fix-container-log-err
Wrap response error for container logs method.
Upstream-commit: 6415f1dcf5c79da853c604733c56b43ae3d18ced
Component: engine
2018-01-13 03:16:38 +01:00
2c7eb8f0d8 Merge pull request #35998 from arm64b/fix-timeout-multi-services
Fix timeout issue of  multi-services creation on AArch64
Upstream-commit: 86cb53e80060f6028e7847daef5b790fa7b9995f
Component: engine
2018-01-13 03:14:31 +01:00
e19dd094e6 Merge pull request #36001 from tophj-ibm/frozen-z-ci
[ci] use alternate sh comparison
Upstream-commit: bc183a0062c1283cfc47f42ec78501868629dd2b
Component: engine
2018-01-13 01:00:21 +01:00
298483e61f Merge component 'engine' from git@github.com:moby/moby master 2018-01-12 17:04:42 +00:00
e1c32a9951 Merge component 'cli' from git@github.com:docker/cli master 2018-01-12 16:41:09 +00:00
837919cf56 [ci] use alternate bash comparison
The pattern `echo str | grep -qE pattern` likes to fail on the z CI here for
an unknown reason. Use `grep -qE pattern <<< str` instead.

Signed-off-by: Christopher Jones <tophj@linux.vnet.ibm.com>
Upstream-commit: 24da8a0ed415c019179ca2c4f7496cbdffb7e4d0
Component: engine
2018-01-12 11:05:20 -05:00
4f33349d30 Wrap response error for container logs method.
Signed-off-by: Emil Davtyan <emil2k@gmail.com>
Upstream-commit: 2d6fb87ca41c52b255e874be62f2a3c2181a7639
Component: engine
2018-01-12 16:43:51 +01:00
d6831a1fa6 Fix timeout issue of multi-services cration on AArch64
Now we only adjust the timeout value for `arm` while not `arm64`,
actually the avarage duration for this test is about 25s to crate
multiple services on arm64, else the integration test will terminate
with below error:

> --- FAIL: TestCreateServiceMultipleTimes (24.11s)
>         daemon.go:285: [ddc3c7c1476c2] waiting for daemon to start
>         daemon.go:317: [ddc3c7c1476c2] daemon started
>         poll.go:121: timeout hit after 10s: task count at 4 waiting for 0
>         daemon.go:275: [ddc3c7c1476c2] exiting daemon
>         clean.go:108: Removing image sha256:e6a8d12d58602a19277ee5632b7ff9fa56a4ea52ba00eedf1d3f6f5a495fe761
>         clean.go:108: Removing image sha256:876244cc2ecb8fe1b0b2e817e3b78709a2a735edb093bc6849f99aa6c18f3a01

This PR adjusts the timeout value for both `arm64` and `arm` to mitigate
this issue on those 2 platforms.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 4542016cbe985d2af60c25f6a5b24df50bb50aba
Component: engine
2018-01-12 11:52:35 +00:00
2539b89332 Merge pull request #803 from thaJeztah/remove-orchestrator-aliases
Remove aliases for orchestrator
Upstream-commit: b7b3e9a261
Component: cli
2018-01-12 08:59:52 +01:00
d4d0b5c268 Move api/errdefs to errdefs
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: d453fe35b9b8b52d0677fe0c3cc8373f2f5d30d0
Component: engine
2018-01-11 21:21:43 -05:00
952c29f8da Add helpers to create errdef errors
Instead of having to create a bunch of custom error types that are doing
nothing but wrapping another error in sub-packages, use a common helper
to create errors of the requested type.

e.g. instead of re-implementing this over and over:

```go
type notFoundError struct {
  cause error
}

func(e notFoundError) Error() string {
  return e.cause.Error()
}

func(e notFoundError) NotFound() {}

func(e notFoundError) Cause() error {
  return e.cause
}
```

Packages can instead just do:

```
  errdefs.NotFound(err)
```

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 87a12421a94faac294079bebc97c8abb4180dde5
Component: engine
2018-01-11 21:21:43 -05:00
a3765ce30c Optimizations for recurrsive unmount
When a recursive unmount fails, don't bother parsing the mount table to check
if what we expected to be a mountpoint is still mounted. `EINVAL` is
returned when you try to unmount something that is not a mountpoint, the
other cases of `EINVAL` would not apply here unless everything is just
wrong. Parsing the mount table over and over is relatively expensive,
especially in the code path that it's in.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: dd2108766017c13a19bdbfd1a56cd1358580e0bb
Component: engine
2018-01-11 16:13:16 -05:00
5127f79a88 Remove aliases for orchestrator
Prefer "strict" values for orchestrator, as it's
easier to add aliases (if we think it's needed) than
to remove them later.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: a812995f98
Component: cli
2018-01-11 21:16:37 +01:00
15165b99b6 Add required pkg-config for Dockerfile.simple
This fix tries to address the issue raised in 35980 where
pkg-config was missing and was causing Dockerfile.simple build
to fail.

```
$ docker build -t docker:simple -f Dockerfile.simple .
..........
CGO_ENABLED=1 go build  -tags "seccomp apparmor selinux netgo cgo static_build" -installsuffix netgo -ldflags "-w -extldflags -static -X main.gitCommit="b2567b37d7b75eb4cf325b77297b140ea686ce8f" -X main.version=1.0.0-rc4+dev " -o runc .
pkg-config: exec: "pkg-config": executable file not found in $PATH
make: *** [static] Error 2
Makefile:42: recipe for target 'static' failed
The command '/bin/sh -c /tmp/install-binaries.sh runc containerd tini proxy dockercli' returned a non-zero code: 2
```

This fix fixes 35980.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: a018046ad0462c78601863784d3b882e77a7281b
Component: engine
2018-01-11 20:12:16 +00:00
4bf05acc16 Merge pull request #35982 from cpuguy83/fix_concurrent_daemon_test_issues
Fix race with concurrent daemon startup in tests
Upstream-commit: 92309e34e42aec3a0e041403bdd3c4fc0dc20269
Component: engine
2018-01-11 14:26:35 -05:00
cfd3975d5f Merge pull request #802 from thaJeztah/fix-yaml-generation
Fix docs YAML generation setting "kubernetes" for "swarm"
Upstream-commit: 41368a84bb
Component: cli
2018-01-11 19:56:36 +01:00
3e7d4bee2e Fix docs YAML generation setting "kubernetes" for "swarm"
Due to a copy/paste error, commands annotated with "swarm"
were incorrectly setting the "kubernetes" property.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 6be06a3db2
Component: cli
2018-01-11 18:30:50 +01:00
59912e9e1d Merge component 'engine' from git@github.com:moby/moby master 2018-01-11 17:06:24 +00:00
8bf6743e94 Fix race with concurrent daemon startup in tests
Using parallel tests is nice, however it can cause an issue with
multiple daemons trying to make changes to iptables at the same time
which causes flakey tests.

This just disables iptables for the set of tests since it is not
required.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 9e3193810da91d81f6b2dba3171443557f756794
Component: engine
2018-01-11 11:47:21 -05:00
10c2915921 Wrap response errors for container copy methods.
This allows IsErrNotFound and IsErrNotImplemented to work as intended.

Signed-off-by: Emil Davtyan <emil2k@gmail.com>
Upstream-commit: 44369bdd6507006108f39b85b5950f933bf1380a
Component: engine
2018-01-11 13:40:49 +01:00
a64e387daf Merge pull request #35976 from thaJeztah/bump-libnetwork2
Bump libnetwork to a1dfea384b39779552a3b4837ea9303194950976
Upstream-commit: cc79c6c7dab994c72133c782a24c69b5ad0f8993
Component: engine
2018-01-10 22:56:00 -08:00
54836718fd busybox: use '-v' option for 'cat'
Use `cat -v` command instead of `catv` for the latest version of
busybox(V1.28.0) with multi-arch

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: ec6659a1216fbfe3fead759b0220501847d12e28
Component: engine
2018-01-11 06:35:17 +00:00
9251d7a17a busybox: Fix ls compatible issue
BusyBox v1.26.2 (2017-03-09 00:04:38 UTC) supports `-le` option
to get the full date and time information, while BusyBox v1.27.2
(2017-11-01 23:22:25 UTC, which is used by the official multi-arch
image, uses `--full-time` instead of `-e` to get the same data. As
a result, we will get below error for the `DockerSuite.TestBuildLastModified`
test case in case of multi-arch image used:

> docker_cli_build_test.go:446:
>     out2 = cli.DockerCmd(c, "run", name, "ls", "-le", "/file").Combined()
>   o/src/github.com/docker/docker/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go:61:
>     t.Fatalf("at %s:%d - %s\n", filepath.Base(file), line, err.Error())
> ... Error: at cli.go:33 -
> Command:  /usr/local/bin/docker run testbuildlastmodified ls -le /file
> ExitCode: 1
> Error:    exit status 1
> Stdout:
> Stderr:   ls: invalid option -- e
> BusyBox v1.27.2 (2017-11-01 23:22:25 UTC) multi-call binary.

This PR tries to fix the above compatible issue for busybox image.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: f88c2c04ef4dbae20eaddeaf69e605878f498041
Component: engine
2018-01-11 06:34:54 +00:00
5c2e02eb8f Removal of TEST_IMAGE_NAMESPACE
We don't need the test image namespace anymore since we've already
upgrade those images to the latest multi-arch ones.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 662bdb4a5638e56d78e66bb2cb5d7a4a751135c9
Component: engine
2018-01-11 05:16:09 +00:00
c6bfcea4c8 Upgrade the frozen images to multi-arch
Upgrade the frozen images to the multi-arch ones.

Since issue #35963 is not fixed yet on linux/amd64, so we keep the busybox
image on amd64 untouched.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: eaae7750efbc80314c5e028c4d43d3cd9e104edd
Component: engine
2018-01-11 05:14:09 +00:00
932ef79d5b Add test case for before and since filter for docker ps
This fix adds an integration test for `before` and `since` filter for `docker ps`

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 52b44b98161872f704f7e3eea16e0f3177ca4e42
Component: engine
2018-01-10 17:42:43 +00:00
f408947b41 Bump libnetwork to a1dfea384b39779552a3b4837ea9303194950976
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 4c3afb53e633a832871cada30890e3497fceff02
Component: engine
2018-01-10 18:09:05 +01:00
eae3cf0a12 Merge component 'engine' from git@github.com:moby/moby master 2018-01-10 17:07:15 +00:00
a9d3d30077 Merge component 'cli' from git@github.com:docker/cli master 2018-01-10 16:41:31 +00:00
1682b7c735 Merge pull request #35902 from dnephin/cleanup-graphdriver-quota-tests
Skip graphdriver/quota TestBlockDev if dependencies are not available
Upstream-commit: 88b94d7849c2ec3ab61b179c8bfdeb28507cf451
Component: engine
2018-01-10 05:32:16 -08:00
dc5184e050 Merge pull request #30897 from yongtang/30242-network-duplicate-names
Update `FindNetwork` to address network name duplications
Upstream-commit: 484612f388cabf4b6f4df915f2bf268a8ffdd9fc
Component: engine
2018-01-10 05:30:58 -08:00
b1b02a3b31 Merge pull request #35968 from Microsoft/jjh/go-winio-0.4.6
Revendor Microsoft/go-winio @ v0.4.6
Upstream-commit: 062b4c8013a50afd4c96f4964f0d759c00f000ea
Component: engine
2018-01-10 05:23:50 -08:00
bf3f938c50 Merge pull request #35940 from yongtang/35920-filter-health-starting
Fix issue of filter in `docker ps` where `health=starting` returns nothing
Upstream-commit: 7c7a7c7944a28e16aed4d2a0f2d590541f1c5687
Component: engine
2018-01-10 14:12:47 +01:00
77c9b11634 Merge pull request #35970 from RenaudWasTaken/cli-fix
Fix node-generic-resources CLI typo
Upstream-commit: 178d0278296c9a0778755f0804ced34756ee4fc7
Component: engine
2018-01-10 12:49:00 +01:00
6252dbd48d Merge pull request #35969 from Microsoft/jjh/typo-would
Fix typo 'woudld' to 'would'
Upstream-commit: 7f81894df299fbedee2fe891276ba60ccca897a4
Component: engine
2018-01-09 22:40:30 -05:00
c31e485134 Fix node-generic-resources CLI typo
Signed-off-by: Renaud Gaubert <rgaubert@nvidia.com>
Upstream-commit: 6702ac590e6148cb3f606388dde93a011cb14931
Component: engine
2018-01-10 00:51:47 +01:00
6b1b00bfce Fix typo 'woudld' to 'would'
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: d92acd59108565ac2e552e9f04e873decd192e6d
Component: engine
2018-01-09 14:25:33 -08:00
6611bbb002 Revendor Microsoft/go-winio @ v0.4.6
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 2956ef1db218f228e6bba5ca8c875aa692092b3d
Component: engine
2018-01-09 13:41:16 -08:00
2f79038e74 Merge pull request #35748 from dnephin/try-new-containerd-cio
Update vendor of containerd, use new containerd/cio
Upstream-commit: 274538c70bfb537430b8543646bc9de36c4d879c
Component: engine
2018-01-09 15:56:05 -05:00
6094444b27 Merge pull request #793 from thaJeztah/bump-version-to-v18.02-dev
Bump version to v18.02.0-dev
Upstream-commit: 4c7749e523
Component: cli
2018-01-09 20:44:53 +01:00
6979911095 Fix --network-add adding duplicate networks
When adding a network using `docker service update --network-add`,
the new network was added by _name_.

Existing entries in a service spec are listed by network ID, which
resulted in the CLI not detecting duplicate entries for the same
network.

This patch changes the behavior to always use the network-ID,
so that duplicate entries are correctly caught.

Before this change;

    $ docker network create -d overlay foo
    $ docker service create --name=test --network=foo nginx:alpine
    $ docker service update --network-add foo test
    $ docker service inspect --format '{{ json .Spec.TaskTemplate.Networks}}' test
    [
      {
        "Target": "9ot0ieagg5xv1gxd85m7y33eq"
      },
      {
        "Target": "9ot0ieagg5xv1gxd85m7y33eq"
      }
    ]

After this change:

    $ docker network create -d overlay foo
    $ docker service create --name=test --network=foo nginx:alpine
    $ docker service update --network-add foo test
    service is already attached to network foo

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: e6ebaf55dd
Component: cli
2018-01-09 20:42:09 +01:00
940cce76d9 Merge component 'engine' from git@github.com:moby/moby master 2018-01-09 17:07:27 +00:00
6f88b66c36 Fix libcontainerd/client.Restore() handling of io cleanup
Make the behvious of cleaning up DirectIO more obvious

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 9d20d5eb3fd744088e700292b15d56de29a3361d
Component: engine
2018-01-09 12:03:02 -05:00
cf94b87820 Use cio.FIFOSet.Close() to cleanup fifos
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: d72dfbfa8db9a99be34c2d7963717a08ab7358c5
Component: engine
2018-01-09 12:00:28 -05:00
097704d16a Remove libcontainerd.IOPipe
replaced with cio.DirectIO

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 3fec7c0858a0a3dee5423e6bffc3a3a1b238c30f
Component: engine
2018-01-09 12:00:28 -05:00
9cffb84b7c Update vendor
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 4f5c47aae4105840a16047b7bca424319a7db709
Component: engine
2018-01-09 12:00:27 -05:00
2e2fe70626 Bump version to v18.02.0-dev
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 1350a08b4f
Component: cli
2018-01-09 10:30:59 +01:00
bcd054dac5 Merge pull request #35957 from crosbymichael/ramdisk
Honor DOCKER_RAMDISK with containerd 1.0
Upstream-commit: 94b8a116fbf1cd90e68d8f5361b520d326a66f9b
Component: engine
2018-01-08 17:38:17 -08:00
207f11f4b6 Merge pull request #35959 from dnephin/remove-str-error-checking
Use errdefs instead of string contains for checking not found
Upstream-commit: 7f6fdce901d51e2692f7d5229d7ba8b4bad6c6a9
Component: engine
2018-01-08 20:33:51 -05:00
ec52ac3e88 Merge pull request #35958 from yongtang/35956-doc-CopyFromContainer
Update doc for CopyFromContainer
Upstream-commit: b4c7017f8d95ab42b1f9aa40260966df2c121cd5
Component: engine
2018-01-08 15:22:40 -08:00
790deda568 Merge pull request #386 from seemethere/bump_ver_18_02_dev
[master] bump VERSION to 18.02.0-ce-dev
2018-01-08 14:15:00 -08:00
adaa8a0f77 bump VERSION to 18.02.0-ce-dev
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-01-08 21:32:48 +00:00
88fc146546 Use errdefs instead of string contains for checking not found
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 9b62d4ffa39f7c042f94f9a3670cae2a816535da
Component: engine
2018-01-08 14:32:39 -05:00
58f87a5e9a Cleanup graphdriver/quota test
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: e3a6323419c8b2a81a21134ed49a1624eb483c81
Component: engine
2018-01-08 13:41:45 -05:00
844b65b181 Update doc for CopyFromContainer
This fix updates doc for CopyFromContainer to explicitly
mention that the content received from the reader is
a TAR archive.

This fix closes 35965.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: e330e7a5ce77736c76c36ba77983accfae01c405
Component: engine
2018-01-08 18:29:59 +00:00
7a08117e1e manifest tests
create, annotate, & push

Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com>
Signed-off-by: Christopher Jones <tophj@linux.vnet.ibm.com>
Upstream-commit: db6d87216d
Component: cli
2018-01-08 11:12:57 -06:00
785a293997 Merge component 'engine' from git@github.com:moby/moby master 2018-01-08 17:06:08 +00:00
1f027b4d1b Honor DOCKER_RAMDISK with containerd 1.0
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Upstream-commit: 54051e9e64185e442e034c7e49a5707459a9eed2
Component: engine
2018-01-08 12:01:03 -05:00
d25231dbba add manifest command
Enable inspection (aka "shallow pull") of images' manifest info, and
also the creation of manifest lists (aka "fat manifests").

The workflow for creating a manifest list will be:

`docker manifest create new-list-ref-name image-ref [image-ref...]`
`docker manifest annotate new-list-ref-name image-ref --os linux --arch
arm`
`docker manifest push new-list-ref-name`

The annotate step is optional. Most architectures are fine by default.

There is also a `manifest inspect` command to allow for a "shallow pull"
of an image's manifest: `docker manifest inspect
manifest-or-manifest_list`.

To be more in line with the existing external manifest tool, there is
also a `-v` option for inspect that will show information depending on
what the reference maps to (list or single manifest).

Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com>
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: 02719bdbb5
Component: cli
2018-01-08 10:43:56 -06:00
4cf72cbba1 Merge component 'cli' from git@github.com:docker/cli master 2018-01-08 16:41:25 +00:00
f81efe6736 vendor updates for manifest cmd
Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com>
Upstream-commit: 17886d7547
Component: cli
2018-01-08 10:40:55 -06:00
476b1d747b Merge pull request #792 from thaJeztah/fix-builder-typo
Fix repeated "for" in docs/reference/builder.md
Upstream-commit: 16cccc30f9
Component: cli
2018-01-08 14:34:14 +01:00
143be37b02 Fix repeated "for" in docs/reference/builder.md
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 7e465d1b09
Component: cli
2018-01-08 12:33:06 +01:00
5017f2840c Merge pull request #35593 from ndeloof/master
Improve swagger schema for code generation
Upstream-commit: 16a1736b9b93e44c898f95d670bbaf20a558103d
Component: engine
2018-01-08 12:17:56 +01:00
27f91f80b9 introduce « exec_die » event
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: aa6bb5cb698ebcf6662e6667bc58055b5b5bde23
Component: engine
2018-01-08 11:42:25 +01:00
5857ab9402 Merge pull request #35798 from ndeloof/ProgressDetail
Progress detail
Upstream-commit: 847df43d1df0ef7343d4f623138dcbb4307d6083
Component: engine
2018-01-08 11:28:49 +01:00
f75b092795 Add test case for docker ps -f health=starting
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: f509a54bdd29b8f65c17097fde3664c6fad36c21
Component: engine
2018-01-07 05:10:36 +00:00
7ee813acf5 Update and use FindNetwork on Windows.
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: b249ccb1151a3c2c7e442b6c1a769821afb28fe4
Component: engine
2018-01-07 03:32:37 +00:00
414f8b2aa4 Merge component 'engine' from git@github.com:moby/moby master 2018-01-06 17:06:58 +00:00
ecf8d36483 Merge component 'cli' from git@github.com:docker/cli master 2018-01-06 16:41:31 +00:00
65164d88f6 Fix Volumes property definition in ContainerConfig
Actually the specification was expecting a 'additionalProperties' for the Volumes data, where in fact it's expecting
a map of string pointing to empty object.

Signed-off-by: Joel Wurtz <joel.wurtz@gmail.com>
Upstream-commit: dc883c0486b398eb5ad99f35aef3ff02a5a7dd29
Component: engine
2018-01-06 16:12:05 +01:00
5fe06b3e89 Merge pull request #35033 from chchliang/viservice
Add `namespace method` conver in `TestV1IDService` 
Upstream-commit: c6378920e14638cc281c5513a989fdff82562426
Component: engine
2018-01-06 14:37:48 +01:00
6169dab4e0 Merge pull request #789 from mistyhacks/load-supports-gzip
docker load supports tar and tar.gz files
Upstream-commit: 6764ce922a
Component: cli
2018-01-06 13:23:34 +01:00
d0f281be92 docker load supports tar and tar.gz files
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: ac7a5650f0
Component: cli
2018-01-05 20:33:31 -08:00
df9a679f90 Update FindUniqueNetwork to address network name duplications
This fix is part of the effort to address 30242 where
issue arise because of the fact that multiple networks
may share the same name (within or across local/swarm scopes).

The focus of this fix is to allow creation of service
when a network in local scope has the same name as the
service network.

An integration test has been added.

This fix fixes 30242.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: cafed80cd019a8b40025eaa5e5b37459362607fb
Component: engine
2018-01-06 01:55:28 +00:00
836e5c6bd0 Fix before and since filter for docker ps
This fix tries to address the issue raised in 35931 where
`before` and `since` filter for `docker ps` does not work
and returns an error
```
Error response from daemon: no such container <container_name>
```

The issue was that `before` and `since` filter are matched
with `view.Get()` which does not take into considerations
of name match.

This fix fixes the issue by adding additional logic for name
match.

This fix fixes 35931.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 9833332dba5cba3709c5d78c28d3dbc52e49bfa9
Component: engine
2018-01-06 00:51:08 +00:00
e6a8744081 Merge pull request #785 from friism/make-config-wording-more-consistent
use 'config' over 'configuration file'
Upstream-commit: a60bdf3bc8
Component: cli
2018-01-05 22:26:48 +01:00
1bed718e52 use 'config' over 'configuration file'
Signed-off-by: Michael Friis <friism@gmail.com>
Upstream-commit: 99e3b4cd93
Component: cli
2018-01-05 13:19:53 -08:00
0e6233fd86 Merge pull request #681 from mistyhacks/expose-no-protocol
Document EXPOSE UDP syntax
Upstream-commit: 6f09f48bf1
Component: cli
2018-01-05 21:39:21 +01:00
9c4ef1072a Merge pull request #35509 from cpuguy83/splunk_dont_readall
Splunk: limit the reader size on error responses
Upstream-commit: 39faf2a3a83c4abad8ed8030a9b942bbb2978359
Component: engine
2018-01-05 12:34:35 -08:00
233f49e086 Merge pull request #35570 from zemanlx/feature/journald-with-SYSLOG_IDENTIFIER
Add journald tag as SYSLOG_IDENTIFIER
Upstream-commit: d80c13a54114de602c8b75030e3ec9c2cde9575b
Component: engine
2018-01-05 20:56:55 +01:00
656c1163c8 add namespace method conver
Signed-off-by: chchliang <chen.chuanliang@zte.com.cn>
Upstream-commit: 0446b6a04edaae1bddeb1dfdb82fd0d931fe1198
Component: engine
2018-01-05 16:24:18 +08:00
3887b15050 Merge pull request #35925 from Microsoft/jjh/builder-default-rw-size-bump
Windows: Bump RW layer size
Upstream-commit: fff423289965260c0ca83024059aa30999792c4a
Component: engine
2018-01-04 22:54:38 -08:00
62d7ad0948 Fix issue of filter in docker ps where health=starting returns nothing
This fix tries to address the issue raised in 35920 where the filter
of `docker ps` with  `health=starting` always returns nothing.

The issue was that in container view, the human readable string (`HealthString()` => `Health.String()`)
of health status was used. In case of starting it is `"health: starting"`.
However, the filter still uses `starting` so no match returned.

This fix fixes the issue by using `container.Health.Status()` instead so that it matches
the string (`starting`) passed by filter.

This fix fixes 35920.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 97b16aecf9275f4103c2737b79d0c5e81583aa58
Component: engine
2018-01-05 05:16:09 +00:00
e76ddf0d7b Merge pull request #35737 from tonistiigi/fix-git-submodules
gitutils: fix checking out submodules
Upstream-commit: 50ce54645094a5d337e5d841c037663e9f4e3170
Component: engine
2018-01-05 10:41:04 +08:00
ad4db68af2 Merge pull request #35753 from kolyshkin/netgo
install-containerd-static: use netgo buildtag
Upstream-commit: 51ccedda52413eef2cd4ba8e3948c84501210f3d
Component: engine
2018-01-05 09:05:46 +08:00
40052b6ec6 Document EXPOSE UDP syntax
Signed-off-by: Misty Stanley-Jones <misty@docker.com>
Upstream-commit: db572ec4ab
Component: cli
2018-01-04 16:16:06 -08:00
d9cc44462d Remove Ubuntu Zesty
Ubuntu Zesty is end of life on January 2018

https://wiki.ubuntu.com/Releases

Signed-off-by: Eli Uriegas <seemethere101@gmail.com>
Upstream-commit: 41086726310e3f78043a4bcf0bcecd5a16d8a144
Component: packaging
2018-01-05 00:02:41 +00:00
0c06f43df3 Merge component 'engine' from git@github.com:moby/moby master 2018-01-04 17:06:40 +00:00
1fbbb4c59b Merge pull request #35924 from Microsoft/32838-partial-fix
Vendor Microsoft/hcsshim @ v0.6.8
Upstream-commit: 4459775eeaa0a3239866fe091014eb1e707bdc2c
Component: engine
2018-01-04 17:49:17 +01:00
c30ceea721 Merge component 'cli' from git@github.com:docker/cli master 2018-01-04 16:41:22 +00:00
8322194c96 Merge pull request #781 from thaJeztah/fix-autogenerated-formatting
Fix gofmt for auto-generated k8s code
Upstream-commit: 220c50abc1
Component: cli
2018-01-04 11:23:32 -05:00
c08c5639be Merge pull request #784 from kizzie/fix/html-for-table
Correct table html with close tag for </thead>
Upstream-commit: 2a4c1ef0c1
Component: cli
2018-01-04 17:12:47 +01:00
Kat
e4754a59e3 Correct table html with close tag for </thead>
Signed-off-by: Kat Samperi <kat.samperi@gmail.com>
Upstream-commit: 57372d18ca
Component: cli
2018-01-04 15:01:28 +00:00
fb52c2003b Windows: Bump RW layer size
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: deb335d04fd47e96fdb7b342dece513174b574bd
Component: engine
2018-01-03 15:59:06 -08:00
39c64668e4 Fix gofmt for auto-generated k8s code
This code kept being modified by my IDE, so fixing
the formatting.

This is auto-generated code, but the code to generate
is not in this repository, so this is a temporary fix
until the code-generation upstream is fixed :)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: bb01064691
Component: cli
2018-01-03 23:57:23 +01:00
fa87c342b2 Vendor Microsoft/hcsshim @ v0.6.8
Signed-off-by: John Howard <jhoward@microsoft.com>
Upstream-commit: 172a442c27ed35778662980809824fdf15a722a6
Component: engine
2018-01-03 10:19:05 -08:00
6f3ae5f1f6 Merge pull request #35772 from arm64b/multi-arch-manifest-support
Download support of images with multi-arch manifest
Upstream-commit: fda904911d87a2b36e6fdcc048726bb6b593d944
Component: engine
2018-01-03 19:03:33 +01:00
169f9cc018 Add test case for 35333: Devicemapper: ignore Nodata errors when delete thin device
This fix adds a test case for 35333: Devicemapper: ignore Nodata errors when delete thin device

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
Upstream-commit: 7c6ef28042c20fdad23cd461ab49b9cfa0c757df
Component: engine
2018-01-03 15:06:52 +00:00
c2b1f7ca70 Devicemapper: ignore Nodata errors when delete thin device
if thin device is deteled and the metadata exists, you can not
delete related containers. This patch ignore Nodata errors for
thin device deletion

Signed-off-by: Liu Hua <sdu.liu@huawei.com>
Upstream-commit: 8451d03d8ef7457f82112179cd3e300c05a08d3d
Component: engine
2018-01-02 18:04:25 +00:00
e1e6adb17e Build rpms for aarch64
Upstream-commit: e204caefd93865ae41a863391b394432130e33fa
Component: packaging
2017-12-20 15:24:30 +01:00
6b042c3e6d install-containerd-static: use netgo buildtag
When compiling containerd binaries statically, linker rightfully
complains:

 + make BUILDTAGS=static_build 'EXTRA_FLAGS=-buildmode pie' 'EXTRA_LDFLAGS=-extldflags "-fno-PIC -static"'
 🇩 bin/ctr
 # github.com/containerd/containerd/cmd/ctr
 /tmp/go-link-343047789/000000.o: In function `_cgo_b0c710f30cfd_C2func_getaddrinfo':
 /tmp/go-build/net/_obj/cgo-gcc-prolog:46: warning: Using 'getaddrinfo'
 in statically linked applications requires at runtime the shared
 libraries from the glibc version used for linking

The same error appears for ctr, containerd, and containerd-stress
binaries.

The fix is to use Go's own DNS resolver functions, rather than
glibc's getaddrinfo() -- this option is turned on by `netgo` build tag.

See https://golang.org/pkg/net/ (look for "Name Resolution") for more
details.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 7368ef96c89fd4f6879addf5214c4a09889a05be
Component: engine
2017-12-19 18:25:02 -08:00
756e315027 fix attribute names on ProgressDetail
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 5e63edfa935e4f87e588d358d7060227745de288
Component: engine
2017-12-16 09:38:34 +01:00
264a31ea91 CreateImage uses ‘id’ to track layers
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: cfa07bffb5e27763fa4bb189133dadd179e4bd23
Component: engine
2017-12-16 09:38:34 +01:00
7b36860dee BuildInfo uses ‘aux’ to document image ID after build
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 9e29d2ea49aaee9cd92fa3fe026ff5f8ab1f8a25
Component: engine
2017-12-16 09:38:33 +01:00
f77854ac3c Show container wait error
If container wait has failed, show an error from the engine
and return an appropriate exit code.

This requires engine changes from https://github.com/moby/moby/pull/34999

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
Upstream-commit: 8471742a8a
Component: cli
2017-12-15 14:15:30 -08:00
53eeb39422 Simplify bash completion for service options
Previously, the completions for `--xxx` and the corresponding
`-xxx-add` and `-xxx-rm` options were defined in separate blocks.
This caused a lot of duplicated code.

This PR removes duplication for xxx=config|group|host|placement-pref|secret.

Now the blocks for `create` and `update` only contain completions for
options that either only exist for the particular command or are specific
to it (completions for `--env-rm` and `--env|env-add` differ).

Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: f2b42bb6a8
Component: cli
2017-12-15 13:49:42 +01:00
a7c2ea2fc4 Fix bash completion for service env, mounts and labels
`service create` and `service update` both used to have `--env`, `--label`
and `--mount` options.
These options now are only valid for `service create`.
`service update` got corresponding `--xxx-add|rm` options instead.

Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: d149c93c0c
Component: cli
2017-12-15 13:49:42 +01:00
6f60e78f91 Download support of images with multi-arch manifest
Currently we only support 'application/vnd.docker.distribution.manifest.v2+json'
manifest images download, with more multi-arch images used, we need to support
download images with 'application/vnd.docker.distribution.manifest.list.v2+json'
format(aka "fat manifest"), else we will fail to download those multi-arch ones.

This PR adds 'application/vnd.docker.distribution.manifest.list.v2+json' manifest
support, thus we can download both multi-arch and legacy images.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Upstream-commit: 0af5db511ed1ed5beab0feb09a2a96347a263410
Component: engine
2017-12-14 05:37:22 +00:00
0834563329 use swagger support for « title » as generated types names for inline schema
align naming convention with x-go-name

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 8e7f9afa471c2be079f2c8897cf3b87e7f60544e
Component: engine
2017-12-13 18:54:37 +01:00
fd3779deb1 Update go-swagger installation steps in Dockerfile
The installation steps for go-swagger was a bit noisy, and not consistent with
other installation steps.

This patch makes it similar to other steps, which makes it less noisy, and
makes the image slightly smaller.

Before:

    b53d7aac3200        14 minutes ago      |1 APT_MIRROR=deb.debian.org /bin/sh -c git …   107MB
    fa74acf32f99        2 hours ago         /bin/sh -c #(nop)  ENV GO_SWAGGER_COMMIT=c28…   0B

After:

    6b2454f1a9a5        10 minutes ago      |1 APT_MIRROR=deb.debian.org /bin/sh -c set …   35.2MB
    fa74acf32f99        2 hours ago         /bin/sh -c #(nop)  ENV GO_SWAGGER_COMMIT=c28…   0B

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 29d77acaf8bfb234ee4f0b3db9e28d7410b99d4e
Component: engine
2017-12-08 14:02:32 -08:00
5b48c4106b gitutils: remove checkout directory on error
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: 4ea320cb8ef71c2fc9ee391e2e8be915ba99b17e
Component: engine
2017-12-08 11:58:13 -08:00
94fbfde561 gitutils: fix checking out submodules
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Upstream-commit: a6025255246aab21426a51986b7d138a14d9ac90
Component: engine
2017-12-07 14:25:19 -08:00
b8eda642a7 Splunk: limit the reader size on error responses
Before this patch, if a splunk endpoint returned a non-OK status, the
splunk driver would read the entire response body. This could lead to
excessive memory allocations. Instead put a cap on the amount the driver
will read from the response body.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: 7f14542ddd1401de734be3ac0331c0ada941c959
Component: engine
2017-12-07 11:22:58 -05:00
c05aa2cc73 Minor bash completion improvements/fixes
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 53376b60c6
Component: cli
2017-12-04 09:33:14 +01:00
8583ba4a32 Improve bash completion for images
Signed-off-by: Harald Albers <github@albersweb.de>
Upstream-commit: 5ee3b9b461
Component: cli
2017-12-04 09:33:14 +01:00
01d480da3c duplicate definitions for API response with just an ID
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: d6935a8f1a4003c0b6f1b89a0e28e721d0756ac9
Component: engine
2017-11-24 11:41:04 +01:00
749a92c1a6 schema is missing CanRemove & DetachKeys
example demonstrates they are expected

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Upstream-commit: 74cb739766e517115c5af9cee2202613661238a0
Component: engine
2017-11-24 11:40:12 +01:00
e56d0513c6 Add journald tag as SYSLOG_IDENTIFIER
Signed-off-by: Vlastimil Zeman <vlastimil.zeman@diffblue.com>
Upstream-commit: ae557f9d85f41e009229d1a33844f06f7ad1fb99
Component: engine
2017-11-22 08:51:23 +00:00
3acd4904bf Fix TestAttachExitCode
Signed-off-by: Daniel Nephin <dnephin@docker.com>
Upstream-commit: bace33d7a8
Component: cli
2017-11-17 18:12:48 -08:00
1a65d7d84f attach: Use ContainerWait instead of Inspect
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
Upstream-commit: 66661761d5
Component: cli
2017-11-17 18:12:46 -08:00
8fc8b79463 *: switch to -buildmode=pie
Go has supported PIC builds for a while now, and given the security
benefits of using PIC binaries we should really enable them. There also
appears to be some indication that non-PIC builds have been interacting
oddly on ppc64le (the linker cannot load some shared libraries), and
using PIC builds appears to solve this problem.

Signed-off-by: Aleksa Sarai <asarai@suse.de>
Upstream-commit: 1f4e37cf4bd2f73dc5257d791cc4dba294ddd156
Component: engine
2017-11-11 21:59:49 +11:00
6d69a9855a Enable HotAdd for Windows
Signed-off-by: Madhan Raj Mookkandy <madhanm@microsoft.com>
Upstream-commit: 5c1cfb1d27a1a7f7c0cb9092e69c3f70717fbbef
Component: engine
2017-11-03 14:24:10 -07:00
0ccfca8508 Improve presentation of published port ranges
Port mappings in `docker service ls` are quite verbose, and occupy a lot of
space when ranges of ports are published.

This patch improves the output by reconstructing ranges of ports.

Given the following service;

    $ docker service create \
      -p 60-61:60-61 \
      -p 62:61 \
      -p 80:80 \
      -p 81:80 \
      -p 90-95:90-95 \
      -p 90-92:90-92/udp \
      -p 93-96:93-96/udp \
      --name foo \
      nginx:alpine

Before this patch is applied:

    $ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    u1kwguv841qg        foo                 replicated          1/1                 nginx:alpine        *:60->60/tcp,*:61->61/tcp,*:62->61/tcp,*:80->80/tcp,*:81->80/tcp,*:90->90/tcp,*:91->91/tcp,*:92->92/tcp,*:93->93/tcp,*:94->94/tcp,*:95->95/tcp,*:90->90/udp,*:91->91/udp,*:92->92/udp,*:93->93/udp,*:94->94/udp,*:95->95/udp,*:96->96/udp

After this patch is applied:

    $ docker service ls
    ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
    u1kwguv841qg        foo                 replicated          1/1                 nginx:alpine        *:60-62->60-61/tcp,*:80-81->80/tcp,*:90-95->90-95/tcp,*:90-96->90-96/udp

Additional enhancements can still be made, and marked as TODO in this change;

- combine non-consecutive ports mapped to a single port (`80->80`, `81->80`,
  `84->80`, `86->80`, `87->80`); to be printed as `*:80-81,84,86-87->80`.
- combine `tcp` and `udp` mappings if their port-mapping is the same;
  print `*:80-81->80-81/tcp+udp` instead of `*:80-81->80-81/tcp, *:80-81->80-81/udp`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: e98e95e7bc
Component: cli
2017-10-02 12:54:20 +02:00
d873e90bed Update gitignore
Adding some lines from the Moby gitignore

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: cdaf6f44ba
Component: cli
2017-09-27 16:45:35 +02:00
6d1342e805 Fix leading characters being stripped from example sections in YAML
`strings.Trim()` strips any character listed in the `cutset` argument,
so any example section having `E`, `x`, `a`, `m`, `p`, `l`, `e`, or `s`
in the first word, had these characters missing in the generated
YAML.

Also trim superfluent whitespace characters to consistently use `|-` ("strip")
as block chomping indicator (see http://www.yaml.org/spec/1.2/spec.html#id2794534)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Upstream-commit: 1f605d43ca
Component: cli
2017-09-27 10:59:09 +02:00
3398b05230 Update event filter zsh completion with disable, enable, install, and remove
Signed-off-by: Jean-Pierre Huynh <jean-pierre.huynh@ounet.fr>
Upstream-commit: d31df921ad
Component: cli
2017-07-21 11:53:05 +01:00
2639 changed files with 55510 additions and 18917 deletions

View File

@ -1,63 +1,116 @@
# Changelog
# Changelog
For more information on the list of deprecated flags and APIs please have a look at
https://docs.docker.com/engine/deprecated/ where you can find the target removal dates
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.
## 18.03.0-ce (2018-03-DD)
## 18.01.0-ce (2018-01-10)
### Builder
* Fix files not being deleted if user-namespaces are enabled [moby/moby#35822](https://github.com/moby/moby/pull/35822)
- Add support for expanding environment-variables in `docker commit --change ...` [moby/moby#35582](https://github.com/moby/moby/pull/35582)
* Switch to -buildmode=pie [moby/moby#34369](https://github.com/moby/moby/pull/34369)
* Allow Dockerfile to be outside of build-context [docker/cli#886](https://github.com/docker/cli/pull/886)
* Builder: fix wrong cache hits building from tars [moby/moby#36329](https://github.com/moby/moby/pull/36329)
- Fixes files leaking to other images in a multi-stage build [moby/moby#36338](https://github.com/moby/moby/pull/36338)
### Client
* Return errors from client in stack deploy configs [docker/cli#757](https://github.com/docker/cli/pull/757)
- Fix description of filter flag in prune commands [docker/cli#774](https://github.com/docker/cli/pull/774)
+ Add "pid" to unsupported options list [docker/cli#768](https://github.com/docker/cli/pull/768)
+ Add support for experimental Cli configuration [docker/cli#758](https://github.com/docker/cli/pull/758)
+ Add support for generic resources to bash completion [docker/cli#749](https://github.com/docker/cli/pull/749)
- Fix error in zsh completion script for docker exec [docker/cli#751](https://github.com/docker/cli/pull/751)
+ Add a debug message when client closes websocket attach connection [moby/moby#35720](https://github.com/moby/moby/pull/35720)
- Fix bash completion for `"docker swarm"` [docker/cli#772](https://github.com/docker/cli/pull/772)
### Documentation
* Correct references to `--publish` long syntax in docs [docker/cli#746](https://github.com/docker/cli/pull/746)
* Corrected descriptions for MAC_ADMIN and MAC_OVERRIDE [docker/cli#761](https://github.com/docker/cli/pull/761)
* Updated developer doc to explain external CLI [moby/moby#35681](https://github.com/moby/moby/pull/35681)
- Fix `"on-failure"` restart policy being documented as "failure" [docker/cli#754](https://github.com/docker/cli/pull/754)
- Fix anchors to "Storage driver options" [docker/cli#748](https://github.com/docker/cli/pull/748)
### Experimental
+ Add kubernetes support to `docker stack` command [docker/cli#721](https://github.com/docker/cli/pull/721)
* Don't append the container id to custom directory checkpoints. [moby/moby#35694](https://github.com/moby/moby/pull/35694)
* Simplify the marshaling of compose types.Config [docker/cli#895](https://github.com/docker/cli/pull/895)
+ Add support for multiple composefile when deploying [docker/cli#569](https://github.com/docker/cli/pull/569)
- Fix broken Kubernetes stack flags [docker/cli#831](https://github.com/docker/cli/pull/831)
- Fix stack marshaling for Kubernetes [docker/cli#890](https://github.com/docker/cli/pull/890)
- Fix and simplify bash completion for service env, mounts and labels [docker/cli#682](https://github.com/docker/cli/pull/682)
- Fix `before` and `since` filter for `docker ps` [moby/moby#35938](https://github.com/moby/moby/pull/35938)
- Fix `--label-file` weird behavior [docker/cli#838](https://github.com/docker/cli/pull/838)
- Fix compilation of defaultCredentialStore() on unsupported platforms [docker/cli#872](https://github.com/docker/cli/pull/872)
* Improve and fix bash completion for images [docker/cli#717](https://github.com/docker/cli/pull/717)
+ Added check for empty source in bind mount [docker/cli#824](https://github.com/docker/cli/pull/824)
- Fix TLS from environment variables in client [moby/moby#36270](https://github.com/moby/moby/pull/36270)
* docker build now runs faster when registry-specific credential helper(s) are configured [docker/cli#840](https://github.com/docker/cli/pull/840)
* Update event filter zsh completion with `disable`, `enable`, `install` and `remove` [docker/cli#372](https://github.com/docker/cli/pull/372)
* Produce errors when empty ids are passed into inspect calls [moby/moby#36144](https://github.com/moby/moby/pull/36144)
* Marshall version for the k8s controller [docker/cli#891](https://github.com/docker/cli/pull/891)
* Set a non-zero timeout for HTTP client communication with plugin backend [docker/cli#883](https://github.com/docker/cli/pull/883)
+ Add DOCKER_TLS environment variable for --tls option [docker/cli#863](https://github.com/docker/cli/pull/863)
+ Add --template-driver option for secrets/configs [docker/cli#896](https://github.com/docker/cli/pull/896)
### Logging
* Fix daemon crash when using the GELF log driver over TCP when the GELF server goes down [moby/moby#35765](https://github.com/moby/moby/pull/35765)
- Fix awslogs batch size calculation for large logs [moby/moby#35726](https://github.com/moby/moby/pull/35726)
* AWS logs - don't add new lines to maximum sized events [moby/moby#36078](https://github.com/moby/moby/pull/36078)
* Move log validator logic after plugins are loaded [moby/moby#36306](https://github.com/moby/moby/pull/36306)
* Support a proxy in Splunk log driver [moby/moby#36220](https://github.com/moby/moby/pull/36220)
- Fix log tail with empty logs [moby/moby#36305](https://github.com/moby/moby/pull/36305)
### Networking
- Windows: Fix to allow docker service to start on Windows VM [docker/libnetwork#1916](https://github.com/docker/libnetwork/pull/1916)
- Fix for docker intercepting DNS requests on ICS network [docker/libnetwork#2014](https://github.com/docker/libnetwork/pull/2014)
+ Windows: Added a new network creation driver option [docker/libnetwork#2021](https://github.com/docker/libnetwork/pull/2021)
* Libnetwork revendoring [moby/moby#36137](https://github.com/moby/moby/pull/36137)
- Fix for deadlock on exit with Memberlist revendor [docker/libnetwork#2040](https://github.com/docker/libnetwork/pull/2040)
* Fix user specified ndots option [docker/libnetwork#2065](https://github.com/docker/libnetwork/pull/2065)
- Fix to use ContainerID for Windows instead of SandboxID [docker/libnetwork#2010](https://github.com/docker/libnetwork/pull/2010)
* Verify NetworkingConfig to make sure EndpointSettings is not nil [moby/moby#36077](https://github.com/moby/moby/pull/36077)
- Fix `DockerNetworkInternalMode` issue [moby/moby#36298](https://github.com/moby/moby/pull/36298)
- Fix race in attachable network attachment [moby/moby#36191](https://github.com/moby/moby/pull/36191)
- Fix timeout issue of `InspectNetwork` on AArch64 [moby/moby#36257](https://github.com/moby/moby/pull/36257)
* Verbose info is missing for partial overlay ID [moby/moby#35989](https://github.com/moby/moby/pull/35989)
* Update `FindNetwork` to address network name duplications [moby/moby#30897](https://github.com/moby/moby/pull/30897)
* Disallow attaching ingress network [docker/swarmkit#2523](https://github.com/docker/swarmkit/pull/2523)
### Runtime
* Validate Mount-specs on container start to prevent missing host-path [moby/moby#35833](https://github.com/moby/moby/pull/35833)
- Fix overlay2 storage driver inside a user namespace [moby/moby#35794](https://github.com/moby/moby/pull/35794)
* Zfs: fix busy error on container stop [moby/moby#35674](https://github.com/moby/moby/pull/35674)
- Fix health checks not using the container's working directory [moby/moby#35845](https://github.com/moby/moby/pull/35845)
- Fix VFS graph driver failure to initialize because of failure to setup fs quota [moby/moby#35827](https://github.com/moby/moby/pull/35827)
- Fix containerd events being processed twice [moby/moby#35896](https://github.com/moby/moby/pull/35896)
* Enable HotAdd for Windows [moby/moby#35414](https://github.com/moby/moby/pull/35414)
* LCOW: Graphdriver fix deadlock in hotRemoveVHDs [moby/moby#36114](https://github.com/moby/moby/pull/36114)
* LCOW: Regular mount if only one layer [moby/moby#36052](https://github.com/moby/moby/pull/36052)
* Remove interim env var LCOW_API_PLATFORM_IF_OMITTED [moby/moby#36269](https://github.com/moby/moby/pull/36269)
* Revendor Microsoft/opengcs @ v0.3.6 [moby/moby#36108](https://github.com/moby/moby/pull/36108)
- Fix issue of ExitCode and PID not show up in Task.Status.ContainerStatus [moby/moby#36150](https://github.com/moby/moby/pull/36150)
- Fix issue with plugin scanner going too deep [moby/moby#36119](https://github.com/moby/moby/pull/36119)
* Do not make graphdriver homes private mounts [moby/moby#36047](https://github.com/moby/moby/pull/36047)
* Do not recursive unmount on cleanup of zfs/btrfs [moby/moby#36237](https://github.com/moby/moby/pull/36237)
* Don't restore image if layer does not exist [moby/moby#36304](https://github.com/moby/moby/pull/36304)
* Adjust minimum API version for templated configs/secrets [moby/moby#36366](https://github.com/moby/moby/pull/36366)
* Bump containerd to 1.0.2 (cfd04396dc68220d1cecbe686a6cc3aa5ce3667c) [moby/moby#36308](https://github.com/moby/moby/pull/36308)
* Bump Golang to 1.9.4 [moby/moby#36243](https://github.com/moby/moby/pull/36243)
* Ensure daemon root is unmounted on shutdown [moby/moby#36107](https://github.com/moby/moby/pull/36107)
* Update runc to 6c55f98695e902427906eed2c799e566e3d3dfb5 [moby/moby#36222](https://github.com/moby/moby/pull/36222)
- Fix container cleanup on daemon restart [moby/moby#36249](https://github.com/moby/moby/pull/36249)
* Support SCTP port mapping (bump up API to v1.37) [moby/moby#33922](https://github.com/moby/moby/pull/33922)
* Support SCTP port mapping [docker/cli#278](https://github.com/docker/cli/pull/278)
- Fix Volumes property definition in ContainerConfig [moby/moby#35946](https://github.com/moby/moby/pull/35946)
* Bump moby and dependencies [docker/cli#829](https://github.com/docker/cli/pull/829)
* C.RWLayer: check for nil before use [moby/moby#36242](https://github.com/moby/moby/pull/36242)
+ Add `REMOVE` and `ORPHANED` to TaskState [moby/moby#36146](https://github.com/moby/moby/pull/36146)
- Fixed error detection using `IsErrNotFound` and `IsErrNotImplemented` for `ContainerStatPath`, `CopyFromContainer`, and `CopyToContainer` methods [moby/moby#35979](https://github.com/moby/moby/pull/35979)
+ Add an integration/internal/container helper package [moby/moby#36266](https://github.com/moby/moby/pull/36266)
+ Add canonical import path [moby/moby#36194](https://github.com/moby/moby/pull/36194)
+ Add/use container.Exec() to integration [moby/moby#36326](https://github.com/moby/moby/pull/36326)
- Fix "--node-generic-resource" singular/plural [moby/moby#36125](https://github.com/moby/moby/pull/36125)
* Daemon.cleanupContainer: nullify container RWLayer upon release [moby/moby#36160](https://github.com/moby/moby/pull/36160)
* Daemon: passdown the `--oom-kill-disable` option to containerd [moby/moby#36201](https://github.com/moby/moby/pull/36201)
* Display a warn message when there is binding ports and net mode is host [moby/moby#35510](https://github.com/moby/moby/pull/35510)
* Refresh containerd remotes on containerd restarted [moby/moby#36173](https://github.com/moby/moby/pull/36173)
* Set daemon root to use shared propagation [moby/moby#36096](https://github.com/moby/moby/pull/36096)
* Optimizations for recursive unmount [moby/moby#34379](https://github.com/moby/moby/pull/34379)
* Perform plugin mounts in the runtime [moby/moby#35829](https://github.com/moby/moby/pull/35829)
* Graphdriver: Fix RefCounter memory leak [moby/moby#36256](https://github.com/moby/moby/pull/36256)
* Use continuity fs package for volume copy [moby/moby#36290](https://github.com/moby/moby/pull/36290)
* Use proc/exe for reexec [moby/moby#36124](https://github.com/moby/moby/pull/36124)
+ Add API support for templated secrets and configs [moby/moby#33702](https://github.com/moby/moby/pull/33702) and [moby/moby#36366](https://github.com/moby/moby/pull/36366)
* Use rslave propagation for mounts from daemon root [moby/moby#36055](https://github.com/moby/moby/pull/36055)
+ Add /proc/keys to masked paths [moby/moby#36368](https://github.com/moby/moby/pull/36368)
* Bump Runc to 1.0.0-rc5 [moby/moby#36449](https://github.com/moby/moby/pull/36449)
- Fixes `runc exec` on big-endian architectures [moby/moby#36449](https://github.com/moby/moby/pull/36449)
* Use chroot when mount namespaces aren't provided [moby/moby#36449](https://github.com/moby/moby/pull/36449)
- Fix systemd slice expansion so that it could be consumed by cAdvisor [moby/moby#36449](https://github.com/moby/moby/pull/36449)
- Fix devices mounted with wrong uid/gid [moby/moby#36449](https://github.com/moby/moby/pull/36449)
### Swarm Mode
- Fix published ports not being updated if a service has the same number of host-mode published ports with Published Port 0 [docker/swarmkit#2376](https://github.com/docker/swarmkit/pull/2376)
* Make the task termination order deterministic [docker/swarmkit#2265](https://github.com/docker/swarmkit/pull/2265)
* Replace EC Private Key with PKCS#8 PEMs [docker/swarmkit#2246](https://github.com/docker/swarmkit/pull/2246)
* Fix IP overlap with empty EndpointSpec [docker/swarmkit #2505](https://github.com/docker/swarmkit/pull/2505)
* Add support for Support SCTP port mapping [docker/swarmkit#2298](https://github.com/docker/swarmkit/pull/2298)
* Do not reschedule tasks if only placement constraints change and are satisfied by the assigned node [docker/swarmkit#2496](https://github.com/docker/swarmkit/pull/2496)
* Ensure task reaper stopChan is closed no more than once [docker/swarmkit #2491](https://github.com/docker/swarmkit/pull/2491)
* Synchronization fixes [docker/swarmkit#2495](https://github.com/docker/swarmkit/pull/2495)
* Add log message to indicate message send retry if streaming unimplemented [docker/swarmkit#2483](https://github.com/docker/swarmkit/pull/2483)
* Debug logs for session, node events on dispatcher, heartbeats [docker/swarmkit#2486](https://github.com/docker/swarmkit/pull/2486)
+ Add swarm types to bash completion event type filter [docker/cli#888](https://github.com/docker/cli/pull/888)
- Fix issue where network inspect does not show Created time for networks in swarm scope [moby/moby#36095](https://github.com/moby/moby/pull/36095)

View File

@ -1 +1 @@
18.01.0-ce
18.03.0-ce-rc2

View File

@ -1,4 +1,12 @@
# if you want to ignore files created by your editor/tools,
# please consider a global .gitignore https://help.github.com/articles/ignoring-files
*.exe
*.exe~
*.orig
.*.swp
.DS_Store
Thumbs.db
.editorconfig
/build/
cli/winresources/rsrc_386.syso
cli/winresources/rsrc_amd64.syso

View File

@ -232,6 +232,7 @@ Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
Kai Qiang Wu (Kennan) <wkq5325@gmail.com> <wkqwu@cn.ibm.com>
Kamil Domański <kamil@domanski.co>
Kamjar Gerami <kami.gerami@gmail.com>
Kat Samperi <kat.samperi@gmail.com> <kizzie@users.noreply.github.com>
Ken Cochrane <kencochrane@gmail.com> <KenCochrane@gmail.com>
Ken Herner <kherner@progress.com> <chosenken@gmail.com>
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
@ -281,6 +282,7 @@ Martin Redmond <redmond.martin@gmail.com> <xgithub@redmond5.com>
Mary Anthony <mary.anthony@docker.com> <mary@docker.com>
Mary Anthony <mary.anthony@docker.com> <moxieandmore@gmail.com>
Mary Anthony <mary.anthony@docker.com> moxiegirl <mary@docker.com>
Mateusz Major <apkd@users.noreply.github.com>
Matt Bentley <matt.bentley@docker.com> <mbentley@mbentley.net>
Matt Schurenko <matt.schurenko@gmail.com>
Matt Williams <mattyw@me.com>
@ -397,6 +399,7 @@ Thatcher Peskens <thatcher@docker.com>
Thatcher Peskens <thatcher@docker.com> <thatcher@dotcloud.com>
Thatcher Peskens <thatcher@docker.com> <thatcher@gmx.net>
Thomas Gazagnaire <thomas@gazagnaire.org> <thomas@gazagnaire.com>
Thomas Krzero <thomas.kovatchitch@gmail.com>
Thomas Léveil <thomasleveil@gmail.com>
Thomas Léveil <thomasleveil@gmail.com> <thomasleveil@users.noreply.github.com>
Tibor Vass <teabee89@gmail.com> <tibor@docker.com>

View File

@ -17,6 +17,7 @@ Aidan Feldman <aidan.feldman@gmail.com>
Aidan Hobson Sayers <aidanhs@cantab.net>
AJ Bowen <aj@gandi.net>
Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Akim Demaille <akim.demaille@docker.com>
Alan Thompson <cloojure@gmail.com>
Albert Callarisa <shark234@gmail.com>
Aleksa Sarai <asarai@suse.de>
@ -107,6 +108,7 @@ Christophe Robin <crobin@nekoo.com>
Christophe Vidal <kriss@krizalys.com>
Christopher Biscardi <biscarch@sketcht.com>
Christopher Jones <tophj@linux.vnet.ibm.com>
Christy Perez <christy@linux.vnet.ibm.com>
Chun Chen <ramichen@tencent.com>
Clinton Kitson <clintonskitson@gmail.com>
Coenraad Loubser <coenraad@wish.org.za>
@ -178,6 +180,7 @@ Eric-Olivier Lamey <eo@lamey.me>
Erica Windisch <erica@windisch.us>
Erik Hollensbe <github@hollensbe.org>
Erik St. Martin <alakriti@gmail.com>
Ethan Haynes <ethanhaynes@alumni.harvard.edu>
Eugene Yakubovich <eugene.yakubovich@coreos.com>
Evan Allrich <evan@unguku.com>
Evan Hazlett <ejhazlett@gmail.com>
@ -234,6 +237,7 @@ Ilya Khlopotov <ilya.khlopotov@gmail.com>
Ilya Sotkov <ilya@sotkov.com>
Isabel Jimenez <contact.isabeljimenez@gmail.com>
Ivan Grcic <igrcic@gmail.com>
Ivan Markin <sw@nogoegst.net>
Jacob Atzen <jacob@jacobatzen.dk>
Jacob Tomlinson <jacob@tom.linson.uk>
Jaivish Kothari <janonymous.codevulture@gmail.com>
@ -314,6 +318,7 @@ Kai Qiang Wu (Kennan) <wkq5325@gmail.com>
Kara Alexandra <kalexandra@us.ibm.com>
Kareem Khazem <karkhaz@karkhaz.com>
Karthik Nayak <Karthik.188@gmail.com>
Kat Samperi <kat.samperi@gmail.com>
Katie McLaughlin <katie@glasnt.com>
Ke Xu <leonhartx.k@gmail.com>
Kei Ohmura <ohmura.kei@gmail.com>
@ -380,6 +385,7 @@ Mark Oates <fl0yd@me.com>
Martin Mosegaard Amdisen <martin.amdisen@praqma.com>
Mary Anthony <mary.anthony@docker.com>
Mason Malone <mason.malone@gmail.com>
Mateusz Major <apkd@users.noreply.github.com>
Matt Gucci <matt9ucci@gmail.com>
Matt Robenolt <matt@ydekproductions.com>
Matthew Heon <mheon@redhat.com>
@ -420,6 +426,7 @@ Moorthy RS <rsmoorthy@gmail.com>
Morgan Bauer <mbauer@us.ibm.com>
Moysés Borges <moysesb@gmail.com>
Mrunal Patel <mrunalp@gmail.com>
muicoder <muicoder@gmail.com>
Muthukumar R <muthur@gmail.com>
Máximo Cuadros <mcuadros@gmail.com>
Nace Oroz <orkica@gmail.com>
@ -520,6 +527,7 @@ Shukui Yang <yangshukui@huawei.com>
Sian Lerk Lau <kiawin@gmail.com>
Sidhartha Mani <sidharthamn@gmail.com>
sidharthamani <sid@rancher.com>
Silvin Lubecki <silvin.lubecki@docker.com>
Simei He <hesimei@zju.edu.cn>
Simon Ferquel <simon.ferquel@docker.com>
Sindhu S <sindhus@live.in>
@ -538,6 +546,7 @@ Steve Durrheimer <s.durrheimer@gmail.com>
Steven Burgess <steven.a.burgess@hotmail.com>
Subhajit Ghosh <isubuz.g@gmail.com>
Sun Jianbo <wonderflow.sun@gmail.com>
Sungwon Han <sungwon.han@navercorp.com>
Sven Dowideit <SvenDowideit@home.org.au>
Sylvain Baubeau <sbaubeau@redhat.com>
Sébastien HOUZÉ <cto@verylastroom.com>
@ -546,6 +555,7 @@ TAGOMORI Satoshi <tagomoris@gmail.com>
Taylor Jones <monitorjbl@gmail.com>
Thatcher Peskens <thatcher@docker.com>
Thomas Gazagnaire <thomas@gazagnaire.org>
Thomas Krzero <thomas.kovatchitch@gmail.com>
Thomas Leonard <thomas.leonard@docker.com>
Thomas Léveil <thomasleveil@gmail.com>
Thomas Riccardi <riccardi@systran.fr>
@ -594,6 +604,7 @@ Wang Long <long.wanglong@huawei.com>
Wang Ping <present.wp@icloud.com>
Wang Xing <hzwangxing@corp.netease.com>
Wang Yuexiao <wang.yuexiao@zte.com.cn>
Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Wayne Song <wsong@docker.com>
Wen Cheng Ma <wenchma@cn.ibm.com>
Wenzhi Liang <wenzhi.liang@gmail.com>

View File

@ -1,6 +1,6 @@
# Docker maintainers file
#
# This file describes who runs the docker/docker project and how.
# This file describes who runs the docker/cli project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
@ -21,23 +21,12 @@
# a subsystem, they are responsible for doing so and holding the
# subsystem maintainers accountable. If ownership is unclear, they are the de facto owners.
# For each release (including minor releases), a "release captain" is assigned from the
# pool of core maintainers. Rotation is encouraged across all maintainers, to ensure
# the release process is clear and up-to-date.
people = [
"aaronlehmann",
"albers",
"aluzzardi",
"anusha",
"cpuguy83",
"crosbymichael",
"dnephin",
"ehazlett",
"johnstep",
"justincormack",
"mavenugo",
"mlaventure",
"stevvooe",
"tibor",
"tonistiigi",
@ -67,7 +56,6 @@
# - close an issue or pull request when it's inappropriate or off-topic
people = [
"ehazlett",
"programmerq",
"thajeztah"
]
@ -90,41 +78,16 @@
Email = "github@albersweb.de"
GitHub = "albers"
[people.aluzzardi]
Name = "Andrea Luzzardi"
Email = "al@docker.com"
GitHub = "aluzzardi"
[people.anusha]
Name = "Anusha Ragunathan"
Email = "anusha@docker.com"
GitHub = "anusha-ragunathan"
[people.cpuguy83]
Name = "Brian Goff"
Email = "cpuguy83@gmail.com"
GitHub = "cpuguy83"
[people.crosbymichael]
Name = "Michael Crosby"
Email = "crosbymichael@gmail.com"
GitHub = "crosbymichael"
[people.dnephin]
Name = "Daniel Nephin"
Email = "dnephin@gmail.com"
GitHub = "dnephin"
[people.ehazlett]
Name = "Evan Hazlett"
Email = "ejhazlett@gmail.com"
GitHub = "ehazlett"
[people.johnstep]
Name = "John Stephens"
Email = "johnstep@docker.com"
GitHub = "johnstep"
[people.justincormack]
Name = "Justin Cormack"
Email = "justin.cormack@docker.com"
@ -135,15 +98,10 @@
Email = "misty@docker.com"
GitHub = "mistyhacks"
[people.mlaventure]
Name = "Kenfe-Mickaël Laventure"
Email = "mickael.laventure@docker.com"
GitHub = "mlaventure"
[people.shykes]
Name = "Solomon Hykes"
Email = "solomon@docker.com"
GitHub = "shykes"
[people.programmerq]
Name = "Jeff Anderson"
Email = "jeff@docker.com"
GitHub = "programmerq"
[people.stevvooe]
Name = "Stephen Day"

View File

@ -51,7 +51,8 @@ watch: ## monitor file changes and run go test
./scripts/test/watch
vendor: vendor.conf ## check that vendor matches vendor.conf
vndr 2> /dev/null
rm -rf vendor
bash -c 'vndr |& grep -v -i clone'
scripts/validate/check-git-diff vendor
.PHONY: authors

View File

@ -1 +1 @@
18.01.0-ce
18.03.0-ce-rc2

View File

@ -5,16 +5,22 @@ import (
"net"
"net/http"
"os"
"path/filepath"
"runtime"
"time"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/config"
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
cliflags "github.com/docker/cli/cli/flags"
manifeststore "github.com/docker/cli/cli/manifest/store"
registryclient "github.com/docker/cli/cli/registry/client"
"github.com/docker/cli/cli/trust"
dopts "github.com/docker/cli/opts"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/client"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
@ -45,6 +51,8 @@ type Cli interface {
ClientInfo() ClientInfo
NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
DefaultVersion() string
ManifestStore() manifeststore.Store
RegistryClient(bool) registryclient.RegistryClient
}
// DockerCli is an instance the docker command line client.
@ -114,6 +122,21 @@ func (cli *DockerCli) ClientInfo() ClientInfo {
return cli.clientInfo
}
// ManifestStore returns a store for local manifests
func (cli *DockerCli) ManifestStore() manifeststore.Store {
// TODO: support override default location from config file
return manifeststore.NewStore(filepath.Join(config.Dir(), "manifests"))
}
// RegistryClient returns a client for communicating with a Docker distribution
// registry
func (cli *DockerCli) RegistryClient(allowInsecure bool) registryclient.RegistryClient {
resolver := func(ctx context.Context, index *registrytypes.IndexInfo) types.AuthConfig {
return ResolveAuthConfig(ctx, cli, index)
}
return registryclient.NewRegistryClient(resolver, UserAgent(), allowInsecure)
}
// Initialize the dockerCli runs initialization that must happen after command
// line flags are parsed.
func (cli *DockerCli) Initialize(opts *cliflags.ClientOptions) error {
@ -277,12 +300,12 @@ func newHTTPClient(host string, tlsOptions *tlsconfig.Options) (*http.Client, er
Timeout: 30 * time.Second,
}).DialContext,
}
proto, addr, _, err := client.ParseHost(host)
hostURL, err := client.ParseHostURL(host)
if err != nil {
return nil, err
}
sockets.ConfigureTransport(tr, proto, addr)
sockets.ConfigureTransport(tr, hostURL.Scheme, hostURL.Host)
return &http.Client{
Transport: tr,

View File

@ -8,6 +8,7 @@ import (
"github.com/docker/cli/cli/command/config"
"github.com/docker/cli/cli/command/container"
"github.com/docker/cli/cli/command/image"
"github.com/docker/cli/cli/command/manifest"
"github.com/docker/cli/cli/command/network"
"github.com/docker/cli/cli/command/node"
"github.com/docker/cli/cli/command/plugin"
@ -39,12 +40,15 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
image.NewImageCommand(dockerCli),
image.NewBuildCommand(dockerCli),
// node
node.NewNodeCommand(dockerCli),
// manifest
manifest.NewManifestCommand(dockerCli),
// network
network.NewNetworkCommand(dockerCli),
// node
node.NewNodeCommand(dockerCli),
// plugin
plugin.NewPluginCommand(dockerCli),

View File

@ -16,9 +16,10 @@ import (
)
type createOptions struct {
name string
file string
labels opts.ListOpts
name string
templateDriver string
file string
labels opts.ListOpts
}
func newConfigCreateCommand(dockerCli command.Cli) *cobra.Command {
@ -28,7 +29,7 @@ func newConfigCreateCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "create [OPTIONS] CONFIG file|-",
Short: "Create a configuration file from a file or STDIN as content",
Short: "Create a config from a file or STDIN",
Args: cli.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
createOpts.name = args[0]
@ -38,6 +39,8 @@ func newConfigCreateCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.VarP(&createOpts.labels, "label", "l", "Config labels")
flags.StringVar(&createOpts.templateDriver, "template-driver", "", "Template driver")
flags.SetAnnotation("driver", "version", []string{"1.37"})
return cmd
}
@ -68,7 +71,11 @@ func runConfigCreate(dockerCli command.Cli, options createOptions) error {
},
Data: configData,
}
if options.templateDriver != "" {
spec.Templating = &swarm.Driver{
Name: options.templateDriver,
}
}
r, err := client.ConfigCreate(ctx, spec)
if err != nil {
return err

View File

@ -82,14 +82,21 @@ func TestConfigCreateWithLabels(t *testing.T) {
}
name := "foo"
data, err := ioutil.ReadFile(filepath.Join("testdata", configDataFile))
assert.NoError(t, err)
expected := swarm.ConfigSpec{
Annotations: swarm.Annotations{
Name: name,
Labels: expectedLabels,
},
Data: data,
}
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if spec.Name != name {
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
if !reflect.DeepEqual(spec.Labels, expectedLabels) {
return types.ConfigCreateResponse{}, errors.Errorf("expected labels %v, got %v", expectedLabels, spec.Labels)
if !reflect.DeepEqual(spec, expected) {
return types.ConfigCreateResponse{}, errors.Errorf("expected %+v, got %+v", expected, spec)
}
return types.ConfigCreateResponse{
@ -105,3 +112,32 @@ func TestConfigCreateWithLabels(t *testing.T) {
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
}
func TestConfigCreateWithTemplatingDriver(t *testing.T) {
expectedDriver := &swarm.Driver{
Name: "template-driver",
}
name := "foo"
cli := test.NewFakeCli(&fakeClient{
configCreateFunc: func(spec swarm.ConfigSpec) (types.ConfigCreateResponse, error) {
if spec.Name != name {
return types.ConfigCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
if spec.Templating.Name != expectedDriver.Name {
return types.ConfigCreateResponse{}, errors.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
}
return types.ConfigCreateResponse{
ID: "ID-" + spec.Name,
}, nil
},
})
cmd := newConfigCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)})
cmd.Flags().Set("template-driver", expectedDriver.Name)
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
}

View File

@ -21,7 +21,7 @@ func newConfigInspectCommand(dockerCli command.Cli) *cobra.Command {
opts := inspectOptions{}
cmd := &cobra.Command{
Use: "inspect [OPTIONS] CONFIG [CONFIG...]",
Short: "Display detailed information on one or more configuration files",
Short: "Display detailed information on one or more configs",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.names = args

View File

@ -19,7 +19,7 @@ func newConfigRemoveCommand(dockerCli command.Cli) *cobra.Command {
return &cobra.Command{
Use: "rm CONFIG [CONFIG...]",
Aliases: []string{"remove"},
Short: "Remove one or more configuration files",
Short: "Remove one or more configs",
Args: cli.RequiresMinArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts := removeOptions{

View File

@ -1,12 +1,14 @@
package container
import (
"fmt"
"io"
"net/http/httputil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/signal"
"github.com/pkg/errors"
@ -66,6 +68,9 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
ctx := context.Background()
client := dockerCli.Client()
// request channel to wait for client
resultC, errC := client.ContainerWait(ctx, opts.container, "")
c, err := inspectContainerAndCheckState(ctx, client, opts.container)
if err != nil {
return err
@ -140,7 +145,24 @@ func runAttach(dockerCli command.Cli, opts *attachOptions) error {
if errAttach != nil {
return errAttach
}
return getExitStatus(ctx, dockerCli.Client(), opts.container)
return getExitStatus(errC, resultC)
}
func getExitStatus(errC <-chan error, resultC <-chan container.ContainerWaitOKBody) error {
select {
case result := <-resultC:
if result.Error != nil {
return fmt.Errorf(result.Error.Message)
}
if result.StatusCode != 0 {
return cli.StatusError{StatusCode: int(result.StatusCode)}
}
case err := <-errC:
return err
}
return nil
}
func resizeTTY(ctx context.Context, dockerCli command.Cli, containerID string) {
@ -157,19 +179,3 @@ func resizeTTY(ctx context.Context, dockerCli command.Cli, containerID string) {
logrus.Debugf("Error monitoring TTY size: %s", err)
}
}
func getExitStatus(ctx context.Context, apiclient client.ContainerAPIClient, containerID string) error {
container, err := apiclient.ContainerInspect(ctx, containerID)
if err != nil {
// If we can't connect, then the daemon probably died.
if !client.IsErrConnectionFailed(err) {
return err
}
return cli.StatusError{StatusCode: -1}
}
status := container.State.ExitCode
if status != 0 {
return cli.StatusError{StatusCode: status}
}
return nil
}

View File

@ -1,6 +1,7 @@
package container
import (
"fmt"
"io/ioutil"
"testing"
@ -8,9 +9,9 @@ import (
"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/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
func TestNewAttachCommandErrors(t *testing.T) {
@ -78,40 +79,50 @@ func TestNewAttachCommandErrors(t *testing.T) {
}
func TestGetExitStatus(t *testing.T) {
containerID := "the exec id"
expecatedErr := errors.New("unexpected error")
var (
expectedErr = fmt.Errorf("unexpected error")
errC = make(chan error, 1)
resultC = make(chan container.ContainerWaitOKBody, 1)
)
testcases := []struct {
inspectError error
exitCode int
result *container.ContainerWaitOKBody
err error
expectedError error
}{
{
inspectError: nil,
exitCode: 0,
result: &container.ContainerWaitOKBody{
StatusCode: 0,
},
},
{
inspectError: expecatedErr,
expectedError: expecatedErr,
err: expectedErr,
expectedError: expectedErr,
},
{
exitCode: 15,
result: &container.ContainerWaitOKBody{
Error: &container.ContainerWaitOKBodyError{
expectedErr.Error(),
},
},
expectedError: expectedErr,
},
{
result: &container.ContainerWaitOKBody{
StatusCode: 15,
},
expectedError: cli.StatusError{StatusCode: 15},
},
}
for _, testcase := range testcases {
client := &fakeClient{
inspectFunc: func(id string) (types.ContainerJSON, error) {
assert.Equal(t, containerID, id)
return types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{
State: &types.ContainerState{ExitCode: testcase.exitCode},
},
}, testcase.inspectError
},
if testcase.err != nil {
errC <- testcase.err
}
err := getExitStatus(context.Background(), client, containerID)
if testcase.result != nil {
resultC <- *testcase.result
}
err := getExitStatus(errC, resultC)
assert.Equal(t, testcase.expectedError, err)
}
}

View File

@ -16,11 +16,22 @@ type fakeClient struct {
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)
containerStartFunc func(container string, options types.ContainerStartOptions) 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)
waitFunc func(string) (<-chan container.ContainerWaitOKBody, <-chan error)
containerListFunc func(types.ContainerListOptions) ([]types.Container, error)
Version string
}
func (f *fakeClient) ContainerList(_ context.Context, options types.ContainerListOptions) ([]types.Container, error) {
if f.containerListFunc != nil {
return f.containerListFunc(options)
}
return []types.Container{}, nil
}
func (f *fakeClient) ContainerInspect(_ context.Context, containerID string) (types.ContainerJSON, error) {
@ -95,3 +106,21 @@ func (f *fakeClient) ContainerLogs(_ context.Context, container string, options
}
return nil, nil
}
func (f *fakeClient) ClientVersion() string {
return f.Version
}
func (f *fakeClient) ContainerWait(_ context.Context, container string, _ container.WaitCondition) (<-chan container.ContainerWaitOKBody, <-chan error) {
if f.waitFunc != nil {
return f.waitFunc(container)
}
return nil, nil
}
func (f *fakeClient) ContainerStart(_ context.Context, container string, options types.ContainerStartOptions) error {
if f.containerStartFunc != nil {
return f.containerStartFunc(container, options)
}
return nil
}

View File

@ -3,6 +3,7 @@ package container
import (
"io"
"io/ioutil"
"os"
"runtime"
"strings"
"testing"
@ -111,6 +112,33 @@ func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.
testutil.ErrorContains(t, err, destDir.Join("missing"))
}
func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) {
srcFile := fs.NewFile(t, t.Name())
defer srcFile.Remove()
options := copyOptions{
source: srcFile.Path() + string(os.PathSeparator),
destination: "container:/path",
}
cli := test.NewFakeCli(&fakeClient{})
err := runCopy(cli, options)
testutil.ErrorContains(t, err, "not a directory")
}
func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) {
options := copyOptions{
source: "/does/not/exist",
destination: "container:/path",
}
cli := test.NewFakeCli(&fakeClient{})
err := runCopy(cli, options)
expected := "no such file or directory"
if runtime.GOOS == "windows" {
expected = "cannot find the file specified"
}
testutil.ErrorContains(t, err, expected)
}
func TestSplitCpArg(t *testing.T) {
var testcases = []struct {
doc string

View File

@ -0,0 +1,165 @@
package container
import (
"fmt"
"io/ioutil"
"testing"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/gotestyourself/gotestyourself/golden"
)
func TestContainerListErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
containerListFunc func(types.ContainerListOptions) ([]types.Container, error)
expectedError string
}{
{
flags: map[string]string{
"format": "{{invalid}}",
},
expectedError: `function "invalid" not defined`,
},
{
flags: map[string]string{
"format": "{{join}}",
},
expectedError: `wrong number of args for join`,
},
{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return nil, fmt.Errorf("error listing containers")
},
expectedError: "error listing containers",
},
}
for _, tc := range testCases {
cmd := newListCommand(
test.NewFakeCli(&fakeClient{
containerListFunc: tc.containerListFunc,
}),
)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestContainerListWithoutFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1"),
*Container("c2", WithName("foo")),
*Container("c3", WithPort(80, 80, TCP), WithPort(81, 81, TCP), WithPort(82, 82, TCP)),
*Container("c4", WithPort(81, 81, UDP)),
*Container("c5", WithPort(82, 82, IP("8.8.8.8"), TCP)),
}, nil
},
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format.golden")
}
func TestContainerListNoTrunc(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1"),
*Container("c2", WithName("foo/bar")),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("no-trunc", "true")
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format-no-trunc.golden")
}
// Test for GitHub issue docker/docker#21772
func TestContainerListNamesMultipleTime(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1"),
*Container("c2", WithName("foo/bar")),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Names}} {{.Names}}")
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-name-name.golden")
}
// Test for GitHub issue docker/docker#30291
func TestContainerListFormatTemplateWithArg(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1", WithLabel("some.label", "value")),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`)
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-with-arg.golden")
}
func TestContainerListFormatSizeSetsOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
assert.True(t, options.Size)
return []types.Container{}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", `{{.Size}}`)
assert.NoError(t, cmd.Execute())
}
func TestContainerListWithConfigFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1", WithLabel("some.label", "value")),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
}, nil
},
})
cli.SetConfigFile(&configfile.ConfigFile{
PsFormat: "{{ .Names }} {{ .Image }} {{ .Labels }}",
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-with-config-format.golden")
}
func TestContainerListWithFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(_ types.ContainerListOptions) ([]types.Container, error) {
return []types.Container{
*Container("c1", WithLabel("some.label", "value")),
*Container("c2", WithName("foo/bar"), WithLabel("foo", "bar")),
}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{ .Names }} {{ .Image }} {{ .Labels }}")
assert.NoError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-with-format.golden")
}

View File

@ -145,7 +145,7 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
expose: opts.NewListOpts(nil),
extraHosts: opts.NewListOpts(opts.ValidateExtraHost),
groupAdd: opts.NewListOpts(nil),
labels: opts.NewListOpts(opts.ValidateEnv),
labels: opts.NewListOpts(nil),
labelsFile: opts.NewListOpts(nil),
linkLocalIPs: opts.NewListOpts(nil),
links: opts.NewListOpts(opts.ValidateLink),
@ -410,7 +410,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions) (*containerConfig, err
}
// collect all the environment variables for the container
envVariables, err := opts.ReadKVStrings(copts.envFile.GetAll(), copts.env.GetAll())
envVariables, err := opts.ReadKVEnvStrings(copts.envFile.GetAll(), copts.env.GetAll())
if err != nil {
return nil, err
}

View File

@ -0,0 +1,25 @@
package container
import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/stretchr/testify/assert"
)
func TestRunLabel(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(_ *container.Config, _ *container.HostConfig, _ *network.NetworkingConfig, _ string) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{
ID: "id",
}, nil
},
Version: "1.36",
})
cmd := NewRunCommand(cli)
cmd.Flags().Set("detach", "true")
cmd.SetArgs([]string{"--label", "foo", "busybox"})
assert.NoError(t, cmd.Execute())
}

View File

@ -0,0 +1,2 @@
c1 c1
c2 c2

View File

@ -0,0 +1,2 @@
c1 value
c2

View File

@ -0,0 +1,2 @@
c1 busybox:latest some.label=value
c2 busybox:latest foo=bar

View File

@ -0,0 +1,2 @@
c1 busybox:latest some.label=value
c2 busybox:latest foo=bar

View File

@ -0,0 +1,3 @@
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
container_id busybox:latest "top" Less than a second ago Up 1 second c1
container_id busybox:latest "top" Less than a second ago Up 1 second c2,foo/bar

View File

@ -0,0 +1,6 @@
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
container_id busybox:latest "top" Less than a second ago Up 1 second c1
container_id busybox:latest "top" Less than a second ago Up 1 second c2
container_id busybox:latest "top" Less than a second ago Up 1 second 80-82/tcp c3
container_id busybox:latest "top" Less than a second ago Up 1 second 81/udp c4
container_id busybox:latest "top" Less than a second ago Up 1 second 8.8.8.8:82->82/tcp c5

View File

@ -37,7 +37,12 @@ func waitExitOrRemoved(ctx context.Context, dockerCli command.Cli, containerID s
go func() {
select {
case result := <-resultC:
statusC <- int(result.StatusCode)
if result.Error != nil {
logrus.Errorf("Error waiting for container: %v", result.Error.Message)
statusC <- 125
} else {
statusC <- int(result.StatusCode)
}
case err := <-errC:
logrus.Errorf("error waiting for container: %v", err)
statusC <- 125

View File

@ -0,0 +1,69 @@
package container
import (
"strings"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types/container"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
func waitFn(cid string) (<-chan container.ContainerWaitOKBody, <-chan error) {
resC := make(chan container.ContainerWaitOKBody)
errC := make(chan error, 1)
var res container.ContainerWaitOKBody
go func() {
switch {
case strings.Contains(cid, "exit-code-42"):
res.StatusCode = 42
resC <- res
case strings.Contains(cid, "non-existent"):
err := errors.Errorf("No such container: %v", cid)
errC <- err
case strings.Contains(cid, "wait-error"):
res.Error = &container.ContainerWaitOKBodyError{Message: "removal failed"}
resC <- res
default:
// normal exit
resC <- res
}
}()
return resC, errC
}
func TestWaitExitOrRemoved(t *testing.T) {
testcases := []struct {
cid string
exitCode int
}{
{
cid: "normal-container",
exitCode: 0,
},
{
cid: "give-me-exit-code-42",
exitCode: 42,
},
{
cid: "i-want-a-wait-error",
exitCode: 125,
},
{
cid: "non-existent-container-id",
exitCode: 125,
},
}
client := test.NewFakeCli(&fakeClient{waitFunc: waitFn, Version: api.DefaultVersion})
for _, testcase := range testcases {
statusC := waitExitOrRemoved(context.Background(), client, testcase.cid, true)
exitCode := <-statusC
assert.Equal(t, testcase.exitCode, exitCode)
}
}

View File

@ -642,9 +642,12 @@ func TestDisplayablePorts(t *testing.T) {
PublicPort: 1024,
PrivatePort: 80,
Type: "udp",
}, {
PrivatePort: 12345,
Type: "sctp",
},
},
"80/tcp, 80/udp, 1024/tcp, 1024/udp, 1.1.1.1:1024->80/tcp, 1.1.1.1:1024->80/udp, 2.1.1.1:1024->80/tcp, 2.1.1.1:1024->80/udp, 1.1.1.1:80->1024/tcp, 1.1.1.1:80->1024/udp, 2.1.1.1:80->1024/tcp, 2.1.1.1:80->1024/udp",
"80/tcp, 80/udp, 1024/tcp, 1024/udp, 12345/sctp, 1.1.1.1:1024->80/tcp, 1.1.1.1:1024->80/udp, 2.1.1.1:1024->80/tcp, 2.1.1.1:1024->80/udp, 1.1.1.1:80->1024/tcp, 1.1.1.1:80->1024/udp, 2.1.1.1:80->1024/tcp, 2.1.1.1:80->1024/udp",
},
}

View File

@ -14,7 +14,7 @@ import (
)
const (
defaultNodeTableFormat = "table {{.ID}} {{if .Self}}*{{else}} {{ end }}\t{{.Hostname}}\t{{.Status}}\t{{.Availability}}\t{{.ManagerStatus}}"
defaultNodeTableFormat = "table {{.ID}} {{if .Self}}*{{else}} {{ end }}\t{{.Hostname}}\t{{.Status}}\t{{.Availability}}\t{{.ManagerStatus}}\t{{.EngineVersion}}"
nodeInspectPrettyTemplate Format = `ID: {{.ID}}
{{- if .Name }}
Name: {{.Name}}
@ -75,6 +75,7 @@ TLS Info:
hostnameHeader = "HOSTNAME"
availabilityHeader = "AVAILABILITY"
managerStatusHeader = "MANAGER STATUS"
engineVersionHeader = "ENGINE VERSION"
tlsStatusHeader = "TLS STATUS"
)
@ -115,6 +116,7 @@ func NodeWrite(ctx Context, nodes []swarm.Node, info types.Info) error {
"Status": statusHeader,
"Availability": availabilityHeader,
"ManagerStatus": managerStatusHeader,
"EngineVersion": engineVersionHeader,
"TLSStatus": tlsStatusHeader,
}
nodeCtx := nodeContext{}
@ -176,6 +178,10 @@ func (c *nodeContext) TLSStatus() string {
return "Needs Rotation"
}
func (c *nodeContext) EngineVersion() string {
return c.n.Description.Engine.EngineVersion
}
// NodeInspectWrite renders the context for a list of nodes
func NodeInspectWrite(ctx Context, refs []string, getRef inspect.GetRefFunc) error {
if ctx.Format != nodeInspectPrettyTemplate {

View File

@ -74,10 +74,10 @@ func TestNodeContextWrite(t *testing.T) {
// Table format
{
context: Context{Format: NewNodeFormat("table", false)},
expected: `ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
nodeID1 foobar_baz Foo Drain Leader
nodeID2 foobar_bar Bar Active Reachable
nodeID3 foobar_boo Boo Active ` + "\n", // (to preserve whitespace)
expected: `ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
nodeID1 foobar_baz Foo Drain Leader 18.03.0-ce
nodeID2 foobar_bar Bar Active Reachable 1.2.3
nodeID3 foobar_boo Boo Active ` + "\n", // (to preserve whitespace)
clusterInfo: swarm.ClusterInfo{TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}},
},
{
@ -172,6 +172,7 @@ foobar_boo Unknown
Description: swarm.NodeDescription{
Hostname: "foobar_baz",
TLSInfo: swarm.TLSInfo{TrustRoot: "no"},
Engine: swarm.EngineDescription{EngineVersion: "18.03.0-ce"},
},
Status: swarm.NodeStatus{State: swarm.NodeState("foo")},
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("drain")},
@ -182,6 +183,7 @@ foobar_boo Unknown
Description: swarm.NodeDescription{
Hostname: "foobar_bar",
TLSInfo: swarm.TLSInfo{TrustRoot: "hi"},
Engine: swarm.EngineDescription{EngineVersion: "1.2.3"},
},
Status: swarm.NodeStatus{State: swarm.NodeState("bar")},
Spec: swarm.NodeSpec{Availability: swarm.NodeAvailability("active")},
@ -215,17 +217,17 @@ func TestNodeContextWriteJSON(t *testing.T) {
}{
{
expected: []map[string]interface{}{
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "1.2.3"},
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": ""},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
},
info: types.Info{},
},
{
expected: []map[string]interface{}{
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Ready"},
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation"},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown"},
{"Availability": "", "Hostname": "foobar_baz", "ID": "nodeID1", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Ready", "EngineVersion": "1.2.3"},
{"Availability": "", "Hostname": "foobar_bar", "ID": "nodeID2", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Needs Rotation", "EngineVersion": ""},
{"Availability": "", "Hostname": "foobar_boo", "ID": "nodeID3", "ManagerStatus": "", "Status": "", "Self": false, "TLSStatus": "Unknown", "EngineVersion": "18.03.0-ce"},
},
info: types.Info{
Swarm: swarm.Info{
@ -240,9 +242,9 @@ func TestNodeContextWriteJSON(t *testing.T) {
for _, testcase := range cases {
nodes := []swarm.Node{
{ID: "nodeID1", Description: swarm.NodeDescription{Hostname: "foobar_baz", TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}}},
{ID: "nodeID1", Description: swarm.NodeDescription{Hostname: "foobar_baz", TLSInfo: swarm.TLSInfo{TrustRoot: "hi"}, Engine: swarm.EngineDescription{EngineVersion: "1.2.3"}}},
{ID: "nodeID2", Description: swarm.NodeDescription{Hostname: "foobar_bar", TLSInfo: swarm.TLSInfo{TrustRoot: "no"}}},
{ID: "nodeID3", Description: swarm.NodeDescription{Hostname: "foobar_boo"}},
{ID: "nodeID3", Description: swarm.NodeDescription{Hostname: "foobar_boo", Engine: swarm.EngineDescription{EngineVersion: "18.03.0-ce"}}},
}
out := bytes.NewBufferString("")
err := NodeWrite(Context{Format: "{{json .}}", Output: out}, nodes, testcase.info)

View File

@ -2,6 +2,7 @@ package formatter
import (
"fmt"
"sort"
"strings"
"time"
@ -520,19 +521,95 @@ func (c *serviceContext) Image() string {
return image
}
type portRange struct {
pStart uint32
pEnd uint32
tStart uint32
tEnd uint32
protocol swarm.PortConfigProtocol
}
func (pr portRange) String() string {
var (
pub string
tgt string
)
if pr.pEnd > pr.pStart {
pub = fmt.Sprintf("%d-%d", pr.pStart, pr.pEnd)
} else {
pub = fmt.Sprintf("%d", pr.pStart)
}
if pr.tEnd > pr.tStart {
tgt = fmt.Sprintf("%d-%d", pr.tStart, pr.tEnd)
} else {
tgt = fmt.Sprintf("%d", pr.tStart)
}
return fmt.Sprintf("*:%s->%s/%s", pub, tgt, pr.protocol)
}
// Ports formats published ports on the ingress network for output.
//
// Where possible, ranges are grouped to produce a compact output:
// - multiple ports mapped to a single port (80->80, 81->80); is formatted as *:80-81->80
// - multiple consecutive ports on both sides; (80->80, 81->81) are formatted as: *:80-81->80-81
//
// The above should not be grouped together, i.e.:
// - 80->80, 81->81, 82->80 should be presented as : *:80-81->80-81, *:82->80
//
// TODO improve:
// - combine non-consecutive ports mapped to a single port (80->80, 81->80, 84->80, 86->80, 87->80); to be printed as *:80-81,84,86-87->80
// - combine tcp and udp mappings if their port-mapping is exactly the same (*:80-81->80-81/tcp+udp instead of *:80-81->80-81/tcp, *:80-81->80-81/udp)
func (c *serviceContext) Ports() string {
if c.service.Endpoint.Ports == nil {
return ""
}
pr := portRange{}
ports := []string{}
for _, pConfig := range c.service.Endpoint.Ports {
if pConfig.PublishMode == swarm.PortConfigPublishModeIngress {
ports = append(ports, fmt.Sprintf("*:%d->%d/%s",
pConfig.PublishedPort,
pConfig.TargetPort,
pConfig.Protocol,
))
sort.Sort(byProtocolAndPublishedPort(c.service.Endpoint.Ports))
for _, p := range c.service.Endpoint.Ports {
if p.PublishMode == swarm.PortConfigPublishModeIngress {
prIsRange := pr.tEnd != pr.tStart
tOverlaps := p.TargetPort <= pr.tEnd
// Start a new port-range if:
// - the protocol is different from the current port-range
// - published or target port are not consecutive to the current port-range
// - the current port-range is a _range_, and the target port overlaps with the current range's target-ports
if p.Protocol != pr.protocol || p.PublishedPort-pr.pEnd > 1 || p.TargetPort-pr.tEnd > 1 || prIsRange && tOverlaps {
// start a new port-range, and print the previous port-range (if any)
if pr.pStart > 0 {
ports = append(ports, pr.String())
}
pr = portRange{
pStart: p.PublishedPort,
pEnd: p.PublishedPort,
tStart: p.TargetPort,
tEnd: p.TargetPort,
protocol: p.Protocol,
}
continue
}
pr.pEnd = p.PublishedPort
pr.tEnd = p.TargetPort
}
}
return strings.Join(ports, ",")
if pr.pStart > 0 {
ports = append(ports, pr.String())
}
return strings.Join(ports, ", ")
}
type byProtocolAndPublishedPort []swarm.PortConfig
func (a byProtocolAndPublishedPort) Len() int { return len(a) }
func (a byProtocolAndPublishedPort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byProtocolAndPublishedPort) Less(i, j int) bool {
if a[i].Protocol == a[j].Protocol {
return a[i].PublishedPort < a[j].PublishedPort
}
return a[i].Protocol < a[j].Protocol
}

View File

@ -224,3 +224,136 @@ func TestServiceContextWriteJSONField(t *testing.T) {
assert.Equal(t, services[i].Spec.Name, s, msg)
}
}
func TestServiceContext_Ports(t *testing.T) {
c := serviceContext{
service: swarm.Service{
Endpoint: swarm.Endpoint{
Ports: []swarm.PortConfig{
{
Protocol: "tcp",
TargetPort: 80,
PublishedPort: 81,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 80,
PublishedPort: 80,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 95,
PublishedPort: 95,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 90,
PublishedPort: 90,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 91,
PublishedPort: 91,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 92,
PublishedPort: 92,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 93,
PublishedPort: 93,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 94,
PublishedPort: 94,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 95,
PublishedPort: 95,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 90,
PublishedPort: 90,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 96,
PublishedPort: 96,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 91,
PublishedPort: 91,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 92,
PublishedPort: 92,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 93,
PublishedPort: 93,
PublishMode: "ingress",
},
{
Protocol: "udp",
TargetPort: 94,
PublishedPort: 94,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 60,
PublishedPort: 60,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 61,
PublishedPort: 61,
PublishMode: "ingress",
},
{
Protocol: "tcp",
TargetPort: 61,
PublishedPort: 62,
PublishMode: "ingress",
},
{
Protocol: "sctp",
TargetPort: 97,
PublishedPort: 97,
PublishMode: "ingress",
},
{
Protocol: "sctp",
TargetPort: 98,
PublishedPort: 98,
PublishMode: "ingress",
},
},
},
},
}
assert.Equal(t, "*:97-98->97-98/sctp, *:60-61->60-61/tcp, *:62->61/tcp, *:80-81->80/tcp, *:90-95->90-95/tcp, *:90-96->90-96/udp", c.Ports())
}

View File

@ -9,8 +9,10 @@ import (
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
@ -206,6 +208,14 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
buildCtx, relDockerfile, err = build.GetContextFromReader(dockerCli.In(), options.dockerfileName)
case isLocalDir(specifiedContext):
contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, options.dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
// Dockerfile is outside of build-context; read the Dockerfile and pass it as dockerfileCtx
dockerfileCtx, err = os.Open(options.dockerfileName)
if err != nil {
return errors.Errorf("unable to open Dockerfile: %v", err)
}
defer dockerfileCtx.Close()
}
case urlutil.IsGitURL(specifiedContext):
tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, options.dockerfileName)
case urlutil.IsURL(specifiedContext):
@ -253,7 +263,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
}
}
// replace Dockerfile if it was added from stdin and there is archive context
// replace Dockerfile if it was added from stdin or a file outside the build-context, and there is archive context
if dockerfileCtx != nil && buildCtx != nil {
buildCtx, relDockerfile, err = build.AddDockerfileToBuildContext(dockerfileCtx, buildCtx)
if err != nil {
@ -261,7 +271,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
}
}
// if streaming and dockerfile was not from stdin then read from file
// if streaming and Dockerfile was not from stdin then read from file
// to the same reader that is usually stdin
if options.stream && dockerfileCtx == nil {
dockerfileCtx, err = os.Open(relDockerfile)

View File

@ -167,6 +167,10 @@ func GetContextFromGitURL(gitURL, dockerfileName string) (string, string, error)
return "", "", err
}
relDockerfile, err := getDockerfileRelPath(absContextDir, dockerfileName)
if err == nil && strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
return "", "", errors.Errorf("the Dockerfile (%s) must be within the build context", dockerfileName)
}
return absContextDir, relDockerfile, err
}
@ -318,10 +322,6 @@ func getDockerfileRelPath(absContextDir, givenDockerfile string) (string, error)
return "", errors.Errorf("unable to get relative Dockerfile path: %v", err)
}
if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
return "", errors.Errorf("the Dockerfile (%s) must be within the build context", givenDockerfile)
}
return relDockerfile, nil
}

View File

@ -108,6 +108,56 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
assert.Equal(t, []string{dockerfileName, ".dockerignore", "foo"}, actual)
}
func TestRunBuildDockerfileOutsideContext(t *testing.T) {
dir := fs.NewDir(t, t.Name(),
fs.WithFile("data", "data file"),
)
defer dir.Remove()
// Dockerfile outside of build-context
df := fs.NewFile(t, t.Name(),
fs.WithContent(`
FROM FOOBAR
COPY data /data
`),
)
defer df.Remove()
dest, err := ioutil.TempDir("", t.Name())
require.NoError(t, err)
defer os.RemoveAll(dest)
var dockerfileName string
fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
buffer := new(bytes.Buffer)
tee := io.TeeReader(context, buffer)
assert.NoError(t, archive.Untar(tee, dest, nil))
dockerfileName = options.Dockerfile
body := new(bytes.Buffer)
return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil
}
cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild})
options := newBuildOptions()
options.context = dir.Path()
options.dockerfileName = df.Path()
err = runBuild(cli, options)
require.NoError(t, err)
files, err := ioutil.ReadDir(dest)
require.NoError(t, err)
var actual []string
for _, fileInfo := range files {
actual = append(actual, fileInfo.Name())
}
sort.Strings(actual)
assert.Equal(t, []string{dockerfileName, ".dockerignore", "data"}, actual)
}
// TestRunBuildFromLocalGitHubDirNonExistingRepo tests that build contexts
// starting with `github.com/` are special-cased, and the build command attempts
// to clone the remote repo.

View File

@ -81,7 +81,7 @@ func runRemove(dockerCli command.Cli, opts removeOptions, images []string) error
if !opts.force || fatalErr {
return errors.New(msg)
}
fmt.Fprintf(dockerCli.Err(), msg)
fmt.Fprintln(dockerCli.Err(), msg)
}
return nil
}

View File

@ -98,7 +98,7 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
assert.Equal(t, true, options.Force)
return []types.ImageDeleteResponseItem{}, notFound{"image1"}
},
expectedStderr: "Error: No such image: image1",
expectedStderr: "Error: No such image: image1\n",
},
{

View File

@ -0,0 +1,93 @@
package manifest
import (
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/manifest/store"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type annotateOptions struct {
target string // the target manifest list name (also transaction ID)
image string // the manifest to annotate within the list
variant string // an architecture variant
os string
arch string
osFeatures []string
}
// NewAnnotateCommand creates a new `docker manifest annotate` command
func newAnnotateCommand(dockerCli command.Cli) *cobra.Command {
var opts annotateOptions
cmd := &cobra.Command{
Use: "annotate [OPTIONS] MANIFEST_LIST MANIFEST",
Short: "Add additional information to a local image manifest",
Args: cli.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
opts.target = args[0]
opts.image = args[1]
return runManifestAnnotate(dockerCli, opts)
},
}
flags := cmd.Flags()
flags.StringVar(&opts.os, "os", "", "Set operating system")
flags.StringVar(&opts.arch, "arch", "", "Set architecture")
flags.StringSliceVar(&opts.osFeatures, "os-features", []string{}, "Set operating system feature")
flags.StringVar(&opts.variant, "variant", "", "Set architecture variant")
return cmd
}
func runManifestAnnotate(dockerCli command.Cli, opts annotateOptions) error {
targetRef, err := normalizeReference(opts.target)
if err != nil {
return errors.Wrapf(err, "annotate: error parsing name for manifest list %s", opts.target)
}
imgRef, err := normalizeReference(opts.image)
if err != nil {
return errors.Wrapf(err, "annotate: error parsing name for manifest %s", opts.image)
}
manifestStore := dockerCli.ManifestStore()
imageManifest, err := manifestStore.Get(targetRef, imgRef)
switch {
case store.IsNotFound(err):
return fmt.Errorf("manifest for image %s does not exist in %s", opts.image, opts.target)
case err != nil:
return err
}
// Update the mf
if opts.os != "" {
imageManifest.Platform.OS = opts.os
}
if opts.arch != "" {
imageManifest.Platform.Architecture = opts.arch
}
for _, osFeature := range opts.osFeatures {
imageManifest.Platform.OSFeatures = appendIfUnique(imageManifest.Platform.OSFeatures, osFeature)
}
if opts.variant != "" {
imageManifest.Platform.Variant = opts.variant
}
if !isValidOSArch(imageManifest.Platform.OS, imageManifest.Platform.Architecture) {
return errors.Errorf("manifest entry for image has unsupported os/arch combination: %s/%s", opts.os, opts.arch)
}
return manifestStore.Save(targetRef, imgRef, imageManifest)
}
func appendIfUnique(list []string, str string) []string {
for _, s := range list {
if s == str {
return list
}
}
return append(list, str)
}

View File

@ -0,0 +1,78 @@
package manifest
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"
"github.com/stretchr/testify/require"
)
func TestManifestAnnotateError(t *testing.T) {
testCases := []struct {
args []string
expectedError string
}{
{
args: []string{"too-few-arguments"},
expectedError: "requires exactly 2 arguments",
},
{
args: []string{"th!si'sa/fa!ke/li$t/name", "example.com/alpine:3.0"},
expectedError: "error parsing name for manifest list",
},
{
args: []string{"example.com/list:v1", "th!si'sa/fa!ke/im@ge/nam32"},
expectedError: "error parsing name for manifest",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(nil)
cmd := newAnnotateCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestManifestAnnotate(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
cmd := newAnnotateCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/fake:0.0"})
cmd.SetOutput(ioutil.Discard)
expectedError := "manifest for image example.com/fake:0.0 does not exist"
testutil.ErrorContains(t, cmd.Execute(), expectedError)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.Flags().Set("os", "freebsd")
cmd.Flags().Set("arch", "fake")
cmd.Flags().Set("os-features", "feature1")
cmd.Flags().Set("variant", "v7")
expectedError = "manifest entry for image has unsupported os/arch combination"
testutil.ErrorContains(t, cmd.Execute(), expectedError)
cmd.Flags().Set("arch", "arm")
require.NoError(t, cmd.Execute())
cmd = newInspectCommand(cli)
err = cmd.Flags().Set("verbose", "true")
require.NoError(t, err)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-annotate.golden")
assert.Equal(t, string(expected), actual.String())
}

View File

@ -0,0 +1,46 @@
package manifest
import (
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/cli/registry/client"
"github.com/docker/distribution"
"github.com/docker/distribution/reference"
"github.com/opencontainers/go-digest"
"golang.org/x/net/context"
)
type fakeRegistryClient struct {
client.RegistryClient
getManifestFunc func(ctx context.Context, ref reference.Named) (manifesttypes.ImageManifest, error)
getManifestListFunc func(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error)
mountBlobFunc func(ctx context.Context, source reference.Canonical, target reference.Named) error
putManifestFunc func(ctx context.Context, source reference.Named, mf distribution.Manifest) (digest.Digest, error)
}
func (c *fakeRegistryClient) GetManifest(ctx context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) {
if c.getManifestFunc != nil {
return c.getManifestFunc(ctx, ref)
}
return manifesttypes.ImageManifest{}, nil
}
func (c *fakeRegistryClient) GetManifestList(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error) {
if c.getManifestListFunc != nil {
return c.getManifestListFunc(ctx, ref)
}
return nil, nil
}
func (c *fakeRegistryClient) MountBlob(ctx context.Context, source reference.Canonical, target reference.Named) error {
if c.mountBlobFunc != nil {
return c.mountBlobFunc(ctx, source, target)
}
return nil
}
func (c *fakeRegistryClient) PutManifest(ctx context.Context, ref reference.Named, mf distribution.Manifest) (digest.Digest, error) {
if c.putManifestFunc != nil {
return c.putManifestFunc(ctx, ref, mf)
}
return digest.Digest(""), nil
}

View File

@ -0,0 +1,45 @@
package manifest
import (
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/spf13/cobra"
)
// NewManifestCommand returns a cobra command for `manifest` subcommands
func NewManifestCommand(dockerCli command.Cli) *cobra.Command {
// use dockerCli as command.Cli
cmd := &cobra.Command{
Use: "manifest COMMAND",
Short: "Manage Docker image manifests and manifest lists",
Long: manifestDescription,
Args: cli.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
fmt.Fprintf(dockerCli.Err(), "\n"+cmd.UsageString())
},
Annotations: map[string]string{"experimentalCLI": ""},
}
cmd.AddCommand(
newCreateListCommand(dockerCli),
newInspectCommand(dockerCli),
newAnnotateCommand(dockerCli),
newPushListCommand(dockerCli),
)
return cmd
}
var manifestDescription = `
The **docker manifest** command has subcommands for managing image manifests and
manifest lists. A manifest list allows you to use one name to refer to the same image
built for multiple architectures.
To see help for a subcommand, use:
docker manifest CMD --help
For full details on using docker manifest lists, see the registry v2 specification.
`

View File

@ -0,0 +1,82 @@
package manifest
import (
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/manifest/store"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
type createOpts struct {
amend bool
insecure bool
}
func newCreateListCommand(dockerCli command.Cli) *cobra.Command {
opts := createOpts{}
cmd := &cobra.Command{
Use: "create MANFEST_LIST MANIFEST [MANIFEST...]",
Short: "Create a local manifest list for annotating and pushing to a registry",
Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
return createManifestList(dockerCli, args, opts)
},
}
flags := cmd.Flags()
flags.BoolVar(&opts.insecure, "insecure", false, "allow communication with an insecure registry")
flags.BoolVarP(&opts.amend, "amend", "a", false, "Amend an existing manifest list")
return cmd
}
func createManifestList(dockerCli command.Cli, args []string, opts createOpts) error {
newRef := args[0]
targetRef, err := normalizeReference(newRef)
if err != nil {
return errors.Wrapf(err, "error parsing name for manifest list %s", newRef)
}
_, err = registry.ParseRepositoryInfo(targetRef)
if err != nil {
return errors.Wrapf(err, "error parsing repository name for manifest list %s", newRef)
}
manifestStore := dockerCli.ManifestStore()
_, err = manifestStore.GetList(targetRef)
switch {
case store.IsNotFound(err):
// New manifest list
case err != nil:
return err
case !opts.amend:
return errors.Errorf("refusing to amend an existing manifest list with no --amend flag")
}
ctx := context.Background()
// Now create the local manifest list transaction by looking up the manifest schemas
// for the constituent images:
manifests := args[1:]
for _, manifestRef := range manifests {
namedRef, err := normalizeReference(manifestRef)
if err != nil {
// TODO: wrap error?
return err
}
manifest, err := getManifest(ctx, dockerCli, targetRef, namedRef, opts.insecure)
if err != nil {
return err
}
if err := manifestStore.Save(targetRef, namedRef, manifest); err != nil {
return err
}
}
fmt.Fprintf(dockerCli.Out(), "Created manifest list %s\n", targetRef.String())
return nil
}

View File

@ -0,0 +1,117 @@
package manifest
import (
"io/ioutil"
"testing"
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/distribution/reference"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestManifestCreateErrors(t *testing.T) {
testCases := []struct {
args []string
expectedError string
}{
{
args: []string{"too-few-arguments"},
expectedError: "requires at least 2 arguments",
},
{
args: []string{"th!si'sa/fa!ke/li$t/name", "example.com/alpine:3.0"},
expectedError: "error parsing name for manifest list",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(nil)
cmd := newCreateListCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
// create a manifest list, then overwrite it, and inspect to see if the old one is still there
func TestManifestCreateAmend(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
namedRef = ref(t, "alpine:3.1")
imageManifest = fullImageManifest(t, namedRef)
err = store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.1"})
cmd.Flags().Set("amend", "true")
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
require.NoError(t, err)
// make a new cli to clear the buffers
cli = test.NewFakeCli(nil)
cli.SetManifestStore(store)
inspectCmd := newInspectCommand(cli)
inspectCmd.SetArgs([]string{"example.com/list:v1"})
require.NoError(t, inspectCmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest-list.golden")
assert.Equal(t, string(expected), actual.String())
}
// attempt to overwrite a saved manifest and get refused
func TestManifestCreateRefuseAmend(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
assert.EqualError(t, err, "refusing to amend an existing manifest list with no --amend flag")
}
// attempt to make a manifest list without valid images
func TestManifestCreateNoManifest(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
cli.SetRegistryClient(&fakeRegistryClient{
getManifestFunc: func(_ context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) {
return manifesttypes.ImageManifest{}, errors.Errorf("No such image: %v", ref)
},
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error) {
return nil, errors.Errorf("No such manifest: %s", ref)
},
})
cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOutput(ioutil.Discard)
err := cmd.Execute()
assert.EqualError(t, err, "No such image: example.com/alpine:3.0")
}

View File

@ -0,0 +1,147 @@
package manifest
import (
"bytes"
"encoding/json"
"fmt"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/manifest/types"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/reference"
"github.com/docker/docker/registry"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
type inspectOptions struct {
ref string
list string
verbose bool
insecure bool
}
// NewInspectCommand creates a new `docker manifest inspect` command
func newInspectCommand(dockerCli command.Cli) *cobra.Command {
var opts inspectOptions
cmd := &cobra.Command{
Use: "inspect [OPTIONS] [MANIFEST_LIST] MANIFEST",
Short: "Display an image manifest, or manifest list",
Args: cli.RequiresRangeArgs(1, 2),
RunE: func(cmd *cobra.Command, args []string) error {
switch len(args) {
case 1:
opts.ref = args[0]
case 2:
opts.list = args[0]
opts.ref = args[1]
}
return runInspect(dockerCli, opts)
},
}
flags := cmd.Flags()
flags.BoolVar(&opts.insecure, "insecure", false, "allow communication with an insecure registry")
flags.BoolVarP(&opts.verbose, "verbose", "v", false, "Output additional info including layers and platform")
return cmd
}
func runInspect(dockerCli command.Cli, opts inspectOptions) error {
namedRef, err := normalizeReference(opts.ref)
if err != nil {
return err
}
// If list reference is provided, display the local manifest in a list
if opts.list != "" {
listRef, err := normalizeReference(opts.list)
if err != nil {
return err
}
imageManifest, err := dockerCli.ManifestStore().Get(listRef, namedRef)
if err != nil {
return err
}
return printManifest(dockerCli, imageManifest, opts)
}
// Try a local manifest list first
localManifestList, err := dockerCli.ManifestStore().GetList(namedRef)
if err == nil {
return printManifestList(dockerCli, namedRef, localManifestList, opts)
}
// Next try a remote manifest
ctx := context.Background()
registryClient := dockerCli.RegistryClient(opts.insecure)
imageManifest, err := registryClient.GetManifest(ctx, namedRef)
if err == nil {
return printManifest(dockerCli, imageManifest, opts)
}
// Finally try a remote manifest list
manifestList, err := registryClient.GetManifestList(ctx, namedRef)
if err != nil {
return err
}
return printManifestList(dockerCli, namedRef, manifestList, opts)
}
func printManifest(dockerCli command.Cli, manifest types.ImageManifest, opts inspectOptions) error {
buffer := new(bytes.Buffer)
if !opts.verbose {
_, raw, err := manifest.Payload()
if err != nil {
return err
}
if err := json.Indent(buffer, raw, "", "\t"); err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), buffer.String())
return nil
}
jsonBytes, err := json.MarshalIndent(manifest, "", "\t")
if err != nil {
return err
}
dockerCli.Out().Write(append(jsonBytes, '\n'))
return nil
}
func printManifestList(dockerCli command.Cli, namedRef reference.Named, list []types.ImageManifest, opts inspectOptions) error {
if !opts.verbose {
targetRepo, err := registry.ParseRepositoryInfo(namedRef)
if err != nil {
return err
}
manifests := []manifestlist.ManifestDescriptor{}
// More than one response. This is a manifest list.
for _, img := range list {
mfd, err := buildManifestDescriptor(targetRepo, img)
if err != nil {
return fmt.Errorf("error assembling ManifestDescriptor")
}
manifests = append(manifests, mfd)
}
deserializedML, err := manifestlist.FromDescriptors(manifests)
if err != nil {
return err
}
jsonBytes, err := deserializedML.MarshalJSON()
if err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), string(jsonBytes))
return nil
}
jsonBytes, err := json.MarshalIndent(list, "", "\t")
if err != nil {
return err
}
dockerCli.Out().Write(append(jsonBytes, '\n'))
return nil
}

View File

@ -0,0 +1,131 @@
package manifest
import (
"io/ioutil"
"os"
"testing"
"github.com/docker/cli/cli/manifest/store"
"github.com/docker/cli/cli/manifest/types"
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/internal/test"
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func newTempManifestStore(t *testing.T) (store.Store, func()) {
tmpdir, err := ioutil.TempDir("", "test-manifest-storage")
require.NoError(t, err)
return store.NewStore(tmpdir), func() { os.RemoveAll(tmpdir) }
}
func ref(t *testing.T, name string) reference.Named {
named, err := reference.ParseNamed("example.com/" + name)
require.NoError(t, err)
return named
}
func fullImageManifest(t *testing.T, ref reference.Named) types.ImageManifest {
man, err := schema2.FromStruct(schema2.Manifest{
Versioned: schema2.SchemaVersion,
Config: distribution.Descriptor{
Digest: "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d624560",
Size: 1520,
MediaType: schema2.MediaTypeImageConfig,
},
Layers: []distribution.Descriptor{
{
MediaType: schema2.MediaTypeLayer,
Size: 1990402,
Digest: "sha256:88286f41530e93dffd4b964e1db22ce4939fffa4a4c665dab8591fbab03d4926",
},
},
})
require.NoError(t, err)
// TODO: include image data for verbose inspect
return types.NewImageManifest(ref, digest.Digest("sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d62abcd"), types.Image{OS: "linux", Architecture: "amd64"}, man)
}
func TestInspectCommandLocalManifestNotFound(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
cmd := newInspectCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
err := cmd.Execute()
assert.EqualError(t, err, "No such manifest: example.com/alpine:3.0")
}
func TestInspectCommandNotFound(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
cli.SetRegistryClient(&fakeRegistryClient{
getManifestFunc: func(_ context.Context, _ reference.Named) (manifesttypes.ImageManifest, error) {
return manifesttypes.ImageManifest{}, errors.New("missing")
},
getManifestListFunc: func(ctx context.Context, ref reference.Named) ([]manifesttypes.ImageManifest, error) {
return nil, errors.Errorf("No such manifest: %s", ref)
},
})
cmd := newInspectCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/alpine:3.0"})
err := cmd.Execute()
assert.EqualError(t, err, "No such manifest: example.com/alpine:3.0")
}
func TestInspectCommandLocalManifest(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest.golden")
assert.Equal(t, string(expected), actual.String())
}
func TestInspectcommandRemoteManifest(t *testing.T) {
store, cleanup := newTempManifestStore(t)
defer cleanup()
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
cli.SetRegistryClient(&fakeRegistryClient{
getManifestFunc: func(_ context.Context, ref reference.Named) (manifesttypes.ImageManifest, error) {
return fullImageManifest(t, ref), nil
},
})
cmd := newInspectCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest.golden")
assert.Equal(t, string(expected), actual.String())
}

View File

@ -0,0 +1,273 @@
package manifest
import (
"encoding/json"
"fmt"
"io"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/manifest/types"
registryclient "github.com/docker/cli/cli/registry/client"
"github.com/docker/distribution/manifest/manifestlist"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
type pushOpts struct {
insecure bool
purge bool
target string
}
type mountRequest struct {
ref reference.Named
manifest types.ImageManifest
}
type manifestBlob struct {
canonical reference.Canonical
os string
}
type pushRequest struct {
targetRef reference.Named
list *manifestlist.DeserializedManifestList
mountRequests []mountRequest
manifestBlobs []manifestBlob
insecure bool
}
func newPushListCommand(dockerCli command.Cli) *cobra.Command {
opts := pushOpts{}
cmd := &cobra.Command{
Use: "push [OPTIONS] MANIFEST_LIST",
Short: "Push a manifest list to a repository",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.target = args[0]
return runPush(dockerCli, opts)
},
}
flags := cmd.Flags()
flags.BoolVarP(&opts.purge, "purge", "p", false, "Remove the local manifest list after push")
flags.BoolVar(&opts.insecure, "insecure", false, "Allow push to an insecure registry")
return cmd
}
func runPush(dockerCli command.Cli, opts pushOpts) error {
targetRef, err := normalizeReference(opts.target)
if err != nil {
return err
}
manifests, err := dockerCli.ManifestStore().GetList(targetRef)
if err != nil {
return err
}
if len(manifests) == 0 {
return errors.Errorf("%s not found", targetRef)
}
pushRequest, err := buildPushRequest(manifests, targetRef, opts.insecure)
if err != nil {
return err
}
ctx := context.Background()
if err := pushList(ctx, dockerCli, pushRequest); err != nil {
return err
}
if opts.purge {
return dockerCli.ManifestStore().Remove(targetRef)
}
return nil
}
func buildPushRequest(manifests []types.ImageManifest, targetRef reference.Named, insecure bool) (pushRequest, error) {
req := pushRequest{targetRef: targetRef, insecure: insecure}
var err error
req.list, err = buildManifestList(manifests, targetRef)
if err != nil {
return req, err
}
targetRepo, err := registry.ParseRepositoryInfo(targetRef)
if err != nil {
return req, err
}
targetRepoName, err := registryclient.RepoNameForReference(targetRepo.Name)
if err != nil {
return req, err
}
for _, imageManifest := range manifests {
manifestRepoName, err := registryclient.RepoNameForReference(imageManifest.Ref)
if err != nil {
return req, err
}
repoName, _ := reference.WithName(manifestRepoName)
if repoName.Name() != targetRepoName {
blobs, err := buildBlobRequestList(imageManifest, repoName)
if err != nil {
return req, err
}
req.manifestBlobs = append(req.manifestBlobs, blobs...)
manifestPush, err := buildPutManifestRequest(imageManifest, targetRef)
if err != nil {
return req, err
}
req.mountRequests = append(req.mountRequests, manifestPush)
}
}
return req, nil
}
func buildManifestList(manifests []types.ImageManifest, targetRef reference.Named) (*manifestlist.DeserializedManifestList, error) {
targetRepoInfo, err := registry.ParseRepositoryInfo(targetRef)
if err != nil {
return nil, err
}
descriptors := []manifestlist.ManifestDescriptor{}
for _, imageManifest := range manifests {
if imageManifest.Platform.Architecture == "" || imageManifest.Platform.OS == "" {
return nil, errors.Errorf(
"manifest %s must have an OS and Architecture to be pushed to a registry", imageManifest.Ref)
}
descriptor, err := buildManifestDescriptor(targetRepoInfo, imageManifest)
if err != nil {
return nil, err
}
descriptors = append(descriptors, descriptor)
}
return manifestlist.FromDescriptors(descriptors)
}
func buildManifestDescriptor(targetRepo *registry.RepositoryInfo, imageManifest types.ImageManifest) (manifestlist.ManifestDescriptor, error) {
repoInfo, err := registry.ParseRepositoryInfo(imageManifest.Ref)
if err != nil {
return manifestlist.ManifestDescriptor{}, err
}
manifestRepoHostname := reference.Domain(repoInfo.Name)
targetRepoHostname := reference.Domain(targetRepo.Name)
if manifestRepoHostname != targetRepoHostname {
return manifestlist.ManifestDescriptor{}, errors.Errorf("cannot use source images from a different registry than the target image: %s != %s", manifestRepoHostname, targetRepoHostname)
}
mediaType, raw, err := imageManifest.Payload()
if err != nil {
return manifestlist.ManifestDescriptor{}, err
}
manifest := manifestlist.ManifestDescriptor{
Platform: imageManifest.Platform,
}
manifest.Descriptor.Digest = imageManifest.Digest
manifest.Size = int64(len(raw))
manifest.MediaType = mediaType
if err = manifest.Descriptor.Digest.Validate(); err != nil {
return manifestlist.ManifestDescriptor{}, errors.Wrapf(err,
"digest parse of image %q failed", imageManifest.Ref)
}
return manifest, nil
}
func buildBlobRequestList(imageManifest types.ImageManifest, repoName reference.Named) ([]manifestBlob, error) {
var blobReqs []manifestBlob
for _, blobDigest := range imageManifest.Blobs() {
canonical, err := reference.WithDigest(repoName, blobDigest)
if err != nil {
return nil, err
}
blobReqs = append(blobReqs, manifestBlob{canonical: canonical, os: imageManifest.Platform.OS})
}
return blobReqs, nil
}
// nolint: interfacer
func buildPutManifestRequest(imageManifest types.ImageManifest, targetRef reference.Named) (mountRequest, error) {
refWithoutTag, err := reference.WithName(targetRef.Name())
if err != nil {
return mountRequest{}, err
}
mountRef, err := reference.WithDigest(refWithoutTag, imageManifest.Digest)
if err != nil {
return mountRequest{}, err
}
// This indentation has to be added to ensure sha parity with the registry
v2ManifestBytes, err := json.MarshalIndent(imageManifest.SchemaV2Manifest, "", " ")
if err != nil {
return mountRequest{}, err
}
// indent only the DeserializedManifest portion of this, in order to maintain parity with the registry
// and not alter the sha
var v2Manifest schema2.DeserializedManifest
if err = v2Manifest.UnmarshalJSON(v2ManifestBytes); err != nil {
return mountRequest{}, err
}
imageManifest.SchemaV2Manifest = &v2Manifest
return mountRequest{ref: mountRef, manifest: imageManifest}, err
}
func pushList(ctx context.Context, dockerCli command.Cli, req pushRequest) error {
rclient := dockerCli.RegistryClient(req.insecure)
if err := mountBlobs(ctx, rclient, req.targetRef, req.manifestBlobs); err != nil {
return err
}
if err := pushReferences(ctx, dockerCli.Out(), rclient, req.mountRequests); err != nil {
return err
}
dgst, err := rclient.PutManifest(ctx, req.targetRef, req.list)
if err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), dgst.String())
return nil
}
func pushReferences(ctx context.Context, out io.Writer, client registryclient.RegistryClient, mounts []mountRequest) error {
for _, mount := range mounts {
newDigest, err := client.PutManifest(ctx, mount.ref, mount.manifest)
if err != nil {
return err
}
fmt.Fprintf(out, "Pushed ref %s with digest: %s\n", mount.ref, newDigest)
}
return nil
}
func mountBlobs(ctx context.Context, client registryclient.RegistryClient, ref reference.Named, blobs []manifestBlob) error {
for _, blob := range blobs {
err := client.MountBlob(ctx, blob.canonical, ref)
switch err.(type) {
case nil:
case registryclient.ErrBlobCreated:
if blob.os != "windows" {
return fmt.Errorf("error mounting %s to %s", blob.canonical, ref)
}
default:
return err
}
}
return nil
}

View File

@ -0,0 +1,73 @@
package manifest
import (
"io/ioutil"
"testing"
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/distribution/reference"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func newFakeRegistryClient(t *testing.T) *fakeRegistryClient {
require.NoError(t, nil)
return &fakeRegistryClient{
getManifestFunc: func(_ context.Context, _ reference.Named) (manifesttypes.ImageManifest, error) {
return manifesttypes.ImageManifest{}, errors.New("")
},
getManifestListFunc: func(_ context.Context, _ reference.Named) ([]manifesttypes.ImageManifest, error) {
return nil, errors.Errorf("")
},
}
}
func TestManifestPushErrors(t *testing.T) {
testCases := []struct {
args []string
expectedError string
}{
{
args: []string{"one-arg", "extra-arg"},
expectedError: "requires exactly 1 argument",
},
{
args: []string{"th!si'sa/fa!ke/li$t/-name"},
expectedError: "invalid reference format",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(nil)
cmd := newPushListCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
// store a one-image manifest list and puah it
func TestManifestPush(t *testing.T) {
store, sCleanup := newTempManifestStore(t)
defer sCleanup()
registry := newFakeRegistryClient(t)
cli := test.NewFakeCli(nil)
cli.SetManifestStore(store)
cli.SetRegistryClient(registry)
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
cmd := newPushListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1"})
err = cmd.Execute()
require.NoError(t, err)
}

View File

@ -0,0 +1,28 @@
{
"Ref": "example.com/alpine:3.0",
"Digest": "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d62abcd",
"SchemaV2Manifest": {
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1520,
"digest": "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d624560"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 1990402,
"digest": "sha256:88286f41530e93dffd4b964e1db22ce4939fffa4a4c665dab8591fbab03d4926"
}
]
},
"Platform": {
"architecture": "arm",
"os": "freebsd",
"os.features": [
"feature1"
],
"variant": "v7"
}
}

View File

@ -0,0 +1,24 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 428,
"digest": "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d62abcd",
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 428,
"digest": "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d62abcd",
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}

View File

@ -0,0 +1,16 @@
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 1520,
"digest": "sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d624560"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 1990402,
"digest": "sha256:88286f41530e93dffd4b964e1db22ce4939fffa4a4c665dab8591fbab03d4926"
}
]
}

View File

@ -0,0 +1,79 @@
package manifest
import (
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/manifest/store"
"github.com/docker/cli/cli/manifest/types"
"github.com/docker/distribution/reference"
"golang.org/x/net/context"
)
type osArch struct {
os string
arch string
}
// Remove any unsupported os/arch combo
// list of valid os/arch values (see "Optional Environment Variables" section
// of https://golang.org/doc/install/source
// Added linux/s390x as we know System z support already exists
var validOSArches = map[osArch]bool{
{os: "darwin", arch: "386"}: true,
{os: "darwin", arch: "amd64"}: true,
{os: "darwin", arch: "arm"}: true,
{os: "darwin", arch: "arm64"}: true,
{os: "dragonfly", arch: "amd64"}: true,
{os: "freebsd", arch: "386"}: true,
{os: "freebsd", arch: "amd64"}: true,
{os: "freebsd", arch: "arm"}: true,
{os: "linux", arch: "386"}: true,
{os: "linux", arch: "amd64"}: true,
{os: "linux", arch: "arm"}: true,
{os: "linux", arch: "arm64"}: true,
{os: "linux", arch: "ppc64le"}: true,
{os: "linux", arch: "mips64"}: true,
{os: "linux", arch: "mips64le"}: true,
{os: "linux", arch: "s390x"}: true,
{os: "netbsd", arch: "386"}: true,
{os: "netbsd", arch: "amd64"}: true,
{os: "netbsd", arch: "arm"}: true,
{os: "openbsd", arch: "386"}: true,
{os: "openbsd", arch: "amd64"}: true,
{os: "openbsd", arch: "arm"}: true,
{os: "plan9", arch: "386"}: true,
{os: "plan9", arch: "amd64"}: true,
{os: "solaris", arch: "amd64"}: true,
{os: "windows", arch: "386"}: true,
{os: "windows", arch: "amd64"}: true,
}
func isValidOSArch(os string, arch string) bool {
// check for existence of this combo
_, ok := validOSArches[osArch{os, arch}]
return ok
}
func normalizeReference(ref string) (reference.Named, error) {
namedRef, err := reference.ParseNormalizedNamed(ref)
if err != nil {
return nil, err
}
if _, isDigested := namedRef.(reference.Canonical); !isDigested {
return reference.TagNameOnly(namedRef), nil
}
return namedRef, nil
}
// getManifest from the local store, and fallback to the remote registry if it
// doesn't exist locally
func getManifest(ctx context.Context, dockerCli command.Cli, listRef, namedRef reference.Named, insecure bool) (types.ImageManifest, error) {
data, err := dockerCli.ManifestStore().Get(listRef, namedRef)
switch {
case store.IsNotFound(err):
return dockerCli.RegistryClient(insecure).GetManifest(ctx, namedRef)
case err != nil:
return types.ImageManifest{}, err
default:
return data, nil
}
}

View File

@ -56,8 +56,8 @@ func TestNodeList(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
nodeListFunc: func() ([]swarm.Node, error) {
return []swarm.Node{
*Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader())),
*Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager()),
*Node(NodeID("nodeID1"), Hostname("node-2-foo"), Manager(Leader()), EngineVersion(".")),
*Node(NodeID("nodeID2"), Hostname("node-10-foo"), Manager(), EngineVersion("18.03.0-ce")),
*Node(NodeID("nodeID3"), Hostname("node-1-foo")),
}, nil
},

View File

@ -1,4 +1,4 @@
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
nodeID3 node-1-foo Ready Active
nodeID1 * node-2-foo Ready Active Leader
nodeID2 node-10-foo Ready Active Reachable
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
nodeID3 node-1-foo Ready Active 1.13.0
nodeID1 * node-2-foo Ready Active Leader .
nodeID2 node-10-foo Ready Active Reachable 18.03.0-ce

View File

@ -21,9 +21,9 @@ const (
func normalize(flag string) Orchestrator {
switch flag {
case "kubernetes", "k8s":
case "kubernetes":
return OrchestratorKubernetes
case "swarm", "swarmkit":
case "swarm":
return OrchestratorSwarm
default:
return orchestratorUnset

View File

@ -0,0 +1,45 @@
package plugin
import (
"io"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"golang.org/x/net/context"
)
type fakeClient struct {
client.Client
pluginCreateFunc func(createContext io.Reader, createOptions types.PluginCreateOptions) error
pluginDisableFunc func(name string, disableOptions types.PluginDisableOptions) error
pluginEnableFunc func(name string, options types.PluginEnableOptions) error
pluginRemoveFunc func(name string, options types.PluginRemoveOptions) error
}
func (c *fakeClient) PluginCreate(ctx context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {
if c.pluginCreateFunc != nil {
return c.pluginCreateFunc(createContext, createOptions)
}
return nil
}
func (c *fakeClient) PluginEnable(ctx context.Context, name string, enableOptions types.PluginEnableOptions) error {
if c.pluginEnableFunc != nil {
return c.pluginEnableFunc(name, enableOptions)
}
return nil
}
func (c *fakeClient) PluginDisable(context context.Context, name string, disableOptions types.PluginDisableOptions) error {
if c.pluginDisableFunc != nil {
return c.pluginDisableFunc(name, disableOptions)
}
return nil
}
func (c *fakeClient) PluginRemove(context context.Context, name string, removeOptions types.PluginRemoveOptions) error {
if c.pluginRemoveFunc != nil {
return c.pluginRemoveFunc(name, removeOptions)
}
return nil
}

View File

@ -0,0 +1,114 @@
package plugin
import (
"fmt"
"io"
"io/ioutil"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/stretchr/testify/assert"
)
func TestCreateErrors(t *testing.T) {
testCases := []struct {
args []string
expectedError string
}{
{
args: []string{},
expectedError: "requires at least 2 arguments",
},
{
args: []string{"INVALID_TAG", "context-dir"},
expectedError: "invalid",
},
{
args: []string{"plugin-foo", "nonexistent_context_dir"},
expectedError: "no such file or directory",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{})
cmd := newCreateCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestCreateErrorOnFileAsContextDir(t *testing.T) {
tmpFile := fs.NewFile(t, "file-as-context-dir")
defer tmpFile.Remove()
cli := test.NewFakeCli(&fakeClient{})
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpFile.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "context must be a directory")
}
func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) {
tmpDir := fs.NewDir(t, "plugin-create-test")
defer tmpDir.Remove()
cli := test.NewFakeCli(&fakeClient{})
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "config.json: no such file or directory")
}
func TestCreateErrorOnInvalidConfig(t *testing.T) {
tmpDir := fs.NewDir(t, "plugin-create-test",
fs.WithDir("rootfs"),
fs.WithFile("config.json", "invalid-config-contents"))
defer tmpDir.Remove()
cli := test.NewFakeCli(&fakeClient{})
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "invalid")
}
func TestCreateErrorFromDaemon(t *testing.T) {
tmpDir := fs.NewDir(t, "plugin-create-test",
fs.WithDir("rootfs"),
fs.WithFile("config.json", `{ "Name": "plugin-foo" }`))
defer tmpDir.Remove()
cli := test.NewFakeCli(&fakeClient{
pluginCreateFunc: func(createContext io.Reader, createOptions types.PluginCreateOptions) error {
return fmt.Errorf("Error creating plugin")
},
})
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "Error creating plugin")
}
func TestCreatePlugin(t *testing.T) {
tmpDir := fs.NewDir(t, "plugin-create-test",
fs.WithDir("rootfs"),
fs.WithFile("config.json", `{ "Name": "plugin-foo" }`))
defer tmpDir.Remove()
cli := test.NewFakeCli(&fakeClient{
pluginCreateFunc: func(createContext io.Reader, createOptions types.PluginCreateOptions) error {
return nil
},
})
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
}

View File

@ -0,0 +1,58 @@
package plugin
import (
"fmt"
"io/ioutil"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
func TestPluginDisableErrors(t *testing.T) {
testCases := []struct {
args []string
expectedError string
pluginDisableFunc func(name string, disableOptions types.PluginDisableOptions) error
}{
{
args: []string{},
expectedError: "requires exactly 1 argument",
},
{
args: []string{"too", "many", "arguments"},
expectedError: "requires exactly 1 argument",
},
{
args: []string{"plugin-foo"},
expectedError: "Error disabling plugin",
pluginDisableFunc: func(name string, disableOptions types.PluginDisableOptions) error {
return fmt.Errorf("Error disabling plugin")
},
},
}
for _, tc := range testCases {
cmd := newDisableCommand(
test.NewFakeCli(&fakeClient{
pluginDisableFunc: tc.pluginDisableFunc,
}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestPluginDisable(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
pluginDisableFunc: func(name string, disableOptions types.PluginDisableOptions) error {
return nil
},
})
cmd := newDisableCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
}

View File

@ -30,7 +30,7 @@ func newEnableCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
flags.IntVar(&opts.timeout, "timeout", 0, "HTTP client timeout (in seconds)")
flags.IntVar(&opts.timeout, "timeout", 30, "HTTP client timeout (in seconds)")
return cmd
}

View File

@ -0,0 +1,70 @@
package plugin
import (
"fmt"
"io/ioutil"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
func TestPluginEnableErrors(t *testing.T) {
testCases := []struct {
args []string
flags map[string]string
pluginEnableFunc func(name string, options types.PluginEnableOptions) error
expectedError string
}{
{
args: []string{},
expectedError: "requires exactly 1 argument",
},
{
args: []string{"too-many", "arguments"},
expectedError: "requires exactly 1 argument",
},
{
args: []string{"plugin-foo"},
pluginEnableFunc: func(name string, options types.PluginEnableOptions) error {
return fmt.Errorf("failed to enable plugin")
},
expectedError: "failed to enable plugin",
},
{
args: []string{"plugin-foo"},
flags: map[string]string{
"timeout": "-1",
},
expectedError: "negative timeout -1 is invalid",
},
}
for _, tc := range testCases {
cmd := newEnableCommand(
test.NewFakeCli(&fakeClient{
pluginEnableFunc: tc.pluginEnableFunc,
}))
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestPluginEnable(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
pluginEnableFunc: func(name string, options types.PluginEnableOptions) error {
return nil
},
})
cmd := newEnableCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
}

View File

@ -0,0 +1,71 @@
package plugin
import (
"fmt"
"io/ioutil"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
)
func TestRemoveErrors(t *testing.T) {
testCases := []struct {
args []string
pluginRemoveFunc func(name string, options types.PluginRemoveOptions) error
expectedError string
}{
{
args: []string{},
expectedError: "requires at least 1 argument",
},
{
args: []string{"plugin-foo"},
pluginRemoveFunc: func(name string, options types.PluginRemoveOptions) error {
return fmt.Errorf("Error removing plugin")
},
expectedError: "Error removing plugin",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{
pluginRemoveFunc: tc.pluginRemoveFunc,
})
cmd := newRemoveCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestRemove(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
pluginRemoveFunc: func(name string, options types.PluginRemoveOptions) error {
return nil
},
})
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
}
func TestRemoveWithForceOption(t *testing.T) {
force := false
cli := test.NewFakeCli(&fakeClient{
pluginRemoveFunc: func(name string, options types.PluginRemoveOptions) error {
force = options.Force
return nil
},
})
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
cmd.Flags().Set("force", "true")
assert.NoError(t, cmd.Execute())
assert.True(t, force)
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
}

View File

@ -10,14 +10,13 @@ import (
"runtime"
"strings"
"golang.org/x/net/context"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/registry"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
// ElectAuthServer returns the default registry to use (by asking the daemon)

View File

@ -16,10 +16,11 @@ import (
)
type createOptions struct {
name string
driver string
file string
labels opts.ListOpts
name string
driver string
templateDriver string
file string
labels opts.ListOpts
}
func newSecretCreateCommand(dockerCli command.Cli) *cobra.Command {
@ -43,6 +44,8 @@ func newSecretCreateCommand(dockerCli command.Cli) *cobra.Command {
flags.VarP(&options.labels, "label", "l", "Secret labels")
flags.StringVarP(&options.driver, "driver", "d", "", "Secret driver")
flags.SetAnnotation("driver", "version", []string{"1.31"})
flags.StringVar(&options.templateDriver, "template-driver", "", "Template driver")
flags.SetAnnotation("driver", "version", []string{"1.37"})
return cmd
}
@ -71,7 +74,11 @@ func runSecretCreate(dockerCli command.Cli, options createOptions) error {
Name: options.driver,
}
}
if options.templateDriver != "" {
spec.Templating = &swarm.Driver{
Name: options.templateDriver,
}
}
r, err := client.SecretCreate(ctx, spec)
if err != nil {
return err

View File

@ -11,7 +11,6 @@ import (
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
@ -52,15 +51,22 @@ func TestSecretCreateErrors(t *testing.T) {
func TestSecretCreateWithName(t *testing.T) {
name := "foo"
var actual []byte
data, err := ioutil.ReadFile(filepath.Join("testdata", secretDataFile))
assert.NoError(t, err)
expected := swarm.SecretSpec{
Annotations: swarm.Annotations{
Name: name,
Labels: make(map[string]string),
},
Data: data,
}
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
if !reflect.DeepEqual(spec, expected) {
return types.SecretCreateResponse{}, errors.Errorf("expected %+v, got %+v", expected, spec)
}
actual = spec.Data
return types.SecretCreateResponse{
ID: "ID-" + spec.Name,
}, nil
@ -70,7 +76,6 @@ func TestSecretCreateWithName(t *testing.T) {
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", secretDataFile)})
assert.NoError(t, cmd.Execute())
golden.Assert(t, string(actual), secretDataFile)
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
}
@ -86,7 +91,7 @@ func TestSecretCreateWithDriver(t *testing.T) {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
if !reflect.DeepEqual(spec.Driver.Name, expectedDriver.Name) {
if spec.Driver.Name != expectedDriver.Name {
return types.SecretCreateResponse{}, errors.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
}
@ -103,6 +108,35 @@ func TestSecretCreateWithDriver(t *testing.T) {
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
}
func TestSecretCreateWithTemplatingDriver(t *testing.T) {
expectedDriver := &swarm.Driver{
Name: "template-driver",
}
name := "foo"
cli := test.NewFakeCli(&fakeClient{
secretCreateFunc: func(spec swarm.SecretSpec) (types.SecretCreateResponse, error) {
if spec.Name != name {
return types.SecretCreateResponse{}, errors.Errorf("expected name %q, got %q", name, spec.Name)
}
if spec.Templating.Name != expectedDriver.Name {
return types.SecretCreateResponse{}, errors.Errorf("expected driver %v, got %v", expectedDriver, spec.Labels)
}
return types.SecretCreateResponse{
ID: "ID-" + spec.Name,
}, nil
},
})
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name})
cmd.Flags().Set("template-driver", expectedDriver.Name)
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
}
func TestSecretCreateWithLabels(t *testing.T) {
expectedLabels := map[string]string{
"lbl1": "Label-foo",

View File

@ -16,6 +16,7 @@ type fakeClient struct {
serviceListFunc func(context.Context, types.ServiceListOptions) ([]swarm.Service, error)
taskListFunc func(context.Context, types.TaskListOptions) ([]swarm.Task, error)
infoFunc func(ctx context.Context) (types.Info, error)
networkInspectFunc func(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error)
}
func (f *fakeClient) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {
@ -60,6 +61,13 @@ func (f *fakeClient) Info(ctx context.Context) (types.Info, error) {
return f.infoFunc(ctx)
}
func (f *fakeClient) NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) {
if f.networkInspectFunc != nil {
return f.networkInspectFunc(ctx, networkID, options)
}
return types.NetworkResource{}, nil
}
func newService(id string, name string) swarm.Service {
return swarm.Service{
ID: id,

View File

@ -353,22 +353,21 @@ func (c *credentialSpecOpt) Value() *swarm.CredentialSpec {
return c.value
}
func convertNetworks(ctx context.Context, apiClient client.NetworkAPIClient, networks opts.NetworkOpt) ([]swarm.NetworkAttachmentConfig, error) {
func resolveNetworkID(ctx context.Context, apiClient client.NetworkAPIClient, networkIDOrName string) (string, error) {
nw, err := apiClient.NetworkInspect(ctx, networkIDOrName, types.NetworkInspectOptions{Scope: "swarm"})
return nw.ID, err
}
func convertNetworks(networks opts.NetworkOpt) []swarm.NetworkAttachmentConfig {
var netAttach []swarm.NetworkAttachmentConfig
for _, net := range networks.Value() {
networkIDOrName := net.Target
_, err := apiClient.NetworkInspect(ctx, networkIDOrName, types.NetworkInspectOptions{Scope: "swarm"})
if err != nil {
return nil, err
}
netAttach = append(netAttach, swarm.NetworkAttachmentConfig{
Target: net.Target,
Aliases: net.Aliases,
DriverOpts: net.DriverOpts,
})
}
sort.Sort(byNetworkTarget(netAttach))
return netAttach, nil
return netAttach
}
type endpointOptions struct {
@ -561,7 +560,7 @@ func (options *serviceOptions) ToStopGracePeriod(flags *pflag.FlagSet) *time.Dur
func (options *serviceOptions) ToService(ctx context.Context, apiClient client.NetworkAPIClient, flags *pflag.FlagSet) (swarm.ServiceSpec, error) {
var service swarm.ServiceSpec
envVariables, err := opts.ReadKVStrings(options.envFile.GetAll(), options.env.GetAll())
envVariables, err := opts.ReadKVEnvStrings(options.envFile.GetAll(), options.env.GetAll())
if err != nil {
return service, err
}
@ -590,10 +589,15 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
return service, err
}
networks, err := convertNetworks(ctx, apiClient, options.networks)
if err != nil {
return service, err
networks := convertNetworks(options.networks)
for i, net := range networks {
nwID, err := resolveNetworkID(ctx, apiClient, net.Target)
if err != nil {
return service, err
}
networks[i].Target = nwID
}
sort.Sort(byNetworkTarget(networks))
resources, err := options.resources.ToResourceRequirements()
if err != nil {

View File

@ -1,12 +1,17 @@
package service
import (
"context"
"fmt"
"testing"
"time"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMemBytesString(t *testing.T) {
@ -123,3 +128,37 @@ func TestResourceOptionsToResourceRequirements(t *testing.T) {
}
}
func TestToServiceNetwork(t *testing.T) {
nws := []types.NetworkResource{
{Name: "aaa-network", ID: "id555"},
{Name: "mmm-network", ID: "id999"},
{Name: "zzz-network", ID: "id111"},
}
client := &fakeClient{
networkInspectFunc: func(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) {
for _, network := range nws {
if network.ID == networkID || network.Name == networkID {
return network, nil
}
}
return types.NetworkResource{}, fmt.Errorf("network not found: %s", networkID)
},
}
nwo := opts.NetworkOpt{}
nwo.Set("zzz-network")
nwo.Set("mmm-network")
nwo.Set("aaa-network")
o := newServiceOptions()
o.mode = "replicated"
o.networks = nwo
ctx := context.Background()
flags := newCreateCommand(nil).Flags()
service, err := o.ToService(ctx, client, flags)
require.NoError(t, err)
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id111"}, {Target: "id555"}, {Target: "id999"}}, service.TaskTemplate.Networks)
}

View File

@ -1119,14 +1119,16 @@ func updateNetworks(ctx context.Context, apiClient client.NetworkAPIClient, flag
if flags.Changed(flagNetworkAdd) {
values := flags.Lookup(flagNetworkAdd).Value.(*opts.NetworkOpt)
networks, err := convertNetworks(ctx, apiClient, *values)
if err != nil {
return err
}
networks := convertNetworks(*values)
for _, network := range networks {
if _, exists := existingNetworks[network.Target]; exists {
nwID, err := resolveNetworkID(ctx, apiClient, network.Target)
if err != nil {
return err
}
if _, exists := existingNetworks[nwID]; exists {
return errors.Errorf("service is already attached to network %s", network.Target)
}
network.Target = nwID
newNetworks = append(newNetworks, network)
existingNetworks[network.Target] = struct{}{}
}

View File

@ -1,6 +1,7 @@
package service
import (
"fmt"
"reflect"
"sort"
"testing"
@ -586,3 +587,69 @@ func TestRemoveGenericResources(t *testing.T) {
assert.NoError(t, removeGenericResources(flags, task))
assert.Len(t, task.Resources.Reservations.GenericResources, 1)
}
func TestUpdateNetworks(t *testing.T) {
ctx := context.Background()
nws := []types.NetworkResource{
{Name: "aaa-network", ID: "id555"},
{Name: "mmm-network", ID: "id999"},
{Name: "zzz-network", ID: "id111"},
}
client := &fakeClient{
networkInspectFunc: func(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) {
for _, network := range nws {
if network.ID == networkID || network.Name == networkID {
return network, nil
}
}
return types.NetworkResource{}, fmt.Errorf("network not found: %s", networkID)
},
}
svc := swarm.ServiceSpec{
TaskTemplate: swarm.TaskSpec{
ContainerSpec: &swarm.ContainerSpec{},
Networks: []swarm.NetworkAttachmentConfig{
{Target: "id999"},
},
},
}
flags := newUpdateCommand(nil).Flags()
err := flags.Set(flagNetworkAdd, "aaa-network")
require.NoError(t, err)
err = updateService(ctx, client, flags, &svc)
require.NoError(t, err)
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id555"}, {Target: "id999"}}, svc.TaskTemplate.Networks)
flags = newUpdateCommand(nil).Flags()
err = flags.Set(flagNetworkAdd, "aaa-network")
require.NoError(t, err)
err = updateService(ctx, client, flags, &svc)
assert.EqualError(t, err, "service is already attached to network aaa-network")
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id555"}, {Target: "id999"}}, svc.TaskTemplate.Networks)
flags = newUpdateCommand(nil).Flags()
err = flags.Set(flagNetworkAdd, "id555")
require.NoError(t, err)
err = updateService(ctx, client, flags, &svc)
assert.EqualError(t, err, "service is already attached to network id555")
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id555"}, {Target: "id999"}}, svc.TaskTemplate.Networks)
flags = newUpdateCommand(nil).Flags()
err = flags.Set(flagNetworkRemove, "id999")
require.NoError(t, err)
err = updateService(ctx, client, flags, &svc)
assert.NoError(t, err)
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id555"}}, svc.TaskTemplate.Networks)
flags = newUpdateCommand(nil).Flags()
err = flags.Set(flagNetworkAdd, "mmm-network")
require.NoError(t, err)
err = flags.Set(flagNetworkRemove, "aaa-network")
require.NoError(t, err)
err = updateService(ctx, client, flags, &svc)
assert.NoError(t, err)
assert.Equal(t, []swarm.NetworkAttachmentConfig{{Target: "id999"}}, svc.TaskTemplate.Networks)
}

View File

@ -9,11 +9,15 @@ import (
// NewStackCommand returns a cobra command for `stack` subcommands
func NewStackCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "stack",
Short: "Manage Docker stacks",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{"version": "1.25"},
Use: "stack",
Short: "Manage Docker stacks",
Args: cli.NoArgs,
RunE: command.ShowHelp(dockerCli.Err()),
Annotations: map[string]string{
"kubernetes": "",
"swarm": "",
"version": "1.25",
},
}
cmd.AddCommand(
newDeployCommand(dockerCli),
@ -37,6 +41,10 @@ func NewTopLevelDeployCommand(dockerCli command.Cli) *cobra.Command {
cmd := newDeployCommand(dockerCli)
// Remove the aliases at the top level
cmd.Aliases = []string{}
cmd.Annotations = map[string]string{"experimental": "", "version": "1.25"}
cmd.Annotations = map[string]string{
"experimental": "",
"swarm": "",
"version": "1.25",
}
return cmd
}

View File

@ -34,7 +34,7 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
flags.StringVar(&opts.Bundlefile, "bundle-file", "", "Path to a Distributed Application Bundle file")
flags.SetAnnotation("bundle-file", "experimental", nil)
flags.SetAnnotation("bundle-file", "swarm", nil)
flags.StringVarP(&opts.Composefile, "compose-file", "c", "", "Path to a Compose file")
flags.StringSliceVarP(&opts.Composefiles, "compose-file", "c", []string{}, "Path to a Compose file")
flags.SetAnnotation("compose-file", "version", []string{"1.25"})
flags.BoolVar(&opts.SendRegistryAuth, "with-registry-auth", false, "Send registry authentication details to Swarm agents")
flags.SetAnnotation("with-registry-auth", "swarm", nil)

View File

@ -27,15 +27,15 @@ func WrapCli(dockerCli command.Cli, cmd *cobra.Command) (*KubeCli, error) {
Cli: dockerCli,
kubeNamespace: "default",
}
if cmd.PersistentFlags().Changed("namespace") {
cli.kubeNamespace, err = cmd.PersistentFlags().GetString("namespace")
if cmd.Flags().Changed("namespace") {
cli.kubeNamespace, err = cmd.Flags().GetString("namespace")
if err != nil {
return nil, err
}
}
kubeConfig := ""
if cmd.PersistentFlags().Changed("kubeconfig") {
kubeConfig, err = cmd.PersistentFlags().GetString("kubeconfig")
if cmd.Flags().Changed("kubeconfig") {
kubeConfig, err = cmd.Flags().GetString("kubeconfig")
if err != nil {
return nil, err
}

View File

@ -5,8 +5,9 @@ import (
"io/ioutil"
"path"
"github.com/docker/cli/cli/command/stack/loader"
"github.com/docker/cli/cli/command/stack/options"
composeTypes "github.com/docker/cli/cli/compose/types"
composetypes "github.com/docker/cli/cli/compose/types"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
@ -16,9 +17,20 @@ import (
func RunDeploy(dockerCli *KubeCli, opts options.Deploy) error {
cmdOut := dockerCli.Out()
// Check arguments
if opts.Composefile == "" {
return errors.Errorf("Please specify a Compose file (with --compose-file).")
if len(opts.Composefiles) == 0 {
return errors.Errorf("Please specify only one compose file (with --compose-file).")
}
// Parse the compose file
cfg, err := loader.LoadComposefile(dockerCli, opts)
if err != nil {
return err
}
stack, err := LoadStack(opts.Namespace, *cfg)
if err != nil {
return err
}
// Initialize clients
stacks, err := dockerCli.stacks()
if err != nil {
@ -36,12 +48,6 @@ func RunDeploy(dockerCli *KubeCli, opts options.Deploy) error {
Pods: pods,
}
// Parse the compose file
stack, cfg, err := LoadStack(opts.Namespace, opts.Composefile)
if err != nil {
return err
}
// FIXME(vdemeester) handle warnings server-side
if err = IsColliding(services, stack, cfg); err != nil {
return err
@ -82,7 +88,7 @@ func RunDeploy(dockerCli *KubeCli, opts options.Deploy) error {
}
// createFileBasedConfigMaps creates a Kubernetes ConfigMap for each Compose global file-based config.
func createFileBasedConfigMaps(stackName string, globalConfigs map[string]composeTypes.ConfigObjConfig, configMaps corev1.ConfigMapInterface) error {
func createFileBasedConfigMaps(stackName string, globalConfigs map[string]composetypes.ConfigObjConfig, configMaps corev1.ConfigMapInterface) error {
for name, config := range globalConfigs {
if config.File == "" {
continue
@ -102,7 +108,7 @@ func createFileBasedConfigMaps(stackName string, globalConfigs map[string]compos
return nil
}
func serviceNames(cfg *composeTypes.Config) []string {
func serviceNames(cfg *composetypes.Config) []string {
names := []string{}
for _, service := range cfg.Services {
@ -113,7 +119,7 @@ func serviceNames(cfg *composeTypes.Config) []string {
}
// createFileBasedSecrets creates a Kubernetes Secret for each Compose global file-based secret.
func createFileBasedSecrets(stackName string, globalSecrets map[string]composeTypes.SecretConfig, secrets corev1.SecretInterface) error {
func createFileBasedSecrets(stackName string, globalSecrets map[string]composetypes.SecretConfig, secrets corev1.SecretInterface) error {
for name, secret := range globalSecrets {
if secret.File == "" {
continue

View File

@ -1,169 +1,24 @@
package kubernetes
import (
"bufio"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/cli/compose/template"
composetypes "github.com/docker/cli/cli/compose/types"
apiv1beta1 "github.com/docker/cli/kubernetes/compose/v1beta1"
"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// LoadStack loads a stack from a Compose file, with a given name.
// FIXME(vdemeester) remove this and use cli/compose/loader for both swarm and kubernetes
func LoadStack(name, composeFile string) (*apiv1beta1.Stack, *composetypes.Config, error) {
if composeFile == "" {
return nil, nil, errors.New("compose-file must be set")
}
workingDir, err := os.Getwd()
// LoadStack loads a stack from a Compose config, with a given name.
func LoadStack(name string, cfg composetypes.Config) (*apiv1beta1.Stack, error) {
res, err := yaml.Marshal(cfg)
if err != nil {
return nil, nil, err
return nil, err
}
composePath := composeFile
if !strings.HasPrefix(composePath, "/") {
composePath = filepath.Join(workingDir, composeFile)
}
if _, err := os.Stat(composePath); os.IsNotExist(err) {
return nil, nil, errors.Errorf("no compose file found in %s", filepath.Dir(composePath))
}
binary, err := ioutil.ReadFile(composePath)
if err != nil {
return nil, nil, errors.Wrap(err, "cannot read compose file")
}
env := env(workingDir)
return load(name, binary, workingDir, env)
}
func load(name string, binary []byte, workingDir string, env map[string]string) (*apiv1beta1.Stack, *composetypes.Config, error) {
processed, err := template.Substitute(string(binary), func(key string) (string, bool) { return env[key], true })
if err != nil {
return nil, nil, errors.Wrap(err, "cannot load compose file")
}
parsed, err := loader.ParseYAML([]byte(processed))
if err != nil {
return nil, nil, errors.Wrapf(err, "cannot load compose file")
}
cfg, err := loader.Load(composetypes.ConfigDetails{
WorkingDir: workingDir,
ConfigFiles: []composetypes.ConfigFile{
{
Config: parsed,
},
},
})
if err != nil {
return nil, nil, errors.Wrapf(err, "cannot load compose file")
}
result, err := processEnvFiles(processed, parsed, cfg)
if err != nil {
return nil, nil, errors.Wrapf(err, "cannot load compose file")
}
return &apiv1beta1.Stack{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: apiv1beta1.StackSpec{
ComposeFile: result,
ComposeFile: string(res),
},
}, cfg, nil
}
type iMap = map[string]interface{}
func processEnvFiles(input string, parsed map[string]interface{}, config *composetypes.Config) (string, error) {
changed := false
for _, svc := range config.Services {
if len(svc.EnvFile) == 0 {
continue
}
// Load() processed the env_file for us, we just need to inject back into
// the intermediate representation
env := iMap{}
for k, v := range svc.Environment {
env[k] = v
}
parsed["services"].(iMap)[svc.Name].(iMap)["environment"] = env
delete(parsed["services"].(iMap)[svc.Name].(iMap), "env_file")
changed = true
}
if !changed {
return input, nil
}
res, err := yaml.Marshal(parsed)
if err != nil {
return "", err
}
return string(res), nil
}
func env(workingDir string) map[string]string {
// Apply .env file first
config := readEnvFile(filepath.Join(workingDir, ".env"))
// Apply env variables
for k, v := range envToMap(os.Environ()) {
config[k] = v
}
return config
}
func readEnvFile(path string) map[string]string {
config := map[string]string{}
file, err := os.Open(path)
if err != nil {
return config // Ignore
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(strings.TrimSpace(line), "#") {
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) == 2 {
key := parts[0]
value := parts[1]
config[key] = value
}
}
return config
}
func envToMap(env []string) map[string]string {
config := map[string]string{}
for _, value := range env {
parts := strings.SplitN(value, "=", 2)
key := parts[0]
value := parts[1]
config[key] = value
}
return config
}, nil
}

View File

@ -3,32 +3,44 @@ package kubernetes
import (
"testing"
"github.com/stretchr/testify/assert"
composetypes "github.com/docker/cli/cli/compose/types"
apiv1beta1 "github.com/docker/cli/kubernetes/compose/v1beta1"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestPlaceholders(t *testing.T) {
env := map[string]string{
"TAG": "_latest_",
"K1": "V1",
"K2": "V2",
}
prefix := "version: '3'\nvolumes:\n data:\n external:\n name: "
var tests = []struct {
input string
expectedOutput string
}{
{prefix + "BEFORE${TAG}AFTER", prefix + "BEFORE_latest_AFTER"},
{prefix + "BEFORE${K1}${K2}AFTER", prefix + "BEFOREV1V2AFTER"},
{prefix + "BEFORE$TAG AFTER", prefix + "BEFORE_latest_ AFTER"},
{prefix + "BEFORE$$TAG AFTER", prefix + "BEFORE$TAG AFTER"},
{prefix + "BEFORE $UNKNOWN AFTER", prefix + "BEFORE AFTER"},
}
for _, test := range tests {
output, _, err := load("stack", []byte(test.input), ".", env)
require.NoError(t, err)
assert.Equal(t, test.expectedOutput, output.Spec.ComposeFile)
}
func TestLoadStack(t *testing.T) {
s, err := LoadStack("foo", composetypes.Config{
Version: "3.1",
Filename: "banana",
Services: []composetypes.ServiceConfig{
{
Name: "foo",
Image: "foo",
},
{
Name: "bar",
Image: "bar",
},
},
})
require.NoError(t, err)
require.Equal(t, &apiv1beta1.Stack{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
},
Spec: apiv1beta1.StackSpec{
ComposeFile: string(`version: "3.1"
services:
bar:
image: bar
foo:
image: foo
networks: {}
volumes: {}
secrets: {}
configs: {}
`),
},
}, s)
}

View File

@ -0,0 +1,152 @@
package loader
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/stack/options"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/cli/compose/schema"
composetypes "github.com/docker/cli/cli/compose/types"
"github.com/pkg/errors"
)
// LoadComposefile parse the composefile specified in the cli and returns its Config and version.
func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.Config, error) {
configDetails, err := getConfigDetails(opts.Composefiles, dockerCli.In())
if err != nil {
return nil, err
}
dicts := getDictsFrom(configDetails.ConfigFiles)
config, err := loader.Load(configDetails)
if err != nil {
if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok {
return nil, errors.Errorf("Compose file contains unsupported options:\n\n%s\n",
propertyWarnings(fpe.Properties))
}
return nil, err
}
unsupportedProperties := loader.GetUnsupportedProperties(dicts...)
if len(unsupportedProperties) > 0 {
fmt.Fprintf(dockerCli.Err(), "Ignoring unsupported options: %s\n\n",
strings.Join(unsupportedProperties, ", "))
}
deprecatedProperties := loader.GetDeprecatedProperties(dicts...)
if len(deprecatedProperties) > 0 {
fmt.Fprintf(dockerCli.Err(), "Ignoring deprecated options:\n\n%s\n\n",
propertyWarnings(deprecatedProperties))
}
return config, nil
}
func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]interface{} {
dicts := []map[string]interface{}{}
for _, configFile := range configFiles {
dicts = append(dicts, configFile.Config)
}
return dicts
}
func propertyWarnings(properties map[string]string) string {
var msgs []string
for name, description := range properties {
msgs = append(msgs, fmt.Sprintf("%s: %s", name, description))
}
sort.Strings(msgs)
return strings.Join(msgs, "\n\n")
}
func getConfigDetails(composefiles []string, stdin io.Reader) (composetypes.ConfigDetails, error) {
var details composetypes.ConfigDetails
if len(composefiles) == 0 {
return details, errors.New("no composefile(s)")
}
if composefiles[0] == "-" && len(composefiles) == 1 {
workingDir, err := os.Getwd()
if err != nil {
return details, err
}
details.WorkingDir = workingDir
} else {
absPath, err := filepath.Abs(composefiles[0])
if err != nil {
return details, err
}
details.WorkingDir = filepath.Dir(absPath)
}
var err error
details.ConfigFiles, err = loadConfigFiles(composefiles, stdin)
if err != nil {
return details, err
}
// Take the first file version (2 files can't have different version)
details.Version = schema.Version(details.ConfigFiles[0].Config)
details.Environment, err = buildEnvironment(os.Environ())
return details, err
}
func buildEnvironment(env []string) (map[string]string, error) {
result := make(map[string]string, len(env))
for _, s := range env {
// if value is empty, s is like "K=", not "K".
if !strings.Contains(s, "=") {
return result, errors.Errorf("unexpected environment %q", s)
}
kv := strings.SplitN(s, "=", 2)
result[kv[0]] = kv[1]
}
return result, nil
}
func loadConfigFiles(filenames []string, stdin io.Reader) ([]composetypes.ConfigFile, error) {
var configFiles []composetypes.ConfigFile
for _, filename := range filenames {
configFile, err := loadConfigFile(filename, stdin)
if err != nil {
return configFiles, err
}
configFiles = append(configFiles, *configFile)
}
return configFiles, nil
}
func loadConfigFile(filename string, stdin io.Reader) (*composetypes.ConfigFile, error) {
var bytes []byte
var err error
if filename == "-" {
bytes, err = ioutil.ReadAll(stdin)
} else {
bytes, err = ioutil.ReadFile(filename)
}
if err != nil {
return nil, err
}
config, err := loader.ParseYAML(bytes)
if err != nil {
return nil, err
}
return &composetypes.ConfigFile{
Filename: filename,
Config: config,
}, nil
}

View File

@ -0,0 +1,47 @@
package loader
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetConfigDetails(t *testing.T) {
content := `
version: "3.0"
services:
foo:
image: alpine:3.5
`
file := fs.NewFile(t, "test-get-config-details", fs.WithContent(content))
defer file.Remove()
details, err := getConfigDetails([]string{file.Path()}, nil)
require.NoError(t, err)
assert.Equal(t, filepath.Dir(file.Path()), details.WorkingDir)
require.Len(t, details.ConfigFiles, 1)
assert.Equal(t, "3.0", details.ConfigFiles[0].Config["version"])
assert.Len(t, details.Environment, len(os.Environ()))
}
func TestGetConfigDetailsStdin(t *testing.T) {
content := `
version: "3.0"
services:
foo:
image: alpine:3.5
`
details, err := getConfigDetails([]string{"-"}, strings.NewReader(content))
require.NoError(t, err)
cwd, err := os.Getwd()
require.NoError(t, err)
assert.Equal(t, cwd, details.WorkingDir)
require.Len(t, details.ConfigFiles, 1)
assert.Equal(t, "3.0", details.ConfigFiles[0].Config["version"])
assert.Len(t, details.Environment, len(os.Environ()))
}

View File

@ -5,7 +5,7 @@ import "github.com/docker/cli/opts"
// Deploy holds docker stack deploy options
type Deploy struct {
Bundlefile string
Composefile string
Composefiles []string
Namespace string
ResolveImage string
SendRegistryAuth bool

View File

@ -29,9 +29,9 @@ func RunDeploy(dockerCli command.Cli, opts options.Deploy) error {
}
switch {
case opts.Bundlefile == "" && opts.Composefile == "":
case opts.Bundlefile == "" && len(opts.Composefiles) == 0:
return errors.Errorf("Please specify either a bundle file (with --bundle-file) or a Compose file (with --compose-file).")
case opts.Bundlefile != "" && opts.Composefile != "":
case opts.Bundlefile != "" && len(opts.Composefiles) != 0:
return errors.Errorf("You cannot specify both a bundle file and a Compose file.")
case opts.Bundlefile != "":
return deployBundle(ctx, dockerCli, opts)

View File

@ -2,17 +2,11 @@ package swarm
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/stack/loader"
"github.com/docker/cli/cli/command/stack/options"
"github.com/docker/cli/cli/compose/convert"
"github.com/docker/cli/cli/compose/loader"
composetypes "github.com/docker/cli/cli/compose/types"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
@ -24,33 +18,11 @@ import (
)
func deployCompose(ctx context.Context, dockerCli command.Cli, opts options.Deploy) error {
configDetails, err := getConfigDetails(opts.Composefile, dockerCli.In())
config, err := loader.LoadComposefile(dockerCli, opts)
if err != nil {
return err
}
config, err := loader.Load(configDetails)
if err != nil {
if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok {
return errors.Errorf("Compose file contains unsupported options:\n\n%s\n",
propertyWarnings(fpe.Properties))
}
return err
}
unsupportedProperties := loader.GetUnsupportedProperties(configDetails)
if len(unsupportedProperties) > 0 {
fmt.Fprintf(dockerCli.Err(), "Ignoring unsupported options: %s\n\n",
strings.Join(unsupportedProperties, ", "))
}
deprecatedProperties := loader.GetDeprecatedProperties(configDetails)
if len(deprecatedProperties) > 0 {
fmt.Fprintf(dockerCli.Err(), "Ignoring deprecated options:\n\n%s\n\n",
propertyWarnings(deprecatedProperties))
}
if err := checkDaemonIsSwarmManager(ctx, dockerCli); err != nil {
return err
}
@ -111,79 +83,6 @@ func getServicesDeclaredNetworks(serviceConfigs []composetypes.ServiceConfig) ma
return serviceNetworks
}
func propertyWarnings(properties map[string]string) string {
var msgs []string
for name, description := range properties {
msgs = append(msgs, fmt.Sprintf("%s: %s", name, description))
}
sort.Strings(msgs)
return strings.Join(msgs, "\n\n")
}
func getConfigDetails(composefile string, stdin io.Reader) (composetypes.ConfigDetails, error) {
var details composetypes.ConfigDetails
if composefile == "-" {
workingDir, err := os.Getwd()
if err != nil {
return details, err
}
details.WorkingDir = workingDir
} else {
absPath, err := filepath.Abs(composefile)
if err != nil {
return details, err
}
details.WorkingDir = filepath.Dir(absPath)
}
configFile, err := getConfigFile(composefile, stdin)
if err != nil {
return details, err
}
// TODO: support multiple files
details.ConfigFiles = []composetypes.ConfigFile{*configFile}
details.Environment, err = buildEnvironment(os.Environ())
return details, err
}
func buildEnvironment(env []string) (map[string]string, error) {
result := make(map[string]string, len(env))
for _, s := range env {
// if value is empty, s is like "K=", not "K".
if !strings.Contains(s, "=") {
return result, errors.Errorf("unexpected environment %q", s)
}
kv := strings.SplitN(s, "=", 2)
result[kv[0]] = kv[1]
}
return result, nil
}
func getConfigFile(filename string, stdin io.Reader) (*composetypes.ConfigFile, error) {
var bytes []byte
var err error
if filename == "-" {
bytes, err = ioutil.ReadAll(stdin)
} else {
bytes, err = ioutil.ReadFile(filename)
}
if err != nil {
return nil, err
}
config, err := loader.ParseYAML(bytes)
if err != nil {
return nil, err
}
return &composetypes.ConfigFile{
Filename: filename,
Config: config,
}, nil
}
func validateExternalNetworks(
ctx context.Context,
client dockerclient.NetworkAPIClient,

View File

@ -1,56 +1,16 @@
package swarm
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/docker/cli/internal/test/network"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestGetConfigDetails(t *testing.T) {
content := `
version: "3.0"
services:
foo:
image: alpine:3.5
`
file := fs.NewFile(t, "test-get-config-details", fs.WithContent(content))
defer file.Remove()
details, err := getConfigDetails(file.Path(), nil)
require.NoError(t, err)
assert.Equal(t, filepath.Dir(file.Path()), details.WorkingDir)
require.Len(t, details.ConfigFiles, 1)
assert.Equal(t, "3.0", details.ConfigFiles[0].Config["version"])
assert.Len(t, details.Environment, len(os.Environ()))
}
func TestGetConfigDetailsStdin(t *testing.T) {
content := `
version: "3.0"
services:
foo:
image: alpine:3.5
`
details, err := getConfigDetails("-", strings.NewReader(content))
require.NoError(t, err)
cwd, err := os.Getwd()
require.NoError(t, err)
assert.Equal(t, cwd, details.WorkingDir)
require.Len(t, details.ConfigFiles, 1)
assert.Equal(t, "3.0", details.ConfigFiles[0].Config["version"])
assert.Len(t, details.Environment, len(os.Environ()))
}
type notFound struct {
error
}

View File

@ -243,8 +243,5 @@ func addStagedSigner(notaryRepo client.Repository, newSigner data.RoleName, sign
if err := notaryRepo.AddDelegationRoleAndKeys(trust.ReleasesRole, signerKeys); err != nil {
return err
}
if err := notaryRepo.AddDelegationPaths(trust.ReleasesRole, []string{""}); err != nil {
return err
}
return nil
return notaryRepo.AddDelegationPaths(trust.ReleasesRole, []string{""})
}

View File

@ -131,8 +131,5 @@ func removeSingleSigner(cli command.Cli, repoName, signerName string, forceYes b
if err = notaryRepo.RemoveDelegationRole(signerDelegation); err != nil {
return err
}
if err = notaryRepo.Publish(); err != nil {
return err
}
return nil
return notaryRepo.Publish()
}

View File

@ -22,7 +22,7 @@ func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "prune [OPTIONS]",
Short: "Remove all unused volumes",
Short: "Remove all unused local volumes",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
spaceReclaimed, output, err := runPrune(dockerCli, options)
@ -45,7 +45,7 @@ func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}
const warning = `WARNING! This will remove all volumes not used by at least one container.
const warning = `WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue?`
func runPrune(dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) {

View File

@ -1,2 +1,2 @@
WARNING! This will remove all volumes not used by at least one container.
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] Total reclaimed space: 0B

View File

@ -1,4 +1,4 @@
WARNING! This will remove all volumes not used by at least one container.
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] Deleted Volumes:
foo
bar

View File

@ -22,43 +22,37 @@ func Volumes(serviceVolumes []composetypes.ServiceVolumeConfig, stackVolumes vol
return mounts, nil
}
func convertVolumeToMount(
func createMountFromVolume(volume composetypes.ServiceVolumeConfig) mount.Mount {
return mount.Mount{
Type: mount.Type(volume.Type),
Target: volume.Target,
ReadOnly: volume.ReadOnly,
Source: volume.Source,
Consistency: mount.Consistency(volume.Consistency),
}
}
func handleVolumeToMount(
volume composetypes.ServiceVolumeConfig,
stackVolumes volumes,
namespace Namespace,
) (mount.Mount, error) {
result := mount.Mount{
Type: mount.Type(volume.Type),
Source: volume.Source,
Target: volume.Target,
ReadOnly: volume.ReadOnly,
Consistency: mount.Consistency(volume.Consistency),
}
result := createMountFromVolume(volume)
if volume.Tmpfs != nil {
return mount.Mount{}, errors.New("tmpfs options are incompatible with type volume")
}
if volume.Bind != nil {
return mount.Mount{}, errors.New("bind options are incompatible with type volume")
}
// Anonymous volumes
if volume.Source == "" {
return result, nil
}
if volume.Type == "volume" && volume.Bind != nil {
return result, errors.New("bind options are incompatible with type volume")
}
if volume.Type == "bind" && volume.Volume != nil {
return result, errors.New("volume options are incompatible with type bind")
}
if volume.Bind != nil {
result.BindOptions = &mount.BindOptions{
Propagation: mount.Propagation(volume.Bind.Propagation),
}
}
// Binds volumes
if volume.Type == "bind" {
return result, nil
}
stackVolume, exists := stackVolumes[volume.Source]
if !exists {
return result, errors.Errorf("undefined volume %q", volume.Source)
return mount.Mount{}, errors.Errorf("undefined volume %q", volume.Source)
}
result.Source = namespace.Scope(volume.Source)
@ -85,6 +79,62 @@ func convertVolumeToMount(
}
}
// Named volumes
return result, nil
}
func handleBindToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {
result := createMountFromVolume(volume)
if volume.Source == "" {
return mount.Mount{}, errors.New("invalid bind source, source cannot be empty")
}
if volume.Volume != nil {
return mount.Mount{}, errors.New("volume options are incompatible with type bind")
}
if volume.Tmpfs != nil {
return mount.Mount{}, errors.New("tmpfs options are incompatible with type bind")
}
if volume.Bind != nil {
result.BindOptions = &mount.BindOptions{
Propagation: mount.Propagation(volume.Bind.Propagation),
}
}
return result, nil
}
func handleTmpfsToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {
result := createMountFromVolume(volume)
if volume.Source != "" {
return mount.Mount{}, errors.New("invalid tmpfs source, source must be empty")
}
if volume.Bind != nil {
return mount.Mount{}, errors.New("bind options are incompatible with type tmpfs")
}
if volume.Volume != nil {
return mount.Mount{}, errors.New("volume options are incompatible with type tmpfs")
}
if volume.Tmpfs != nil {
result.TmpfsOptions = &mount.TmpfsOptions{
SizeBytes: volume.Tmpfs.Size,
}
}
return result, nil
}
func convertVolumeToMount(
volume composetypes.ServiceVolumeConfig,
stackVolumes volumes,
namespace Namespace,
) (mount.Mount, error) {
switch volume.Type {
case "volume", "":
return handleVolumeToMount(volume, stackVolumes, namespace)
case "bind":
return handleBindToMount(volume)
case "tmpfs":
return handleTmpfsToMount(volume)
}
return mount.Mount{}, errors.New("volume type must be volume, bind, or tmpfs")
}

View File

@ -22,7 +22,28 @@ func TestConvertVolumeToMountAnonymousVolume(t *testing.T) {
assert.Equal(t, expected, mount)
}
func TestConvertVolumeToMountConflictingOptionsBind(t *testing.T) {
func TestConvertVolumeToMountAnonymousBind(t *testing.T) {
config := composetypes.ServiceVolumeConfig{
Type: "bind",
Target: "/foo/bar",
Bind: &composetypes.ServiceVolumeBind{
Propagation: "slave",
},
}
_, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo"))
assert.EqualError(t, err, "invalid bind source, source cannot be empty")
}
func TestConvertVolumeToMountUnapprovedType(t *testing.T) {
config := composetypes.ServiceVolumeConfig{
Type: "foo",
Target: "/foo/bar",
}
_, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo"))
assert.EqualError(t, err, "volume type must be volume, bind, or tmpfs")
}
func TestConvertVolumeToMountConflictingOptionsBindInVolume(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
@ -37,7 +58,22 @@ func TestConvertVolumeToMountConflictingOptionsBind(t *testing.T) {
assert.EqualError(t, err, "bind options are incompatible with type volume")
}
func TestConvertVolumeToMountConflictingOptionsVolume(t *testing.T) {
func TestConvertVolumeToMountConflictingOptionsTmpfsInVolume(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
Type: "volume",
Source: "foo",
Target: "/target",
Tmpfs: &composetypes.ServiceVolumeTmpfs{
Size: 1000,
},
}
_, err := convertVolumeToMount(config, volumes{}, namespace)
assert.EqualError(t, err, "tmpfs options are incompatible with type volume")
}
func TestConvertVolumeToMountConflictingOptionsVolumeInBind(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
@ -52,6 +88,49 @@ func TestConvertVolumeToMountConflictingOptionsVolume(t *testing.T) {
assert.EqualError(t, err, "volume options are incompatible with type bind")
}
func TestConvertVolumeToMountConflictingOptionsTmpfsInBind(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
Type: "bind",
Source: "/foo",
Target: "/target",
Tmpfs: &composetypes.ServiceVolumeTmpfs{
Size: 1000,
},
}
_, err := convertVolumeToMount(config, volumes{}, namespace)
assert.EqualError(t, err, "tmpfs options are incompatible with type bind")
}
func TestConvertVolumeToMountConflictingOptionsBindInTmpfs(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
Type: "tmpfs",
Target: "/target",
Bind: &composetypes.ServiceVolumeBind{
Propagation: "slave",
},
}
_, err := convertVolumeToMount(config, volumes{}, namespace)
assert.EqualError(t, err, "bind options are incompatible with type tmpfs")
}
func TestConvertVolumeToMountConflictingOptionsVolumeInTmpfs(t *testing.T) {
namespace := NewNamespace("foo")
config := composetypes.ServiceVolumeConfig{
Type: "tmpfs",
Target: "/target",
Volume: &composetypes.ServiceVolumeVolume{
NoCopy: true,
},
}
_, err := convertVolumeToMount(config, volumes{}, namespace)
assert.EqualError(t, err, "volume options are incompatible with type tmpfs")
}
func TestConvertVolumeToMountNamedVolume(t *testing.T) {
stackVolumes := volumes{
"normal": composetypes.VolumeConfig{
@ -231,3 +310,35 @@ func TestConvertVolumeToMountVolumeDoesNotExist(t *testing.T) {
_, err := convertVolumeToMount(config, volumes{}, namespace)
assert.EqualError(t, err, "undefined volume \"unknown\"")
}
func TestConvertTmpfsToMountVolume(t *testing.T) {
config := composetypes.ServiceVolumeConfig{
Type: "tmpfs",
Target: "/foo/bar",
Tmpfs: &composetypes.ServiceVolumeTmpfs{
Size: 1000,
},
}
expected := mount.Mount{
Type: mount.TypeTmpfs,
Target: "/foo/bar",
TmpfsOptions: &mount.TmpfsOptions{SizeBytes: 1000},
}
mount, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo"))
assert.NoError(t, err)
assert.Equal(t, expected, mount)
}
func TestConvertTmpfsToMountVolumeWithSource(t *testing.T) {
config := composetypes.ServiceVolumeConfig{
Type: "tmpfs",
Source: "/bar",
Target: "/foo/bar",
Tmpfs: &composetypes.ServiceVolumeTmpfs{
Size: 1000,
},
}
_, err := convertVolumeToMount(config, volumes{}, NewNamespace("foo"))
assert.EqualError(t, err, "invalid tmpfs source, source must be empty")
}

View File

@ -1,4 +1,4 @@
version: "3.5"
version: "3.6"
services:
foo:
@ -10,7 +10,7 @@ services:
foo: bar
target: foo
network: foo
cache_from:
cache_from:
- foo
- bar
labels: [FOO=BAR]
@ -193,7 +193,7 @@ services:
ports:
- 3000
- "3000-3005"
- "3001-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
@ -249,6 +249,10 @@ services:
source: ./opt
target: /opt
consistency: cached
- type: tmpfs
target: /opt
tmpfs:
size: 10000
working_dir: /code

View File

@ -0,0 +1,391 @@
package loader
import (
"time"
"github.com/docker/cli/cli/compose/types"
)
func fullExampleConfig(workingDir, homeDir string) *types.Config {
return &types.Config{
Version: "3.6",
Services: services(workingDir, homeDir),
Networks: networks(),
Volumes: volumes(),
}
}
func services(workingDir, homeDir string) []types.ServiceConfig {
return []types.ServiceConfig{
{
Name: "foo",
Build: types.BuildConfig{
Context: "./dir",
Dockerfile: "Dockerfile",
Args: map[string]*string{"foo": strPtr("bar")},
Target: "foo",
Network: "foo",
CacheFrom: []string{"foo", "bar"},
Labels: map[string]string{"FOO": "BAR"},
},
CapAdd: []string{"ALL"},
CapDrop: []string{"NET_ADMIN", "SYS_ADMIN"},
CgroupParent: "m-executor-abcd",
Command: []string{"bundle", "exec", "thin", "-p", "3000"},
ContainerName: "my-web-container",
DependsOn: []string{"db", "redis"},
Deploy: types.DeployConfig{
Mode: "replicated",
Replicas: uint64Ptr(6),
Labels: map[string]string{"FOO": "BAR"},
UpdateConfig: &types.UpdateConfig{
Parallelism: uint64Ptr(3),
Delay: time.Duration(10 * time.Second),
FailureAction: "continue",
Monitor: time.Duration(60 * time.Second),
MaxFailureRatio: 0.3,
Order: "start-first",
},
Resources: types.Resources{
Limits: &types.Resource{
NanoCPUs: "0.001",
MemoryBytes: 50 * 1024 * 1024,
},
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{
Condition: "on-failure",
Delay: durationPtr(5 * time.Second),
MaxAttempts: uint64Ptr(3),
Window: durationPtr(2 * time.Minute),
},
Placement: types.Placement{
Constraints: []string{"node=foo"},
Preferences: []types.PlacementPreferences{
{
Spread: "node.labels.az",
},
},
},
EndpointMode: "dnsrr",
},
Devices: []string{"/dev/ttyUSB0:/dev/ttyUSB0"},
DNS: []string{"8.8.8.8", "9.9.9.9"},
DNSSearch: []string{"dc1.example.com", "dc2.example.com"},
DomainName: "foo.com",
Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"},
Environment: map[string]*string{
"FOO": strPtr("foo_from_env_file"),
"BAR": strPtr("bar_from_env_file_2"),
"BAZ": strPtr("baz_from_service_def"),
"QUX": strPtr("qux_from_environment"),
},
EnvFile: []string{
"./example1.env",
"./example2.env",
},
Expose: []string{"3000", "8000"},
ExternalLinks: []string{
"redis_1",
"project_db_1:mysql",
"project_db_1:postgresql",
},
ExtraHosts: []string{
"somehost:162.242.195.82",
"otherhost:50.31.209.229",
},
HealthCheck: &types.HealthCheckConfig{
Test: types.HealthCheckTest([]string{"CMD-SHELL", "echo \"hello world\""}),
Interval: durationPtr(10 * time.Second),
Timeout: durationPtr(1 * time.Second),
Retries: uint64Ptr(5),
StartPeriod: durationPtr(15 * time.Second),
},
Hostname: "foo",
Image: "redis",
Ipc: "host",
Labels: map[string]string{
"com.example.description": "Accounting webapp",
"com.example.number": "42",
"com.example.empty-label": "",
},
Links: []string{
"db",
"db:database",
"redis",
},
Logging: &types.LoggingConfig{
Driver: "syslog",
Options: map[string]string{
"syslog-address": "tcp://192.168.0.42:123",
},
},
MacAddress: "02:42:ac:11:65:43",
NetworkMode: "container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b",
Networks: map[string]*types.ServiceNetworkConfig{
"some-network": {
Aliases: []string{"alias1", "alias3"},
Ipv4Address: "",
Ipv6Address: "",
},
"other-network": {
Ipv4Address: "172.16.238.10",
Ipv6Address: "2001:3984:3989::10",
},
"other-other-network": nil,
},
Pid: "host",
Ports: []types.ServicePortConfig{
//"3000",
{
Mode: "ingress",
Target: 3000,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3001,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3002,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3003,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3004,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3005,
Protocol: "tcp",
},
//"8000:8000",
{
Mode: "ingress",
Target: 8000,
Published: 8000,
Protocol: "tcp",
},
//"9090-9091:8080-8081",
{
Mode: "ingress",
Target: 8080,
Published: 9090,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 8081,
Published: 9091,
Protocol: "tcp",
},
//"49100:22",
{
Mode: "ingress",
Target: 22,
Published: 49100,
Protocol: "tcp",
},
//"127.0.0.1:8001:8001",
{
Mode: "ingress",
Target: 8001,
Published: 8001,
Protocol: "tcp",
},
//"127.0.0.1:5000-5010:5000-5010",
{
Mode: "ingress",
Target: 5000,
Published: 5000,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5001,
Published: 5001,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5002,
Published: 5002,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5003,
Published: 5003,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5004,
Published: 5004,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5005,
Published: 5005,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5006,
Published: 5006,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5007,
Published: 5007,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5008,
Published: 5008,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5009,
Published: 5009,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5010,
Published: 5010,
Protocol: "tcp",
},
},
Privileged: true,
ReadOnly: true,
Restart: "always",
SecurityOpt: []string{
"label=level:s0:c100,c200",
"label=type:svirt_apache_t",
},
StdinOpen: true,
StopSignal: "SIGUSR1",
StopGracePeriod: durationPtr(time.Duration(20 * time.Second)),
Tmpfs: []string{"/run", "/tmp"},
Tty: true,
Ulimits: map[string]*types.UlimitsConfig{
"nproc": {
Single: 65535,
},
"nofile": {
Soft: 20000,
Hard: 40000,
},
},
User: "someone",
Volumes: []types.ServiceVolumeConfig{
{Target: "/var/lib/mysql", Type: "volume"},
{Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"},
{Source: workingDir, Target: "/code", Type: "bind"},
{Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"},
{Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true},
{Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"},
{Source: workingDir + "/opt", Target: "/opt", Consistency: "cached", Type: "bind"},
{Target: "/opt", Type: "tmpfs", Tmpfs: &types.ServiceVolumeTmpfs{
Size: int64(10000),
}},
},
WorkingDir: "/code",
},
}
}
func networks() map[string]types.NetworkConfig {
return map[string]types.NetworkConfig{
"some-network": {},
"other-network": {
Driver: "overlay",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
Ipam: types.IPAMConfig{
Driver: "overlay",
Config: []*types.IPAMPool{
{Subnet: "172.16.238.0/24"},
{Subnet: "2001:3984:3989::/64"},
},
},
},
"external-network": {
Name: "external-network",
External: types.External{External: true},
},
"other-external-network": {
Name: "my-cool-network",
External: types.External{External: true},
},
}
}
func volumes() map[string]types.VolumeConfig {
return map[string]types.VolumeConfig{
"some-volume": {},
"other-volume": {
Driver: "flocker",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
},
"another-volume": {
Name: "user_specified_name",
Driver: "vsphere",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
},
"external-volume": {
Name: "external-volume",
External: types.External{External: true},
},
"other-external-volume": {
Name: "my-cool-volume",
External: types.External{External: true},
},
"external-volume3": {
Name: "this-is-volume3",
External: types.External{External: true},
},
}
}

View File

@ -45,27 +45,43 @@ func Load(configDetails types.ConfigDetails) (*types.Config, error) {
if len(configDetails.ConfigFiles) < 1 {
return nil, errors.Errorf("No files specified")
}
if len(configDetails.ConfigFiles) > 1 {
return nil, errors.Errorf("Multiple files are not yet supported")
configs := []*types.Config{}
for _, file := range configDetails.ConfigFiles {
configDict := file.Config
version := schema.Version(configDict)
if configDetails.Version == "" {
configDetails.Version = version
}
if configDetails.Version != version {
return nil, errors.Errorf("version mismatched between two composefiles : %v and %v", configDetails.Version, version)
}
if err := validateForbidden(configDict); err != nil {
return nil, err
}
var err error
configDict, err = interpolateConfig(configDict, configDetails.LookupEnv)
if err != nil {
return nil, err
}
if err := schema.Validate(configDict, configDetails.Version); err != nil {
return nil, err
}
cfg, err := loadSections(configDict, configDetails)
if err != nil {
return nil, err
}
cfg.Filename = file.Filename
configs = append(configs, cfg)
}
configDict := getConfigDict(configDetails)
configDetails.Version = schema.Version(configDict)
if err := validateForbidden(configDict); err != nil {
return nil, err
}
var err error
configDict, err = interpolateConfig(configDict, configDetails.LookupEnv)
if err != nil {
return nil, err
}
if err := schema.Validate(configDict, configDetails.Version); err != nil {
return nil, err
}
return loadSections(configDict, configDetails)
return merge(configs)
}
func validateForbidden(configDict map[string]interface{}) error {
@ -82,7 +98,9 @@ func validateForbidden(configDict map[string]interface{}) error {
func loadSections(config map[string]interface{}, configDetails types.ConfigDetails) (*types.Config, error) {
var err error
cfg := types.Config{}
cfg := types.Config{
Version: schema.Version(config),
}
var loaders = []struct {
key string
@ -142,14 +160,16 @@ func getSection(config map[string]interface{}, key string) map[string]interface{
// GetUnsupportedProperties returns the list of any unsupported properties that are
// used in the Compose files.
func GetUnsupportedProperties(configDetails types.ConfigDetails) []string {
func GetUnsupportedProperties(configDicts ...map[string]interface{}) []string {
unsupported := map[string]bool{}
for _, service := range getServices(getConfigDict(configDetails)) {
serviceDict := service.(map[string]interface{})
for _, property := range types.UnsupportedProperties {
if _, isSet := serviceDict[property]; isSet {
unsupported[property] = true
for _, configDict := range configDicts {
for _, service := range getServices(configDict) {
serviceDict := service.(map[string]interface{})
for _, property := range types.UnsupportedProperties {
if _, isSet := serviceDict[property]; isSet {
unsupported[property] = true
}
}
}
}
@ -168,8 +188,17 @@ func sortedKeys(set map[string]bool) []string {
// GetDeprecatedProperties returns the list of any deprecated properties that
// are used in the compose files.
func GetDeprecatedProperties(configDetails types.ConfigDetails) map[string]string {
return getProperties(getServices(getConfigDict(configDetails)), types.DeprecatedProperties)
func GetDeprecatedProperties(configDicts ...map[string]interface{}) map[string]string {
deprecated := map[string]string{}
for _, configDict := range configDicts {
deprecatedProperties := getProperties(getServices(configDict), types.DeprecatedProperties)
for key, value := range deprecatedProperties {
deprecated[key] = value
}
}
return deprecated
}
func getProperties(services map[string]interface{}, propertyMap map[string]string) map[string]string {
@ -198,11 +227,6 @@ func (e *ForbiddenPropertiesError) Error() string {
return "Configuration contains forbidden properties"
}
// TODO: resolve multiple files into a single config
func getConfigDict(configDetails types.ConfigDetails) map[string]interface{} {
return configDetails.ConfigFiles[0].Config
}
func getServices(configDict map[string]interface{}) map[string]interface{} {
if services, ok := configDict["services"]; ok {
if servicesDict, ok := services.(map[string]interface{}); ok {
@ -337,7 +361,9 @@ func LoadService(name string, serviceDict map[string]interface{}, workingDir str
return nil, err
}
resolveVolumePaths(serviceConfig.Volumes, workingDir, lookupEnv)
if err := resolveVolumePaths(serviceConfig.Volumes, workingDir, lookupEnv); err != nil {
return nil, err
}
return serviceConfig, nil
}
@ -376,12 +402,16 @@ func resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, l
return nil
}
func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string, lookupEnv template.Mapping) {
func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string, lookupEnv template.Mapping) error {
for i, volume := range volumes {
if volume.Type != "bind" {
continue
}
if volume.Source == "" {
return errors.New(`invalid mount config for type "bind": field Source must not be empty`)
}
filePath := expandUser(volume.Source, lookupEnv)
// Check for a Unix absolute path first, to handle a Windows client
// with a Unix daemon. This handles a Windows client connecting to a
@ -394,6 +424,7 @@ func resolveVolumePaths(volumes []types.ServiceVolumeConfig, workingDir string,
volume.Source = filePath
volumes[i] = volume
}
return nil
}
// TODO: make this more robust

View File

@ -119,6 +119,7 @@ func strPtr(val string) *string {
}
var sampleConfig = types.Config{
Version: "3.0",
Services: []types.ServiceConfig{
{
Name: "foo",
@ -174,6 +175,7 @@ func TestParseYAML(t *testing.T) {
func TestLoad(t *testing.T) {
actual, err := Load(buildConfigDetails(sampleDict, nil))
require.NoError(t, err)
assert.Equal(t, sampleConfig.Version, actual.Version)
assert.Equal(t, serviceSort(sampleConfig.Services), serviceSort(actual.Services))
assert.Equal(t, sampleConfig.Networks, actual.Networks)
assert.Equal(t, sampleConfig.Volumes, actual.Volumes)
@ -572,6 +574,8 @@ networks:
config, err := Load(buildConfigDetails(dict, env))
require.NoError(t, err)
expected := &types.Config{
Filename: "filename.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "web",
@ -670,7 +674,7 @@ services:
_, err = Load(configDetails)
require.NoError(t, err)
unsupported := GetUnsupportedProperties(configDetails)
unsupported := GetUnsupportedProperties(dict)
assert.Equal(t, []string{"build", "links", "pid"}, unsupported)
}
@ -713,7 +717,7 @@ services:
_, err = Load(configDetails)
require.NoError(t, err)
deprecated := GetDeprecatedProperties(configDetails)
deprecated := GetDeprecatedProperties(dict)
assert.Len(t, deprecated, 2)
assert.Contains(t, deprecated, "container_name")
assert.Contains(t, deprecated, "expose")
@ -841,383 +845,151 @@ func TestFullExample(t *testing.T) {
workingDir, err := os.Getwd()
require.NoError(t, err)
stopGracePeriod := time.Duration(20 * time.Second)
expectedConfig := fullExampleConfig(workingDir, homeDir)
expectedServiceConfig := types.ServiceConfig{
Name: "foo",
assert.Equal(t, expectedConfig.Services, config.Services)
assert.Equal(t, expectedConfig.Networks, config.Networks)
assert.Equal(t, expectedConfig.Volumes, config.Volumes)
}
Build: types.BuildConfig{
Context: "./dir",
Dockerfile: "Dockerfile",
Args: map[string]*string{"foo": strPtr("bar")},
Target: "foo",
Network: "foo",
CacheFrom: []string{"foo", "bar"},
Labels: map[string]string{"FOO": "BAR"},
},
CapAdd: []string{"ALL"},
CapDrop: []string{"NET_ADMIN", "SYS_ADMIN"},
CgroupParent: "m-executor-abcd",
Command: []string{"bundle", "exec", "thin", "-p", "3000"},
ContainerName: "my-web-container",
DependsOn: []string{"db", "redis"},
Deploy: types.DeployConfig{
Mode: "replicated",
Replicas: uint64Ptr(6),
Labels: map[string]string{"FOO": "BAR"},
UpdateConfig: &types.UpdateConfig{
Parallelism: uint64Ptr(3),
Delay: time.Duration(10 * time.Second),
FailureAction: "continue",
Monitor: time.Duration(60 * time.Second),
MaxFailureRatio: 0.3,
Order: "start-first",
},
Resources: types.Resources{
Limits: &types.Resource{
NanoCPUs: "0.001",
MemoryBytes: 50 * 1024 * 1024,
},
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{
Condition: "on-failure",
Delay: durationPtr(5 * time.Second),
MaxAttempts: uint64Ptr(3),
Window: durationPtr(2 * time.Minute),
},
Placement: types.Placement{
Constraints: []string{"node=foo"},
Preferences: []types.PlacementPreferences{
{
Spread: "node.labels.az",
},
},
},
EndpointMode: "dnsrr",
},
Devices: []string{"/dev/ttyUSB0:/dev/ttyUSB0"},
DNS: []string{"8.8.8.8", "9.9.9.9"},
DNSSearch: []string{"dc1.example.com", "dc2.example.com"},
DomainName: "foo.com",
Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"},
Environment: map[string]*string{
"FOO": strPtr("foo_from_env_file"),
"BAR": strPtr("bar_from_env_file_2"),
"BAZ": strPtr("baz_from_service_def"),
"QUX": strPtr("qux_from_environment"),
},
EnvFile: []string{
"./example1.env",
"./example2.env",
},
Expose: []string{"3000", "8000"},
ExternalLinks: []string{
"redis_1",
"project_db_1:mysql",
"project_db_1:postgresql",
},
ExtraHosts: []string{
"somehost:162.242.195.82",
"otherhost:50.31.209.229",
},
HealthCheck: &types.HealthCheckConfig{
Test: types.HealthCheckTest([]string{"CMD-SHELL", "echo \"hello world\""}),
Interval: durationPtr(10 * time.Second),
Timeout: durationPtr(1 * time.Second),
Retries: uint64Ptr(5),
StartPeriod: durationPtr(15 * time.Second),
},
Hostname: "foo",
Image: "redis",
Ipc: "host",
Labels: map[string]string{
"com.example.description": "Accounting webapp",
"com.example.number": "42",
"com.example.empty-label": "",
},
Links: []string{
"db",
"db:database",
"redis",
},
Logging: &types.LoggingConfig{
Driver: "syslog",
Options: map[string]string{
"syslog-address": "tcp://192.168.0.42:123",
},
},
MacAddress: "02:42:ac:11:65:43",
NetworkMode: "container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b",
Networks: map[string]*types.ServiceNetworkConfig{
"some-network": {
Aliases: []string{"alias1", "alias3"},
Ipv4Address: "",
Ipv6Address: "",
},
"other-network": {
Ipv4Address: "172.16.238.10",
Ipv6Address: "2001:3984:3989::10",
},
"other-other-network": nil,
},
Pid: "host",
Ports: []types.ServicePortConfig{
//"3000",
{
Mode: "ingress",
Target: 3000,
Protocol: "tcp",
},
//"3000-3005",
{
Mode: "ingress",
Target: 3000,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3001,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3002,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3003,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3004,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 3005,
Protocol: "tcp",
},
//"8000:8000",
{
Mode: "ingress",
Target: 8000,
Published: 8000,
Protocol: "tcp",
},
//"9090-9091:8080-8081",
{
Mode: "ingress",
Target: 8080,
Published: 9090,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 8081,
Published: 9091,
Protocol: "tcp",
},
//"49100:22",
{
Mode: "ingress",
Target: 22,
Published: 49100,
Protocol: "tcp",
},
//"127.0.0.1:8001:8001",
{
Mode: "ingress",
Target: 8001,
Published: 8001,
Protocol: "tcp",
},
//"127.0.0.1:5000-5010:5000-5010",
{
Mode: "ingress",
Target: 5000,
Published: 5000,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5001,
Published: 5001,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5002,
Published: 5002,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5003,
Published: 5003,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5004,
Published: 5004,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5005,
Published: 5005,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5006,
Published: 5006,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5007,
Published: 5007,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5008,
Published: 5008,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5009,
Published: 5009,
Protocol: "tcp",
},
{
Mode: "ingress",
Target: 5010,
Published: 5010,
Protocol: "tcp",
},
},
Privileged: true,
ReadOnly: true,
Restart: "always",
SecurityOpt: []string{
"label=level:s0:c100,c200",
"label=type:svirt_apache_t",
},
StdinOpen: true,
StopSignal: "SIGUSR1",
StopGracePeriod: &stopGracePeriod,
Tmpfs: []string{"/run", "/tmp"},
Tty: true,
Ulimits: map[string]*types.UlimitsConfig{
"nproc": {
Single: 65535,
},
"nofile": {
Soft: 20000,
Hard: 40000,
},
},
User: "someone",
Volumes: []types.ServiceVolumeConfig{
{Target: "/var/lib/mysql", Type: "volume"},
{Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind"},
{Source: workingDir, Target: "/code", Type: "bind"},
{Source: workingDir + "/static", Target: "/var/www/html", Type: "bind"},
{Source: homeDir + "/configs", Target: "/etc/configs/", Type: "bind", ReadOnly: true},
{Source: "datavolume", Target: "/var/lib/mysql", Type: "volume"},
{Source: workingDir + "/opt", Target: "/opt", Consistency: "cached", Type: "bind"},
},
WorkingDir: "/code",
}
func TestLoadTmpfsVolume(t *testing.T) {
config, err := loadYAML(`
version: "3.6"
services:
tmpfs:
image: nginx:latest
volumes:
- type: tmpfs
target: /app
tmpfs:
size: 10000
`)
require.NoError(t, err)
assert.Equal(t, []types.ServiceConfig{expectedServiceConfig}, config.Services)
expectedNetworkConfig := map[string]types.NetworkConfig{
"some-network": {},
"other-network": {
Driver: "overlay",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
Ipam: types.IPAMConfig{
Driver: "overlay",
Config: []*types.IPAMPool{
{Subnet: "172.16.238.0/24"},
{Subnet: "2001:3984:3989::/64"},
},
},
},
"external-network": {
Name: "external-network",
External: types.External{External: true},
},
"other-external-network": {
Name: "my-cool-network",
External: types.External{External: true},
expected := types.ServiceVolumeConfig{
Target: "/app",
Type: "tmpfs",
Tmpfs: &types.ServiceVolumeTmpfs{
Size: int64(10000),
},
}
assert.Equal(t, expectedNetworkConfig, config.Networks)
require.Len(t, config.Services, 1)
assert.Len(t, config.Services[0].Volumes, 1)
assert.Equal(t, expected, config.Services[0].Volumes[0])
}
expectedVolumeConfig := map[string]types.VolumeConfig{
"some-volume": {},
"other-volume": {
Driver: "flocker",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
},
"another-volume": {
Name: "user_specified_name",
Driver: "vsphere",
DriverOpts: map[string]string{
"foo": "bar",
"baz": "1",
},
},
"external-volume": {
Name: "external-volume",
External: types.External{External: true},
},
"other-external-volume": {
Name: "my-cool-volume",
External: types.External{External: true},
},
"external-volume3": {
Name: "this-is-volume3",
External: types.External{External: true},
},
func TestLoadTmpfsVolumeAdditionalPropertyNotAllowed(t *testing.T) {
_, err := loadYAML(`
version: "3.5"
services:
tmpfs:
image: nginx:latest
volumes:
- type: tmpfs
target: /app
tmpfs:
size: 10000
`)
require.Error(t, err)
assert.Contains(t, err.Error(), "services.tmpfs.volumes.0 Additional property tmpfs is not allowed")
}
func TestLoadBindMountSourceMustNotBeEmpty(t *testing.T) {
_, err := loadYAML(`
version: "3.5"
services:
tmpfs:
image: nginx:latest
volumes:
- type: bind
target: /app
`)
require.EqualError(t, err, `invalid mount config for type "bind": field Source must not be empty`)
}
func TestLoadBindMountWithSource(t *testing.T) {
config, err := loadYAML(`
version: "3.5"
services:
bind:
image: nginx:latest
volumes:
- type: bind
target: /app
source: "."
`)
require.NoError(t, err)
workingDir, err := os.Getwd()
require.NoError(t, err)
expected := types.ServiceVolumeConfig{
Type: "bind",
Source: workingDir,
Target: "/app",
}
assert.Equal(t, expectedVolumeConfig, config.Volumes)
require.Len(t, config.Services, 1)
assert.Len(t, config.Services[0].Volumes, 1)
assert.Equal(t, expected, config.Services[0].Volumes[0])
}
func TestLoadTmpfsVolumeSizeCanBeZero(t *testing.T) {
config, err := loadYAML(`
version: "3.6"
services:
tmpfs:
image: nginx:latest
volumes:
- type: tmpfs
target: /app
tmpfs:
size: 0
`)
require.NoError(t, err)
expected := types.ServiceVolumeConfig{
Target: "/app",
Type: "tmpfs",
Tmpfs: &types.ServiceVolumeTmpfs{},
}
require.Len(t, config.Services, 1)
assert.Len(t, config.Services[0].Volumes, 1)
assert.Equal(t, expected, config.Services[0].Volumes[0])
}
func TestLoadTmpfsVolumeSizeMustBeGTEQZero(t *testing.T) {
_, err := loadYAML(`
version: "3.6"
services:
tmpfs:
image: nginx:latest
volumes:
- type: tmpfs
target: /app
tmpfs:
size: -1
`)
require.Error(t, err)
assert.Contains(t, err.Error(), "services.tmpfs.volumes.0.tmpfs.size Must be greater than or equal to 0")
}
func TestLoadTmpfsVolumeSizeMustBeInteger(t *testing.T) {
_, err := loadYAML(`
version: "3.6"
services:
tmpfs:
image: nginx:latest
volumes:
- type: tmpfs
target: /app
tmpfs:
size: 0.0001
`)
require.Error(t, err)
assert.Contains(t, err.Error(), "services.tmpfs.volumes.0.tmpfs.size must be a integer")
}
func serviceSort(services []types.ServiceConfig) []types.ServiceConfig {

View File

@ -0,0 +1,233 @@
package loader
import (
"reflect"
"sort"
"github.com/docker/cli/cli/compose/types"
"github.com/imdario/mergo"
"github.com/pkg/errors"
)
type specials struct {
m map[reflect.Type]func(dst, src reflect.Value) error
}
func (s *specials) Transformer(t reflect.Type) func(dst, src reflect.Value) error {
if fn, ok := s.m[t]; ok {
return fn
}
return nil
}
func merge(configs []*types.Config) (*types.Config, error) {
base := configs[0]
for _, override := range configs[1:] {
var err error
base.Services, err = mergeServices(base.Services, override.Services)
if err != nil {
return base, errors.Wrapf(err, "cannot merge services from %s", override.Filename)
}
base.Volumes, err = mergeVolumes(base.Volumes, override.Volumes)
if err != nil {
return base, errors.Wrapf(err, "cannot merge volumes from %s", override.Filename)
}
base.Networks, err = mergeNetworks(base.Networks, override.Networks)
if err != nil {
return base, errors.Wrapf(err, "cannot merge networks from %s", override.Filename)
}
base.Secrets, err = mergeSecrets(base.Secrets, override.Secrets)
if err != nil {
return base, errors.Wrapf(err, "cannot merge secrets from %s", override.Filename)
}
base.Configs, err = mergeConfigs(base.Configs, override.Configs)
if err != nil {
return base, errors.Wrapf(err, "cannot merge configs from %s", override.Filename)
}
}
return base, nil
}
func mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, error) {
baseServices := mapByName(base)
overrideServices := mapByName(override)
specials := &specials{
m: map[reflect.Type]func(dst, src reflect.Value) error{
reflect.TypeOf(&types.LoggingConfig{}): safelyMerge(mergeLoggingConfig),
reflect.TypeOf([]types.ServicePortConfig{}): mergeSlice(toServicePortConfigsMap, toServicePortConfigsSlice),
reflect.TypeOf([]types.ServiceSecretConfig{}): mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),
reflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),
},
}
for name, overrideService := range overrideServices {
if baseService, ok := baseServices[name]; ok {
if err := mergo.Merge(&baseService, &overrideService, mergo.WithOverride, mergo.WithTransformers(specials)); err != nil {
return base, errors.Wrapf(err, "cannot merge service %s", name)
}
baseServices[name] = baseService
continue
}
baseServices[name] = overrideService
}
services := []types.ServiceConfig{}
for _, baseService := range baseServices {
services = append(services, baseService)
}
sort.Slice(services, func(i, j int) bool { return services[i].Name < services[j].Name })
return services, nil
}
func toServiceSecretConfigsMap(s interface{}) (map[interface{}]interface{}, error) {
secrets, ok := s.([]types.ServiceSecretConfig)
if !ok {
return nil, errors.Errorf("not a serviceSecretConfig: %v", s)
}
m := map[interface{}]interface{}{}
for _, secret := range secrets {
m[secret.Source] = secret
}
return m, nil
}
func toServiceConfigObjConfigsMap(s interface{}) (map[interface{}]interface{}, error) {
secrets, ok := s.([]types.ServiceConfigObjConfig)
if !ok {
return nil, errors.Errorf("not a serviceSecretConfig: %v", s)
}
m := map[interface{}]interface{}{}
for _, secret := range secrets {
m[secret.Source] = secret
}
return m, nil
}
func toServicePortConfigsMap(s interface{}) (map[interface{}]interface{}, error) {
ports, ok := s.([]types.ServicePortConfig)
if !ok {
return nil, errors.Errorf("not a servicePortConfig slice: %v", s)
}
m := map[interface{}]interface{}{}
for _, p := range ports {
m[p.Published] = p
}
return m, nil
}
func toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
s := []types.ServiceSecretConfig{}
for _, v := range m {
s = append(s, v.(types.ServiceSecretConfig))
}
sort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })
dst.Set(reflect.ValueOf(s))
return nil
}
func toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
s := []types.ServiceConfigObjConfig{}
for _, v := range m {
s = append(s, v.(types.ServiceConfigObjConfig))
}
sort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })
dst.Set(reflect.ValueOf(s))
return nil
}
func toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {
s := []types.ServicePortConfig{}
for _, v := range m {
s = append(s, v.(types.ServicePortConfig))
}
sort.Slice(s, func(i, j int) bool { return s[i].Published < s[j].Published })
dst.Set(reflect.ValueOf(s))
return nil
}
type tomapFn func(s interface{}) (map[interface{}]interface{}, error)
type writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error
func safelyMerge(mergeFn func(dst, src reflect.Value) error) func(dst, src reflect.Value) error {
return func(dst, src reflect.Value) error {
if src.IsNil() {
return nil
}
if dst.IsNil() {
dst.Set(src)
return nil
}
return mergeFn(dst, src)
}
}
func mergeSlice(tomap tomapFn, writeValue writeValueFromMapFn) func(dst, src reflect.Value) error {
return func(dst, src reflect.Value) error {
dstMap, err := sliceToMap(tomap, dst)
if err != nil {
return err
}
srcMap, err := sliceToMap(tomap, src)
if err != nil {
return err
}
if err := mergo.Map(&dstMap, srcMap, mergo.WithOverride); err != nil {
return err
}
return writeValue(dst, dstMap)
}
}
func sliceToMap(tomap tomapFn, v reflect.Value) (map[interface{}]interface{}, error) {
// check if valid
if !v.IsValid() {
return nil, errors.Errorf("invalid value : %+v", v)
}
return tomap(v.Interface())
}
func mergeLoggingConfig(dst, src reflect.Value) error {
// Same driver, merging options
if getLoggingDriver(dst.Elem()) == getLoggingDriver(src.Elem()) ||
getLoggingDriver(dst.Elem()) == "" || getLoggingDriver(src.Elem()) == "" {
if getLoggingDriver(dst.Elem()) == "" {
dst.Elem().FieldByName("Driver").SetString(getLoggingDriver(src.Elem()))
}
dstOptions := dst.Elem().FieldByName("Options").Interface().(map[string]string)
srcOptions := src.Elem().FieldByName("Options").Interface().(map[string]string)
return mergo.Merge(&dstOptions, srcOptions, mergo.WithOverride)
}
// Different driver, override with src
dst.Set(src)
return nil
}
func getLoggingDriver(v reflect.Value) string {
return v.FieldByName("Driver").String()
}
func mapByName(services []types.ServiceConfig) map[string]types.ServiceConfig {
m := map[string]types.ServiceConfig{}
for _, service := range services {
m[service.Name] = service
}
return m
}
func mergeVolumes(base, override map[string]types.VolumeConfig) (map[string]types.VolumeConfig, error) {
err := mergo.Map(&base, &override)
return base, err
}
func mergeNetworks(base, override map[string]types.NetworkConfig) (map[string]types.NetworkConfig, error) {
err := mergo.Map(&base, &override)
return base, err
}
func mergeSecrets(base, override map[string]types.SecretConfig) (map[string]types.SecretConfig, error) {
err := mergo.Map(&base, &override)
return base, err
}
func mergeConfigs(base, override map[string]types.ConfigObjConfig) (map[string]types.ConfigObjConfig, error) {
err := mergo.Map(&base, &override)
return base, err
}

View File

@ -0,0 +1,945 @@
package loader
import (
"testing"
"github.com/docker/cli/cli/compose/types"
"github.com/stretchr/testify/require"
)
func TestLoadTwoDifferentVersion(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{Filename: "base.yml", Config: map[string]interface{}{
"version": "3.1",
}},
{Filename: "override.yml", Config: map[string]interface{}{
"version": "3.4",
}},
},
}
_, err := Load(configDetails)
require.EqualError(t, err, "version mismatched between two composefiles : 3.1 and 3.4")
}
func TestLoadLogging(t *testing.T) {
loggingCases := []struct {
name string
loggingBase map[string]interface{}
loggingOverride map[string]interface{}
expected *types.LoggingConfig
}{
{
name: "no_override_driver",
loggingBase: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "json-file",
"options": map[string]interface{}{
"frequency": "2000",
"timeout": "23",
},
},
},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"options": map[string]interface{}{
"timeout": "360",
"pretty-print": "on",
},
},
},
expected: &types.LoggingConfig{
Driver: "json-file",
Options: map[string]string{
"frequency": "2000",
"timeout": "360",
"pretty-print": "on",
},
},
},
{
name: "override_driver",
loggingBase: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "json-file",
"options": map[string]interface{}{
"frequency": "2000",
"timeout": "23",
},
},
},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "syslog",
"options": map[string]interface{}{
"timeout": "360",
"pretty-print": "on",
},
},
},
expected: &types.LoggingConfig{
Driver: "syslog",
Options: map[string]string{
"timeout": "360",
"pretty-print": "on",
},
},
},
{
name: "no_base_driver",
loggingBase: map[string]interface{}{
"logging": map[string]interface{}{
"options": map[string]interface{}{
"frequency": "2000",
"timeout": "23",
},
},
},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "json-file",
"options": map[string]interface{}{
"timeout": "360",
"pretty-print": "on",
},
},
},
expected: &types.LoggingConfig{
Driver: "json-file",
Options: map[string]string{
"frequency": "2000",
"timeout": "360",
"pretty-print": "on",
},
},
},
{
name: "no_driver",
loggingBase: map[string]interface{}{
"logging": map[string]interface{}{
"options": map[string]interface{}{
"frequency": "2000",
"timeout": "23",
},
},
},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"options": map[string]interface{}{
"timeout": "360",
"pretty-print": "on",
},
},
},
expected: &types.LoggingConfig{
Options: map[string]string{
"frequency": "2000",
"timeout": "360",
"pretty-print": "on",
},
},
},
{
name: "no_override_options",
loggingBase: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "json-file",
"options": map[string]interface{}{
"frequency": "2000",
"timeout": "23",
},
},
},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "syslog",
},
},
expected: &types.LoggingConfig{
Driver: "syslog",
},
},
{
name: "no_base",
loggingBase: map[string]interface{}{},
loggingOverride: map[string]interface{}{
"logging": map[string]interface{}{
"driver": "json-file",
"options": map[string]interface{}{
"frequency": "2000",
},
},
},
expected: &types.LoggingConfig{
Driver: "json-file",
Options: map[string]string{
"frequency": "2000",
},
},
},
}
for _, tc := range loggingCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.loggingBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.loggingOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Logging: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleServicePorts(t *testing.T) {
portsCases := []struct {
name string
portBase map[string]interface{}
portOverride map[string]interface{}
expected []types.ServicePortConfig
}{
{
name: "no_override",
portBase: map[string]interface{}{
"ports": []interface{}{
"8080:80",
},
},
portOverride: map[string]interface{}{},
expected: []types.ServicePortConfig{
{
Mode: "ingress",
Published: 8080,
Target: 80,
Protocol: "tcp",
},
},
},
{
name: "override_different_published",
portBase: map[string]interface{}{
"ports": []interface{}{
"8080:80",
},
},
portOverride: map[string]interface{}{
"ports": []interface{}{
"8081:80",
},
},
expected: []types.ServicePortConfig{
{
Mode: "ingress",
Published: 8080,
Target: 80,
Protocol: "tcp",
},
{
Mode: "ingress",
Published: 8081,
Target: 80,
Protocol: "tcp",
},
},
},
{
name: "override_same_published",
portBase: map[string]interface{}{
"ports": []interface{}{
"8080:80",
},
},
portOverride: map[string]interface{}{
"ports": []interface{}{
"8080:81",
},
},
expected: []types.ServicePortConfig{
{
Mode: "ingress",
Published: 8080,
Target: 81,
Protocol: "tcp",
},
},
},
}
for _, tc := range portsCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.portBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.portOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Ports: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleSecretsConfig(t *testing.T) {
portsCases := []struct {
name string
secretBase map[string]interface{}
secretOverride map[string]interface{}
expected []types.ServiceSecretConfig
}{
{
name: "no_override",
secretBase: map[string]interface{}{
"secrets": []interface{}{
"my_secret",
},
},
secretOverride: map[string]interface{}{},
expected: []types.ServiceSecretConfig{
{
Source: "my_secret",
},
},
},
{
name: "override_simple",
secretBase: map[string]interface{}{
"secrets": []interface{}{
"foo_secret",
},
},
secretOverride: map[string]interface{}{
"secrets": []interface{}{
"bar_secret",
},
},
expected: []types.ServiceSecretConfig{
{
Source: "bar_secret",
},
{
Source: "foo_secret",
},
},
},
{
name: "override_same_source",
secretBase: map[string]interface{}{
"secrets": []interface{}{
"foo_secret",
map[string]interface{}{
"source": "bar_secret",
"target": "waw_secret",
},
},
},
secretOverride: map[string]interface{}{
"secrets": []interface{}{
map[string]interface{}{
"source": "bar_secret",
"target": "bof_secret",
},
map[string]interface{}{
"source": "baz_secret",
"target": "waw_secret",
},
},
},
expected: []types.ServiceSecretConfig{
{
Source: "bar_secret",
Target: "bof_secret",
},
{
Source: "baz_secret",
Target: "waw_secret",
},
{
Source: "foo_secret",
},
},
},
}
for _, tc := range portsCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.secretBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.secretOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Secrets: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleConfigobjsConfig(t *testing.T) {
portsCases := []struct {
name string
configBase map[string]interface{}
configOverride map[string]interface{}
expected []types.ServiceConfigObjConfig
}{
{
name: "no_override",
configBase: map[string]interface{}{
"configs": []interface{}{
"my_config",
},
},
configOverride: map[string]interface{}{},
expected: []types.ServiceConfigObjConfig{
{
Source: "my_config",
},
},
},
{
name: "override_simple",
configBase: map[string]interface{}{
"configs": []interface{}{
"foo_config",
},
},
configOverride: map[string]interface{}{
"configs": []interface{}{
"bar_config",
},
},
expected: []types.ServiceConfigObjConfig{
{
Source: "bar_config",
},
{
Source: "foo_config",
},
},
},
{
name: "override_same_source",
configBase: map[string]interface{}{
"configs": []interface{}{
"foo_config",
map[string]interface{}{
"source": "bar_config",
"target": "waw_config",
},
},
},
configOverride: map[string]interface{}{
"configs": []interface{}{
map[string]interface{}{
"source": "bar_config",
"target": "bof_config",
},
map[string]interface{}{
"source": "baz_config",
"target": "waw_config",
},
},
},
expected: []types.ServiceConfigObjConfig{
{
Source: "bar_config",
Target: "bof_config",
},
{
Source: "baz_config",
Target: "waw_config",
},
{
Source: "foo_config",
},
},
},
}
for _, tc := range portsCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.configBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.configOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Configs: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleUlimits(t *testing.T) {
ulimitCases := []struct {
name string
ulimitBase map[string]interface{}
ulimitOverride map[string]interface{}
expected map[string]*types.UlimitsConfig
}{
{
name: "no_override",
ulimitBase: map[string]interface{}{
"ulimits": map[string]interface{}{
"noproc": 65535,
},
},
ulimitOverride: map[string]interface{}{},
expected: map[string]*types.UlimitsConfig{
"noproc": {
Single: 65535,
},
},
},
{
name: "override_simple",
ulimitBase: map[string]interface{}{
"ulimits": map[string]interface{}{
"noproc": 65535,
},
},
ulimitOverride: map[string]interface{}{
"ulimits": map[string]interface{}{
"noproc": 44444,
},
},
expected: map[string]*types.UlimitsConfig{
"noproc": {
Single: 44444,
},
},
},
{
name: "override_different_notation",
ulimitBase: map[string]interface{}{
"ulimits": map[string]interface{}{
"nofile": map[string]interface{}{
"soft": 11111,
"hard": 99999,
},
"noproc": 44444,
},
},
ulimitOverride: map[string]interface{}{
"ulimits": map[string]interface{}{
"nofile": 55555,
"noproc": map[string]interface{}{
"soft": 22222,
"hard": 33333,
},
},
},
expected: map[string]*types.UlimitsConfig{
"noproc": {
Soft: 22222,
Hard: 33333,
},
"nofile": {
Single: 55555,
},
},
},
}
for _, tc := range ulimitCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.ulimitBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.ulimitOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Ulimits: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleNetworks(t *testing.T) {
networkCases := []struct {
name string
networkBase map[string]interface{}
networkOverride map[string]interface{}
expected map[string]*types.ServiceNetworkConfig
}{
{
name: "no_override",
networkBase: map[string]interface{}{
"networks": []interface{}{
"net1",
"net2",
},
},
networkOverride: map[string]interface{}{},
expected: map[string]*types.ServiceNetworkConfig{
"net1": nil,
"net2": nil,
},
},
{
name: "override_simple",
networkBase: map[string]interface{}{
"networks": []interface{}{
"net1",
"net2",
},
},
networkOverride: map[string]interface{}{
"networks": []interface{}{
"net1",
"net3",
},
},
expected: map[string]*types.ServiceNetworkConfig{
"net1": nil,
"net2": nil,
"net3": nil,
},
},
{
name: "override_with_aliases",
networkBase: map[string]interface{}{
"networks": map[string]interface{}{
"net1": map[string]interface{}{
"aliases": []interface{}{
"alias1",
},
},
"net2": nil,
},
},
networkOverride: map[string]interface{}{
"networks": map[string]interface{}{
"net1": map[string]interface{}{
"aliases": []interface{}{
"alias2",
"alias3",
},
},
"net3": map[string]interface{}{},
},
},
expected: map[string]*types.ServiceNetworkConfig{
"net1": {
Aliases: []string{"alias2", "alias3"},
},
"net2": nil,
"net3": {},
},
},
}
for _, tc := range networkCases {
t.Run(tc.name, func(t *testing.T) {
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Filename: "base.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.networkBase,
},
},
},
{
Filename: "override.yml",
Config: map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": tc.networkOverride,
},
},
},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Networks: tc.expected,
Environment: types.MappingWithEquals{},
},
},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
})
}
}
func TestLoadMultipleConfigs(t *testing.T) {
base := map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": map[string]interface{}{
"image": "foo",
"build": map[string]interface{}{
"context": ".",
"dockerfile": "bar.Dockerfile",
},
"ports": []interface{}{
"8080:80",
"9090:90",
},
"labels": []interface{}{
"foo=bar",
},
"cap_add": []interface{}{
"NET_ADMIN",
},
},
},
"volumes": map[string]interface{}{},
"networks": map[string]interface{}{},
"secrets": map[string]interface{}{},
"configs": map[string]interface{}{},
}
override := map[string]interface{}{
"version": "3.4",
"services": map[string]interface{}{
"foo": map[string]interface{}{
"image": "baz",
"build": map[string]interface{}{
"dockerfile": "foo.Dockerfile",
"args": []interface{}{
"buildno=1",
"password=secret",
},
},
"ports": []interface{}{
map[string]interface{}{
"target": 81,
"published": 8080,
},
},
"labels": map[string]interface{}{
"foo": "baz",
},
"cap_add": []interface{}{
"SYS_ADMIN",
},
},
"bar": map[string]interface{}{
"image": "bar",
},
},
"volumes": map[string]interface{}{},
"networks": map[string]interface{}{},
"secrets": map[string]interface{}{},
"configs": map[string]interface{}{},
}
configDetails := types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{Filename: "base.yml", Config: base},
{Filename: "override.yml", Config: override},
},
}
config, err := Load(configDetails)
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "bar",
Image: "bar",
Environment: types.MappingWithEquals{},
},
{
Name: "foo",
Image: "baz",
Build: types.BuildConfig{
Context: ".",
Dockerfile: "foo.Dockerfile",
Args: types.MappingWithEquals{
"buildno": strPtr("1"),
"password": strPtr("secret"),
},
},
Ports: []types.ServicePortConfig{
{
Target: 81,
Published: 8080,
},
{
Mode: "ingress",
Target: 90,
Published: 9090,
Protocol: "tcp",
},
},
Labels: types.Labels{
"foo": "baz",
},
CapAdd: []string{"NET_ADMIN", "SYS_ADMIN"},
Environment: types.MappingWithEquals{},
}},
Networks: map[string]types.NetworkConfig{},
Volumes: map[string]types.VolumeConfig{},
Secrets: map[string]types.SecretConfig{},
Configs: map[string]types.ConfigObjConfig{},
}, config)
}

View File

@ -0,0 +1,329 @@
package loader
import (
"testing"
"github.com/stretchr/testify/assert"
yaml "gopkg.in/yaml.v2"
)
func TestMarshallConfig(t *testing.T) {
cfg := fullExampleConfig("/foo", "/bar")
expected := `version: "3.6"
services:
foo:
build:
context: ./dir
dockerfile: Dockerfile
args:
foo: bar
labels:
FOO: BAR
cache_from:
- foo
- bar
network: foo
target: foo
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
cgroup_parent: m-executor-abcd
command:
- bundle
- exec
- thin
- -p
- "3000"
container_name: my-web-container
depends_on:
- db
- redis
deploy:
mode: replicated
replicas: 6
labels:
FOO: BAR
update_config:
parallelism: 3
delay: 10s
failure_action: continue
monitor: 1m0s
max_failure_ratio: 0.3
order: start-first
resources:
limits:
cpus: "0.001"
memory: "52428800"
reservations:
cpus: "0.0001"
memory: "20971520"
generic_resources:
- discrete_resource_spec:
kind: gpu
value: 2
- discrete_resource_spec:
kind: ssd
value: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 2m0s
placement:
constraints:
- node=foo
preferences:
- spread: node.labels.az
endpoint_mode: dnsrr
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
dns:
- 8.8.8.8
- 9.9.9.9
dns_search:
- dc1.example.com
- dc2.example.com
domainname: foo.com
entrypoint:
- /code/entrypoint.sh
- -p
- "3000"
environment:
BAR: bar_from_env_file_2
BAZ: baz_from_service_def
FOO: foo_from_env_file
QUX: qux_from_environment
env_file:
- ./example1.env
- ./example2.env
expose:
- "3000"
- "8000"
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
extra_hosts:
- somehost:162.242.195.82
- otherhost:50.31.209.229
hostname: foo
healthcheck:
test:
- CMD-SHELL
- echo "hello world"
timeout: 1s
interval: 10s
retries: 5
start_period: 15s
image: redis
ipc: host
labels:
com.example.description: Accounting webapp
com.example.empty-label: ""
com.example.number: "42"
links:
- db
- db:database
- redis
logging:
driver: syslog
options:
syslog-address: tcp://192.168.0.42:123
mac_address: 02:42:ac:11:65:43
network_mode: container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b
networks:
other-network:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
other-other-network: null
some-network:
aliases:
- alias1
- alias3
pid: host
ports:
- mode: ingress
target: 3000
protocol: tcp
- mode: ingress
target: 3001
protocol: tcp
- mode: ingress
target: 3002
protocol: tcp
- mode: ingress
target: 3003
protocol: tcp
- mode: ingress
target: 3004
protocol: tcp
- mode: ingress
target: 3005
protocol: tcp
- mode: ingress
target: 8000
published: 8000
protocol: tcp
- mode: ingress
target: 8080
published: 9090
protocol: tcp
- mode: ingress
target: 8081
published: 9091
protocol: tcp
- mode: ingress
target: 22
published: 49100
protocol: tcp
- mode: ingress
target: 8001
published: 8001
protocol: tcp
- mode: ingress
target: 5000
published: 5000
protocol: tcp
- mode: ingress
target: 5001
published: 5001
protocol: tcp
- mode: ingress
target: 5002
published: 5002
protocol: tcp
- mode: ingress
target: 5003
published: 5003
protocol: tcp
- mode: ingress
target: 5004
published: 5004
protocol: tcp
- mode: ingress
target: 5005
published: 5005
protocol: tcp
- mode: ingress
target: 5006
published: 5006
protocol: tcp
- mode: ingress
target: 5007
published: 5007
protocol: tcp
- mode: ingress
target: 5008
published: 5008
protocol: tcp
- mode: ingress
target: 5009
published: 5009
protocol: tcp
- mode: ingress
target: 5010
published: 5010
protocol: tcp
privileged: true
read_only: true
restart: always
security_opt:
- label=level:s0:c100,c200
- label=type:svirt_apache_t
stdin_open: true
stop_grace_period: 20s
stop_signal: SIGUSR1
tmpfs:
- /run
- /tmp
tty: true
ulimits:
nofile:
soft: 20000
hard: 40000
nproc: 65535
user: someone
volumes:
- type: volume
target: /var/lib/mysql
- type: bind
source: /opt/data
target: /var/lib/mysql
- type: bind
source: /foo
target: /code
- type: bind
source: /foo/static
target: /var/www/html
- type: bind
source: /bar/configs
target: /etc/configs/
read_only: true
- type: volume
source: datavolume
target: /var/lib/mysql
- type: bind
source: /foo/opt
target: /opt
consistency: cached
- type: tmpfs
target: /opt
tmpfs:
size: 10000
working_dir: /code
networks:
external-network:
name: external-network
external: true
other-external-network:
name: my-cool-network
external: true
other-network:
driver: overlay
driver_opts:
baz: "1"
foo: bar
ipam:
driver: overlay
config:
- subnet: 172.16.238.0/24
- subnet: 2001:3984:3989::/64
some-network: {}
volumes:
another-volume:
name: user_specified_name
driver: vsphere
driver_opts:
baz: "1"
foo: bar
external-volume:
name: external-volume
external: true
external-volume3:
name: this-is-volume3
external: true
other-external-volume:
name: my-cool-volume
external: true
other-volume:
driver: flocker
driver_opts:
baz: "1"
foo: bar
some-volume: {}
secrets: {}
configs: {}
`
actual, err := yaml.Marshal(cfg)
assert.NoError(t, err)
assert.Equal(t, expected, string(actual))
// Make sure the expected still
dict, err := ParseYAML([]byte("version: '3.6'\n" + expected))
assert.NoError(t, err)
_, err = Load(buildConfigDetails(dict, map[string]string{}))
assert.NoError(t, err)
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,582 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"id": "config_schema_v3.6.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"}
}
},
"tmpfs": {
"type": "object",
"properties": {
"size": {
"type": "integer",
"minimum": 0
}
}
}
},
"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

@ -1,6 +1,6 @@
package schema
//go:generate go-bindata -pkg schema -nometadata data
//go:generate esc -o bindata.go -pkg schema -private -modtime=1518458244 data
import (
"fmt"
@ -56,7 +56,7 @@ func normalizeVersion(version string) string {
// Validate uses the jsonschema to validate the configuration
func Validate(config map[string]interface{}, version string) error {
schemaData, err := Asset(fmt.Sprintf("data/config_schema_v%s.json", version))
schemaData, err := _escFSByte(false, fmt.Sprintf("/data/config_schema_v%s.json", version))
if err != nil {
return errors.Errorf("unsupported Compose file version: %s", version)
}

View File

@ -1,6 +1,7 @@
package types
import (
"fmt"
"time"
)
@ -23,7 +24,6 @@ var UnsupportedProperties = []string{
"security_opt",
"shm_size",
"sysctls",
"tmpfs",
"ulimits",
"userns_mode",
}
@ -70,76 +70,90 @@ func (cd ConfigDetails) LookupEnv(key string) (string, bool) {
// Config is a full compose file configuration
type Config struct {
Services []ServiceConfig
Filename string `yaml:"-"`
Version string
Services Services
Networks map[string]NetworkConfig
Volumes map[string]VolumeConfig
Secrets map[string]SecretConfig
Configs map[string]ConfigObjConfig
}
// Services is a list of ServiceConfig
type Services []ServiceConfig
// MarshalYAML makes Services implement yaml.Marshaller
func (s Services) MarshalYAML() (interface{}, error) {
services := map[string]ServiceConfig{}
for _, service := range s {
services[service.Name] = service
}
return services, nil
}
// ServiceConfig is the configuration of one service
type ServiceConfig struct {
Name string
Name string `yaml:"-"`
Build BuildConfig
CapAdd []string `mapstructure:"cap_add"`
CapDrop []string `mapstructure:"cap_drop"`
CgroupParent string `mapstructure:"cgroup_parent"`
Command ShellCommand
Configs []ServiceConfigObjConfig
ContainerName string `mapstructure:"container_name"`
CredentialSpec CredentialSpecConfig `mapstructure:"credential_spec"`
DependsOn []string `mapstructure:"depends_on"`
Deploy DeployConfig
Devices []string
DNS StringList
DNSSearch StringList `mapstructure:"dns_search"`
DomainName string `mapstructure:"domainname"`
Entrypoint ShellCommand
Environment MappingWithEquals
EnvFile StringList `mapstructure:"env_file"`
Expose StringOrNumberList
ExternalLinks []string `mapstructure:"external_links"`
ExtraHosts HostsList `mapstructure:"extra_hosts"`
Hostname string
HealthCheck *HealthCheckConfig
Image string
Ipc string
Labels Labels
Links []string
Logging *LoggingConfig
MacAddress string `mapstructure:"mac_address"`
NetworkMode string `mapstructure:"network_mode"`
Networks map[string]*ServiceNetworkConfig
Pid string
Ports []ServicePortConfig
Privileged bool
ReadOnly bool `mapstructure:"read_only"`
Restart string
Secrets []ServiceSecretConfig
SecurityOpt []string `mapstructure:"security_opt"`
StdinOpen bool `mapstructure:"stdin_open"`
StopGracePeriod *time.Duration `mapstructure:"stop_grace_period"`
StopSignal string `mapstructure:"stop_signal"`
Tmpfs StringList
Tty bool `mapstructure:"tty"`
Ulimits map[string]*UlimitsConfig
User string
Volumes []ServiceVolumeConfig
WorkingDir string `mapstructure:"working_dir"`
Isolation string `mapstructure:"isolation"`
Build BuildConfig `yaml:",omitempty"`
CapAdd []string `mapstructure:"cap_add" yaml:"cap_add,omitempty"`
CapDrop []string `mapstructure:"cap_drop" yaml:"cap_drop,omitempty"`
CgroupParent string `mapstructure:"cgroup_parent" yaml:"cgroup_parent,omitempty"`
Command ShellCommand `yaml:",omitempty"`
Configs []ServiceConfigObjConfig `yaml:",omitempty"`
ContainerName string `mapstructure:"container_name" yaml:"container_name,omitempty"`
CredentialSpec CredentialSpecConfig `mapstructure:"credential_spec" yaml:"credential_spec,omitempty"`
DependsOn []string `mapstructure:"depends_on" yaml:"depends_on,omitempty"`
Deploy DeployConfig `yaml:",omitempty"`
Devices []string `yaml:",omitempty"`
DNS StringList `yaml:",omitempty"`
DNSSearch StringList `mapstructure:"dns_search" yaml:"dns_search,omitempty"`
DomainName string `mapstructure:"domainname" yaml:"domainname,omitempty"`
Entrypoint ShellCommand `yaml:",omitempty"`
Environment MappingWithEquals `yaml:",omitempty"`
EnvFile StringList `mapstructure:"env_file" yaml:"env_file,omitempty"`
Expose StringOrNumberList `yaml:",omitempty"`
ExternalLinks []string `mapstructure:"external_links" yaml:"external_links,omitempty"`
ExtraHosts HostsList `mapstructure:"extra_hosts" yaml:"extra_hosts,omitempty"`
Hostname string `yaml:",omitempty"`
HealthCheck *HealthCheckConfig `yaml:",omitempty"`
Image string `yaml:",omitempty"`
Ipc string `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
Links []string `yaml:",omitempty"`
Logging *LoggingConfig `yaml:",omitempty"`
MacAddress string `mapstructure:"mac_address" yaml:"mac_address,omitempty"`
NetworkMode string `mapstructure:"network_mode" yaml:"network_mode,omitempty"`
Networks map[string]*ServiceNetworkConfig `yaml:",omitempty"`
Pid string `yaml:",omitempty"`
Ports []ServicePortConfig `yaml:",omitempty"`
Privileged bool `yaml:",omitempty"`
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty"`
Restart string `yaml:",omitempty"`
Secrets []ServiceSecretConfig `yaml:",omitempty"`
SecurityOpt []string `mapstructure:"security_opt" yaml:"security_opt,omitempty"`
StdinOpen bool `mapstructure:"stdin_open" yaml:"stdin_open,omitempty"`
StopGracePeriod *time.Duration `mapstructure:"stop_grace_period" yaml:"stop_grace_period,omitempty"`
StopSignal string `mapstructure:"stop_signal" yaml:"stop_signal,omitempty"`
Tmpfs StringList `yaml:",omitempty"`
Tty bool `mapstructure:"tty" yaml:"tty,omitempty"`
Ulimits map[string]*UlimitsConfig `yaml:",omitempty"`
User string `yaml:",omitempty"`
Volumes []ServiceVolumeConfig `yaml:",omitempty"`
WorkingDir string `mapstructure:"working_dir" yaml:"working_dir,omitempty"`
Isolation string `mapstructure:"isolation" yaml:"isolation,omitempty"`
}
// BuildConfig is a type for build
// using the same format at libcompose: https://github.com/docker/libcompose/blob/master/yaml/build.go#L12
type BuildConfig struct {
Context string
Dockerfile string
Args MappingWithEquals
Labels Labels
CacheFrom StringList `mapstructure:"cache_from"`
Network string
Target string
Context string `yaml:",omitempty"`
Dockerfile string `yaml:",omitempty"`
Args MappingWithEquals `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
CacheFrom StringList `mapstructure:"cache_from" yaml:"cache_from,omitempty"`
Network string `yaml:",omitempty"`
Target string `yaml:",omitempty"`
}
// ShellCommand is a string or list of string args
@ -170,30 +184,30 @@ type HostsList []string
// LoggingConfig the logging configuration for a service
type LoggingConfig struct {
Driver string
Options map[string]string
Driver string `yaml:",omitempty"`
Options map[string]string `yaml:",omitempty"`
}
// DeployConfig the deployment configuration for a service
type DeployConfig struct {
Mode string
Replicas *uint64
Labels Labels
UpdateConfig *UpdateConfig `mapstructure:"update_config"`
Resources Resources
RestartPolicy *RestartPolicy `mapstructure:"restart_policy"`
Placement Placement
EndpointMode string `mapstructure:"endpoint_mode"`
Mode string `yaml:",omitempty"`
Replicas *uint64 `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
UpdateConfig *UpdateConfig `mapstructure:"update_config" yaml:"update_config,omitempty"`
Resources Resources `yaml:",omitempty"`
RestartPolicy *RestartPolicy `mapstructure:"restart_policy" yaml:"restart_policy,omitempty"`
Placement Placement `yaml:",omitempty"`
EndpointMode string `mapstructure:"endpoint_mode" yaml:"endpoint_mode,omitempty"`
}
// HealthCheckConfig the healthcheck configuration for a service
type HealthCheckConfig struct {
Test HealthCheckTest
Timeout *time.Duration
Interval *time.Duration
Retries *uint64
StartPeriod *time.Duration `mapstructure:"start_period"`
Disable bool
Test HealthCheckTest `yaml:",omitempty"`
Timeout *time.Duration `yaml:",omitempty"`
Interval *time.Duration `yaml:",omitempty"`
Retries *uint64 `yaml:",omitempty"`
StartPeriod *time.Duration `mapstructure:"start_period" yaml:"start_period,omitempty"`
Disable bool `yaml:",omitempty"`
}
// HealthCheckTest is the command run to test the health of a service
@ -201,32 +215,32 @@ type HealthCheckTest []string
// UpdateConfig the service update configuration
type UpdateConfig struct {
Parallelism *uint64
Delay time.Duration
FailureAction string `mapstructure:"failure_action"`
Monitor time.Duration
MaxFailureRatio float32 `mapstructure:"max_failure_ratio"`
Order string
Parallelism *uint64 `yaml:",omitempty"`
Delay time.Duration `yaml:",omitempty"`
FailureAction string `mapstructure:"failure_action" yaml:"failure_action,omitempty"`
Monitor time.Duration `yaml:",omitempty"`
MaxFailureRatio float32 `mapstructure:"max_failure_ratio" yaml:"max_failure_ratio,omitempty"`
Order string `yaml:",omitempty"`
}
// Resources the resource limits and reservations
type Resources struct {
Limits *Resource
Reservations *Resource
Limits *Resource `yaml:",omitempty"`
Reservations *Resource `yaml:",omitempty"`
}
// 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"`
GenericResources []GenericResource `mapstructure:"generic_resources"`
NanoCPUs string `mapstructure:"cpus" yaml:"cpus,omitempty"`
MemoryBytes UnitBytes `mapstructure:"memory" yaml:"memory,omitempty"`
GenericResources []GenericResource `mapstructure:"generic_resources" yaml:"generic_resources,omitempty"`
}
// 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"`
DiscreteResourceSpec *DiscreteGenericResource `mapstructure:"discrete_resource_spec" yaml:"discrete_resource_spec,omitempty"`
}
// DiscreteGenericResource represents a "user defined" resource which is defined
@ -241,68 +255,79 @@ type DiscreteGenericResource struct {
// UnitBytes is the bytes type
type UnitBytes int64
// MarshalYAML makes UnitBytes implement yaml.Marshaller
func (u UnitBytes) MarshalYAML() (interface{}, error) {
return fmt.Sprintf("%d", u), nil
}
// RestartPolicy the service restart policy
type RestartPolicy struct {
Condition string
Delay *time.Duration
MaxAttempts *uint64 `mapstructure:"max_attempts"`
Window *time.Duration
Condition string `yaml:",omitempty"`
Delay *time.Duration `yaml:",omitempty"`
MaxAttempts *uint64 `mapstructure:"max_attempts" yaml:"max_attempts,omitempty"`
Window *time.Duration `yaml:",omitempty"`
}
// Placement constraints for the service
type Placement struct {
Constraints []string
Preferences []PlacementPreferences
Constraints []string `yaml:",omitempty"`
Preferences []PlacementPreferences `yaml:",omitempty"`
}
// PlacementPreferences is the preferences for a service placement
type PlacementPreferences struct {
Spread string
Spread string `yaml:",omitempty"`
}
// ServiceNetworkConfig is the network configuration for a service
type ServiceNetworkConfig struct {
Aliases []string
Ipv4Address string `mapstructure:"ipv4_address"`
Ipv6Address string `mapstructure:"ipv6_address"`
Aliases []string `yaml:",omitempty"`
Ipv4Address string `mapstructure:"ipv4_address" yaml:"ipv4_address,omitempty"`
Ipv6Address string `mapstructure:"ipv6_address" yaml:"ipv6_address,omitempty"`
}
// ServicePortConfig is the port configuration for a service
type ServicePortConfig struct {
Mode string
Target uint32
Published uint32
Protocol string
Mode string `yaml:",omitempty"`
Target uint32 `yaml:",omitempty"`
Published uint32 `yaml:",omitempty"`
Protocol string `yaml:",omitempty"`
}
// ServiceVolumeConfig are references to a volume used by a service
type ServiceVolumeConfig struct {
Type string
Source string
Target string
ReadOnly bool `mapstructure:"read_only"`
Consistency string
Bind *ServiceVolumeBind
Volume *ServiceVolumeVolume
Type string `yaml:",omitempty"`
Source string `yaml:",omitempty"`
Target string `yaml:",omitempty"`
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty"`
Consistency string `yaml:",omitempty"`
Bind *ServiceVolumeBind `yaml:",omitempty"`
Volume *ServiceVolumeVolume `yaml:",omitempty"`
Tmpfs *ServiceVolumeTmpfs `yaml:",omitempty"`
}
// ServiceVolumeBind are options for a service volume of type bind
type ServiceVolumeBind struct {
Propagation string
Propagation string `yaml:",omitempty"`
}
// ServiceVolumeVolume are options for a service volume of type volume
type ServiceVolumeVolume struct {
NoCopy bool `mapstructure:"nocopy"`
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty"`
}
// ServiceVolumeTmpfs are options for a service volume of type tmpfs
type ServiceVolumeTmpfs struct {
Size int64 `yaml:",omitempty"`
}
// FileReferenceConfig for a reference to a swarm file object
type FileReferenceConfig struct {
Source string
Target string
UID string
GID string
Mode *uint32
Source string `yaml:",omitempty"`
Target string `yaml:",omitempty"`
UID string `yaml:",omitempty"`
GID string `yaml:",omitempty"`
Mode *uint32 `yaml:",omitempty"`
}
// ServiceConfigObjConfig is the config obj configuration for a service
@ -313,63 +338,79 @@ type ServiceSecretConfig FileReferenceConfig
// UlimitsConfig the ulimit configuration
type UlimitsConfig struct {
Single int
Soft int
Hard int
Single int `yaml:",omitempty"`
Soft int `yaml:",omitempty"`
Hard int `yaml:",omitempty"`
}
// MarshalYAML makes UlimitsConfig implement yaml.Marshaller
func (u *UlimitsConfig) MarshalYAML() (interface{}, error) {
if u.Single != 0 {
return u.Single, nil
}
return u, nil
}
// NetworkConfig for a network
type NetworkConfig struct {
Name string
Driver string
DriverOpts map[string]string `mapstructure:"driver_opts"`
Ipam IPAMConfig
External External
Internal bool
Attachable bool
Labels Labels
Name string `yaml:",omitempty"`
Driver string `yaml:",omitempty"`
DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty"`
Ipam IPAMConfig `yaml:",omitempty"`
External External `yaml:",omitempty"`
Internal bool `yaml:",omitempty"`
Attachable bool `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
}
// IPAMConfig for a network
type IPAMConfig struct {
Driver string
Config []*IPAMPool
Driver string `yaml:",omitempty"`
Config []*IPAMPool `yaml:",omitempty"`
}
// IPAMPool for a network
type IPAMPool struct {
Subnet string
Subnet string `yaml:",omitempty"`
}
// VolumeConfig for a volume
type VolumeConfig struct {
Name string
Driver string
DriverOpts map[string]string `mapstructure:"driver_opts"`
External External
Labels Labels
Name string `yaml:",omitempty"`
Driver string `yaml:",omitempty"`
DriverOpts map[string]string `mapstructure:"driver_opts" yaml:"driver_opts,omitempty"`
External External `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
}
// External identifies a Volume or Network as a reference to a resource that is
// not managed, and should already exist.
// External.name is deprecated and replaced by Volume.name
type External struct {
Name string
External bool
Name string `yaml:",omitempty"`
External bool `yaml:",omitempty"`
}
// MarshalYAML makes External implement yaml.Marshaller
func (e External) MarshalYAML() (interface{}, error) {
if e.Name == "" {
return e.External, nil
}
return External{Name: e.Name}, nil
}
// CredentialSpecConfig for credential spec on Windows
type CredentialSpecConfig struct {
File string
Registry string
File string `yaml:",omitempty"`
Registry string `yaml:",omitempty"`
}
// FileObjectConfig is a config type for a file used by a service
type FileObjectConfig struct {
Name string
File string
External External
Labels Labels
Name string `yaml:",omitempty"`
File string `yaml:",omitempty"`
External External `yaml:",omitempty"`
Labels Labels `yaml:",omitempty"`
}
// SecretConfig for a secret

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