Compare commits

..

111 Commits

Author SHA1 Message Date
Nicolas De Loof
d0899ca124 remove py27 testing, 1.26 and later drop python 2 support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 17:20:02 +01:00
Nicolas De Loof
94c41848cb Attempt to fix release process
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 15:00:50 +01:00
Nicolas De Loof
540e5da903 bake github release API json payload in groovy
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 14:06:24 +01:00
Nicolas De Loof
3f4920cdf5 run release on tag by Jenkinsfile
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 12:27:47 +01:00
Ulysses Souza
702dd9406c Merge pull request #7093 from ulyssessouza/warn-invalid-version
Validate version format on formats 2+
2020-01-08 10:47:01 +01:00
Ulysses Souza
704ee56553 Merge pull request #7122 from ndeloof/shutil
Don't adjust output on terminal width when piped into another command
2020-01-08 10:46:03 +01:00
Nicolas De Loof
31396786ba publish package on PyPI
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
d6c13b69c3 compute sha256sum
windows nodes don't have openssl installed:'(

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
0e826efee5 attempt to fix windows build
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
1af3852277 Generate changelog
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
9c6db546e8 Remove Circle-CI and AppVeyor config files
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
417d72ea3d Compute checksum
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
bdb11849b1 Use .Jenkinsfile extension for IDE support
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
da55677154 Release pipeline
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
7be66baaa7 TAG and BUILD_TAG are obsolete
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
6b0acc9ecb tests don't run in parallel
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
8859ab0d66 Use gotemplate formater to extract specific data
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
9478725a70 Fix tested docker releases in Pipeline
This allows Engine team to trigger a compose build by pushing a PR
changing the `dockerVersions` variable to test Release Candidates

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
2955f48468 Get docker versions using a plain command line
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
644c55c4f7 Use declarative syntax when possible
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
912d90832c Use a simple script to get docker-ce releases
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
c5c287db5c We don't use FOSSA anymore
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
dd889b990b Prepare drop of python 2.x support
see https://github.com/docker/compose/issues/6890

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 10:15:48 +01:00
Nicolas De Loof
3df4ba1544 Assume infinite terminal width when not running in a terminal
Close https://github.com/docker/compose/issues/7119

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2020-01-08 08:40:18 +01:00
ulyssessouza
7f49bbb998 Validate version format on formats 2+
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2020-01-07 18:37:47 +01:00
Ulysses Souza
9f373b0b86 Merge pull request #7128 from docker/post-release-1.25.1
Post release 1.25.1
2020-01-07 17:20:41 +01:00
Ulysses Souza
67cce913a6 Set dev version to 1.26.0dev after releasing 1.25.1
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-01-07 16:44:42 +01:00
Ulysses Souza
cc93c97689 Merge pull request #7123 from docker/bump-1.25.1
Bump 1.25.1
2020-01-06 19:08:18 +01:00
Ulysses Souza
a82fef0722 "Bump 1.25.1"
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-01-06 17:42:50 +01:00
Ulysses Souza
f70b8c9a53 Merge remote-tracking branch 'upstream/release' into bump-1.25.1 2020-01-06 17:17:07 +01:00
Ulysses Souza
b572a1e2e0 Merge pull request #7121 from ulyssessouza/fix_binary_string_error_treatment
Fix binary string error treatment
2020-01-06 16:56:30 +01:00
Ulysses Souza
37eb7a509b Decode APIError explanation to unicode before usage
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-01-06 16:00:34 +01:00
Ulysses Souza
cba8ad474c Fix by adding an assert to make the comparison effective
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-01-06 15:53:32 +01:00
dependabot-preview[bot]
e9220f45df Bump coverage from 4.4.2 to 4.5.4
Bumps [coverage](https://github.com/nedbat/coveragepy) from 4.4.2 to 4.5.4.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/coverage-4.4.2...coverage-4.5.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 08:09:10 +01:00
dependabot-preview[bot]
780a425c60 Bump flake8 from 3.5.0 to 3.7.9
Bumps [flake8](https://gitlab.com/pycqa/flake8) from 3.5.0 to 3.7.9.
- [Release notes](https://gitlab.com/pycqa/flake8/tags)
- [Commits](https://gitlab.com/pycqa/flake8/compare/3.5.0...3.7.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 08:09:07 +01:00
dependabot-preview[bot]
d32b9f95ca Bump pytest-cov from 2.5.1 to 2.8.1
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 2.5.1 to 2.8.1.
- [Release notes](https://github.com/pytest-dev/pytest-cov/releases)
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v2.5.1...v2.8.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-04 08:08:54 +01:00
Ulysses Souza
a23f39127e Merge pull request #7071 from docker/bump-1.25.1-rc1
Bump 1.25.1-rc1
2019-11-29 20:15:40 +01:00
Ulysses Souza
d92e9beec1 "Bump 1.25.1-rc1"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-29 19:21:16 +01:00
Ulysses Souza
8ebd7f96f0 Merge pull request #7070 from docker/macos-folder-build
Build fixes for macOS
2019-11-29 19:16:41 +01:00
Christopher Crone
b7a675b1c0 Upload macOS folder format to bintray
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-11-29 18:28:47 +01:00
Christopher Crone
8820343882 Stash all macOS build artifacts
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-11-29 18:28:17 +01:00
Christopher Crone
fedc8f71ad Build single binary and folder format for macOS
Previously we were overwriting the single binary with the folder
format.

Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-11-29 18:27:39 +01:00
Ulysses Souza
e82d38f333 Merge pull request #7052 from ndeloof/pull_can_build
Report image we can't pull and must be built
2019-11-29 15:48:38 +01:00
Christopher Crone
d6b5d324e2 Use Python3 for macOS build environment
With the deprecation of Python 2 coming soon, explicitly use
Python 3.

Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-11-28 20:26:58 +01:00
Ulysses Souza
44edd65065 Merge pull request #7009 from glance-/shellcheck
Resolve shellcheck warnings in container-script
2019-11-28 13:37:50 +01:00
Nicolas De Loof
55c5c8e8ac Report image we can't pull and must be built
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-25 15:18:27 +01:00
Ulysses Souza
517efbf386 Merge pull request #7005 from glance-/HOME-in-container
Pass in HOME env-var in container mode.
2019-11-22 17:02:07 +01:00
Anton Lundin
c8cfc590cc Better userns detection in container-script
This uses formatting to have docker info just emit the information we're interested in.

Based-on-code-by: Sebastiaan van Stijn <github@gone.​nl>
Signed-off-by: Anton Lundin <anton.lundin@umu.se>

Co-Authored-By: Sebastiaan van Stijn <thaJeztah@users.noreply.github.com>
2019-11-22 16:24:09 +01:00
Ulysses Souza
a7e8356651 Update maintainers and add CODEOWNERS for github
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-22 16:00:07 +01:00
Ulysses Souza
332fa8bf62 Merge pull request #7010 from ndeloof/catalina
Build OSX binary as a directory
2019-11-22 15:26:09 +01:00
Ulysses Souza
a83d86e7ce Merge pull request #7037 from ndeloof/stdin
config_detail.filename is None when passed by stdin
2019-11-22 15:24:43 +01:00
Ulysses Souza
1de8205996 Merge pull request #7048 from ulyssessouza/update-dev-version
Update dev version to 1.26.0dev
2019-11-22 14:15:09 +01:00
Ulysses Souza
d837d27ad7 Update dev version
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-22 14:13:50 +01:00
Ulysses Souza
cfc131b502 Merge pull request #7042 from ulyssessouza/release
Sync backport changes in release 1.25.0
2019-11-22 14:10:42 +01:00
Nicolas De Loof
e6ec77047b Revert "only pull images that can't build"
This reverts commit c6dd7da15e.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-21 14:37:41 +01:00
Ulysses Souza
f4cf7a939e Announce drop py2
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-21 13:23:56 +01:00
Nicolas De Loof
fa9e8bd641 Skip label if some config file was passed by stdin
com.docker.compose.project.config_files must contain valid file paths

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-21 09:59:22 +01:00
Nicolas De Loof
e13a7213f1 Build OSX binary as a directory
OSX Catalina otherwise do scan the temporary executable files created by the single-file packaging.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-21 09:01:41 +01:00
Nicolas De Loof
fe2b692547 testcase for compose file read from stdin
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-20 15:38:15 +01:00
Nicolas De Loof
962421d019 config_detail.filename is None when passed by stdin
Fix #7032

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2019-11-20 09:00:47 +01:00
Ulysses Souza
4038169d96 Merge pull request #7028 from docker/bump-1.25.0
Bump 1.25.0
2019-11-18 22:56:24 +01:00
Ulysses Souza
b42d4197ce Add latest tag question on resume and start to tag on build
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-18 22:46:12 +01:00
Ulysses Souza
0a186604be "Bump 1.25.0"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-18 19:35:34 +01:00
Ulysses Souza
d072601197 "Bump 1.25.0"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-18 19:29:40 +01:00
Ulysses Souza
a0592ce585 "Bump 1.25.0"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-11-18 19:14:13 +01:00
Ulysses Souza
c49678a11f Merge remote-tracking branch 'upstream/release' into bump-1.25.0 2019-11-18 18:28:25 +01:00
Anton Lundin
aeddfd41d6 Resolve shellcheck warnings in container-script
This fixes a couple of small potential issues pointed out by shellcheck.

Signed-off-by: Anton Lundin <anton.lundin@umu.se>
2019-11-07 21:55:03 +01:00
Anton Lundin
b9a4581d60 Pass in HOME env-var in container mode.
To get ~/-paths to work as expected in contaier mode, env-var HOME must
be the same outside the container as inside the docker-compose
container, otherwise HOME inside the container points to /root which
might not be what the user expects.

Signed-off-by: Anton Lundin <anton.lundin@umu.se>
2019-11-06 13:05:58 +01:00
Djordje Lukic
f6b6cd22df Merge pull request #6987 from docker/bump-1.25.0-rc4
Bump 1.25.0-rc4
2019-10-28 16:54:32 +01:00
Djordje Lukic
8f3c9c58c5 "Bump 1.25.0-rc4"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-10-28 16:18:12 +01:00
Djordje Lukic
52c3e94be0 Merge remote-tracking branch 'origin/release' into bump-1.25.0-rc4 2019-10-28 16:16:58 +01:00
Djordje Lukic
ea22d5821c Merge pull request #6984 from docker/bump-1.25.0-rc3
Bump 1.25.0-rc3
2019-10-28 12:13:11 +01:00
Djordje Lukic
c7e82489f4 "Bump 1.25.0-rc3"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-10-28 11:33:59 +01:00
Djordje Lukic
952340043a Merge remote-tracking branch 'origin/release' into bump-1.25.0-rc3 2019-10-28 11:24:06 +01:00
Ulysses Souza
2c668e237d Merge pull request #6835 from docker/bump-1.25.0-rc2
Bump 1.25.0-rc2
2019-08-07 15:03:32 +02:00
Ulysses Souza
661ac20e5d "Bump 1.25.0-rc2"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-08-06 15:28:46 +02:00
Ulysses Souza
ab93b87f04 Merge remote-tracking branch 'upstream/release' into bump-1.25.0-rc2 2019-08-06 15:05:08 +02:00
Djordje Lukic
85d940909e Merge pull request #6766 from docker/bump-1.24.1
Bump 1.24.1
2019-06-24 12:15:25 +02:00
Djordje Lukic
4667896b69 "Bump 1.24.1"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-06-24 11:20:44 +02:00
Djordje Lukic
a78e3b0c7c Bump docker-py
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-06-24 10:38:39 +02:00
Dave Tucker
5e7521909d Add .fossa.yml file
This commit adds a .fossa.yml file used by fossa.io
It allows for fossa to scan the dependencies and figure out which oss
licenses are in use. This can be added to CI at some point in the near
future.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
2019-06-24 10:38:38 +02:00
Djordje Lukic
272e85dce3 Merge remote-tracking branch 'origin/release' into bump-1.24.1 2019-06-24 10:38:25 +02:00
Ulysses Souza
2bc4161526 Merge pull request #6726 from docker/bump-1.25.0-rc1
Bump 1.25.0-rc1
2019-05-24 00:33:04 +02:00
Ulysses Souza
8552e8e283 "Bump 1.25.0-rc1"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-05-23 23:39:09 +02:00
Ulysses Souza
3803d35c03 Merge remote-tracking branch 'upstream/release' into bump-1.25.0-rc1 2019-05-23 23:38:30 +02:00
Ulysses Souza
d9fa8158c3 Merge pull request #6616 from docker/bump-1.24.0
Bump 1.24.0
2019-03-28 18:58:40 +01:00
Ulysses Souza
0aa590649c "Bump 1.24.0"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-28 18:34:02 +01:00
Ulysses Souza
eb2fdf81b4 Bump docker-py 3.7.2
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-28 18:29:27 +01:00
Ulysses Souza
917c2701f2 Fix script for release file already present case
This avoids a:
"AttributeError: 'HTTPError' object has no attribute 'message'"

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-28 18:29:25 +01:00
Ulysses Souza
3a3288c54b Merge pull request #6609 from docker/bump-1.24.0-rc3
Bump 1.24.0-rc3
2019-03-22 15:51:21 +01:00
Ulysses Souza
428942498b "Bump 1.24.0-rc3"
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:52 +01:00
Ulysses Souza
c54341758a Fix bintray docker-compose link
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:22 +01:00
Ulysses Souza
662761dbba Fix typo on finalize
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:22 +01:00
Ulysses Souza
0e05ac6d2c Use os.system() instead of run_setup()
Use `os.system()` instead of `run_setup()` because the last
is not taking any effect

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:22 +01:00
Ulysses Souza
295dd9abda Bump docker-py version to 3.7.1
This docker-py version includes ssh fixes

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:21 +01:00
Ben Firshman
81b30c4380 Enable bootloader_ignore_signals in pyinstaller
Fixes #3347

Signed-off-by: Ben Firshman <ben@firshman.co.uk>
2019-03-22 15:15:19 +01:00
Michael Irwin
360753ecc1 Added test case to verify fix for #6525
Signed-off-by: Michael Irwin <mikesir87@gmail.com>
2019-03-22 15:15:18 +01:00
Michael Irwin
3fae0119ca Fix merging of compose files when network has None config
Signed-off-by: Michael Irwin <mikesir87@gmail.com>

Resolves #6525
2019-03-22 15:15:18 +01:00
Christopher Crone
0fdb9783cd circleci: Fix virtualenv version to 16.2.0
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-03-22 15:15:17 +01:00
Ulysses Souza
0dec6b5ff1 Fix Flake8 lint
This removes extra indentation and replace the use of `is` by `==` when
comparing strings

Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:16 +01:00
Christopher Crone
e0412a2488 Dockerfile: Force version of virtualenv to 16.2.0
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-03-22 15:15:16 +01:00
Christopher Crone
3fc5c6f563 script.build.linux: Do not tail image build logs
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-03-22 15:15:16 +01:00
Christopher Crone
28310b3ba4 requirements-dev: Fix version of mock to 2.0.0
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-03-22 15:15:16 +01:00
Christopher Crone
4585db124a macOS: Bump Python and OpenSSL
Signed-off-by: Christopher Crone <christopher.crone@docker.com>
2019-03-22 15:15:16 +01:00
Ulysses Souza
1f9b20d97b Add --parallel to docker build's options in bash and zsh completion
Signed-off-by: Ulysses Souza <ulysses.souza@docker.com>
2019-03-22 15:15:13 +01:00
Djordje Lukic
82a89aef1c Support for credential_spec
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-03-22 15:15:12 +01:00
Harald Albers
3934617e37 Add bash completion for ps --all|-a
Signed-off-by: Harald Albers <github@albersweb.de>
2019-03-22 15:15:10 +01:00
Djordje Lukic
82db4fd4f2 Merge pull request #6455 from docker/bump-1.24.0-rc1
Bump 1.24.0-rc1
2019-01-14 17:54:34 +01:00
Djordje Lukic
0f3d4ddaa7 "Bump 1.24.0-rc1"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-01-11 18:28:30 +01:00
Djordje Lukic
2007951731 "Bump 1.24.0-rc1"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-01-11 17:57:05 +01:00
Djordje Lukic
60f8ce09f9 "Bump 1.24.0-rc1"
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2019-01-11 17:43:47 +01:00
32 changed files with 925 additions and 273 deletions

View File

@@ -1,63 +0,0 @@
version: 2
jobs:
test:
macos:
xcode: "9.4.1"
steps:
- checkout
- run:
name: setup script
command: ./script/setup/osx
- run:
name: install tox
command: sudo pip install --upgrade tox==2.1.1 virtualenv==16.2.0
- run:
name: unit tests
command: tox -e py27,py37 -- tests/unit
build-osx-binary:
macos:
xcode: "9.4.1"
steps:
- checkout
- run:
name: upgrade python tools
command: sudo pip install --upgrade pip virtualenv==16.2.0
- run:
name: setup script
command: DEPLOYMENT_TARGET=10.11 ./script/setup/osx
- run:
name: build script
command: ./script/build/osx
- store_artifacts:
path: dist/docker-compose-Darwin-x86_64
destination: docker-compose-Darwin-x86_64
- deploy:
name: Deploy binary to bintray
command: |
OS_NAME=Darwin PKG_NAME=osx ./script/circle/bintray-deploy.sh
build-linux-binary:
machine:
enabled: true
steps:
- checkout
- run:
name: build Linux binary
command: ./script/build/linux
- store_artifacts:
path: dist/docker-compose-Linux-x86_64
destination: docker-compose-Linux-x86_64
- deploy:
name: Deploy binary to bintray
command: |
OS_NAME=Linux PKG_NAME=linux ./script/circle/bintray-deploy.sh
workflows:
version: 2
all:
jobs:
- test
- build-linux-binary
- build-osx-binary

View File

@@ -11,3 +11,4 @@ docs/_site
.tox
**/__pycache__
*.pyc
Jenkinsfile

6
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,6 @@
# GitHub code owners
# See https://help.github.com/articles/about-codeowners/
#
# KEEP THIS FILE SORTED. Order is important. Last match takes precedence.
* @ndeloof @rumpl @ulyssessouza

View File

@@ -1,6 +1,136 @@
Change log
==========
1.25.1 (2020-01-06)
-------------------
### Features
- Bump `pytest-cov` 2.8.1
- Bump `flake8` 3.7.9
- Bump `coverage` 4.5.4
### Bugfixes
- Decode APIError explanation to unicode before usage on start and create of a container
- Reports when images that cannot be pulled and must be built
- Discard label `com.docker.compose.filepaths` having None as value. Typically, when coming from stdin
- Added OSX binary as a directory to solve slow start up time caused by MacOS Catalina binary scan
- Passed in HOME env-var in container mode (running with `script/run/run.sh`)
- Reverted behavior of "only pull images that we can't build" and replace by a warning informing the image we can't pull and must be built
1.25.0 (2019-11-18)
-------------------
### Features
- Set no-colors to true if CLICOLOR env variable is set to 0
- Add working dir, config files and env file in service labels
- Add dependencies for ARM build
- Add BuildKit support, use `DOCKER_BUILDKIT=1` and `COMPOSE_DOCKER_CLI_BUILD=1`
- Bump paramiko to 2.6.0
- Add working dir, config files and env file in service labels
- Add tag `docker-compose:latest`
- Add `docker-compose:<version>-alpine` image/tag
- Add `docker-compose:<version>-debian` image/tag
- Bumped `docker-py` 4.1.0
- Supports `requests` up to 2.22.0 version
- Drops empty tag on `build:cache_from`
- `Dockerfile` now generates `libmusl` binaries for alpine
- Only pull images that can't be built
- Attribute `scale` can now accept `0` as a value
- Added `--quiet` build flag
- Added `--no-interpolate` to `docker-compose config`
- Bump OpenSSL for macOS build (`1.1.0j` to `1.1.1c`)
- Added `--no-rm` to `build` command
- Added support for `credential_spec`
- Resolve digests without pulling image
- Upgrade `pyyaml` to `4.2b1`
- Lowered severity to `warning` if `down` tries to remove nonexisting image
- Use improved API fields for project events when possible
- Update `setup.py` for modern `pypi/setuptools` and remove `pandoc` dependencies
- Removed `Dockerfile.armhf` which is no longer needed
### Bugfixes
- Make container service color deterministic, remove red from chosen colors
- Fix non ascii chars error. Python2 only
- Format image size as decimal to be align with Docker CLI
- Use Python Posix support to get tty size
- Fix same file 'extends' optimization
- Use python POSIX support to get tty size
- Format image size as decimal to be align with Docker CLI
- Fixed stdin_open
- Fixed `--remove-orphans` when used with `up --no-start`
- Fixed `docker-compose ps --all`
- Fixed `depends_on` dependency recreation behavior
- Fixed bash completion for `build --memory`
- Fixed misleading warning concerning env vars when performing an `exec` command
- Fixed failure check in parallel_execute_watch
- Fixed race condition after pulling image
- Fixed error on duplicate mount points
- Fixed merge on networks section
- Always connect Compose container to `stdin`
- Fixed the presentation of failed services on 'docker-compose start' when containers are not available
1.24.1 (2019-06-24)
-------------------
### Bugfixes
- Fixed acceptance tests
1.24.0 (2019-03-28)
-------------------

194
Jenkinsfile vendored
View File

@@ -1,92 +1,112 @@
#!groovy
def buildImage = { String baseImage ->
def image
wrappedNode(label: "ubuntu && amd64 && !zfs", cleanWorkspace: true) {
stage("build image for \"${baseImage}\"") {
checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${gitCommit()}"
image = docker.image(imageName)
try {
image.pull()
} catch (Exception exc) {
sh """GIT_COMMIT=\$(script/build/write-git-sha) && \\
docker build -t ${imageName} \\
--target build \\
--build-arg BUILD_PLATFORM="${baseImage}" \\
--build-arg GIT_COMMIT="${GIT_COMMIT}" \\
.\\
"""
sh "docker push ${imageName}"
echo "${imageName}"
return imageName
}
}
}
echo "image.id: ${image.id}"
return image.id
}
def get_versions = { String imageId, int number ->
def docker_versions
wrappedNode(label: "ubuntu && amd64 && !zfs") {
def result = sh(script: """docker run --rm \\
--entrypoint=/code/.tox/py37/bin/python \\
${imageId} \\
/code/script/test/versions.py -n ${number} docker/docker-ce recent
""", returnStdout: true
)
docker_versions = result.split()
}
return docker_versions
}
def runTests = { Map settings ->
def dockerVersions = settings.get("dockerVersions", null)
def pythonVersions = settings.get("pythonVersions", null)
def baseImage = settings.get("baseImage", null)
def imageName = settings.get("image", null)
if (!pythonVersions) {
throw new Exception("Need Python versions to test. e.g.: `runTests(pythonVersions: 'py37')`")
}
if (!dockerVersions) {
throw new Exception("Need Docker versions to test. e.g.: `runTests(dockerVersions: 'all')`")
}
{ ->
wrappedNode(label: "ubuntu && amd64 && !zfs", cleanWorkspace: true) {
stage("test python=${pythonVersions} / docker=${dockerVersions} / baseImage=${baseImage}") {
checkout(scm)
def storageDriver = sh(script: 'docker info | awk -F \': \' \'$1 == "Storage Driver" { print $2; exit }\'', returnStdout: true).trim()
echo "Using local system's storage driver: ${storageDriver}"
sh """docker run \\
-t \\
--rm \\
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
-e "TAG=${imageName}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersions}" \\
-e "BUILD_NUMBER=\$BUILD_TAG" \\
-e "PY_TEST_VERSIONS=${pythonVersions}" \\
--entrypoint="script/test/ci" \\
${imageName} \\
--verbose
"""
}
}
}
}
def testMatrix = [failFast: true]
def dockerVersions = ['19.03.5', '18.09.9']
def baseImages = ['alpine', 'debian']
baseImages.each { baseImage ->
def imageName = buildImage(baseImage)
get_versions(imageName, 2).each { dockerVersion ->
testMatrix["${baseImage}_${dockerVersion}"] = runTests([baseImage: baseImage, image: imageName, dockerVersions: dockerVersion, pythonVersions: 'py37'])
}
def pythonVersions = ['py27', 'py37']
pipeline {
agent none
options {
skipDefaultCheckout(true)
buildDiscarder(logRotator(daysToKeepStr: '30'))
timeout(time: 2, unit: 'HOURS')
timestamps()
}
stages {
stage('Build test images') {
// TODO use declarative 1.5.0 `matrix` once available on CI
parallel {
stage('alpine') {
agent {
label 'ubuntu && amd64 && !zfs'
}
steps {
buildImage('alpine')
}
}
stage('debian') {
agent {
label 'ubuntu && amd64 && !zfs'
}
steps {
buildImage('debian')
}
}
}
}
stage('Test') {
steps {
// TODO use declarative 1.5.0 `matrix` once available on CI
script {
def testMatrix = [:]
baseImages.each { baseImage ->
dockerVersions.each { dockerVersion ->
pythonVersions.each { pythonVersion ->
testMatrix["${baseImage}_${dockerVersion}_${pythonVersion}"] = runTests(dockerVersion, pythonVersion, baseImage)
}
}
}
parallel testMatrix
}
}
}
}
}
parallel(testMatrix)
def buildImage(baseImage) {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
image = docker.image(imageName)
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
try {
image.pull()
} catch (Exception exc) {
ansiColor('xterm') {
sh """docker build -t ${imageName} \\
--target build \\
--build-arg BUILD_PLATFORM="${baseImage}" \\
--build-arg GIT_COMMIT="${scmvar.GIT_COMMIT}" \\
.\\
"""
sh "docker push ${imageName}"
}
echo "${imageName}"
return imageName
}
}
}
def runTests(dockerVersion, pythonVersion, baseImage) {
return {
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
node("ubuntu && amd64 && !zfs") {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def storageDriver = sh(script: "docker info -f \'{{.Driver}}\'", returnStdout: true).trim()
echo "Using local system's storage driver: ${storageDriver}"
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
sh """docker run \\
-t \\
--rm \\
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
-e "TAG=${imageName}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersion}" \\
-e "BUILD_NUMBER=${env.BUILD_NUMBER}" \\
-e "PY_TEST_VERSIONS=${pythonVersion}" \\
--entrypoint="script/test/ci" \\
${imageName} \\
--verbose
"""
}
}
}
}
}

View File

@@ -11,6 +11,7 @@
[Org]
[Org."Core maintainers"]
people = [
"ndeloof",
"rumpl",
"ulyssessouza",
]
@@ -77,6 +78,11 @@
Email = "mazz@houseofmnowster.com"
GitHub = "mnowster"
[people.ndeloof]
Name = "Nicolas De Loof"
Email = "nicolas.deloof@gmail.com"
GitHub = "ndeloof"
[people.rumpl]
Name = "Djordje Lukic"
Email = "djordje.lukic@docker.com"

View File

@@ -2,6 +2,8 @@ Docker Compose
==============
![Docker Compose](logo.png?raw=true "Docker Compose Logo")
## :exclamation: The docker-compose project announces that as Python 2 reaches it's EOL, versions 1.25.x will be the last to support it. For more information, please refer to this [issue](https://github.com/docker/compose/issues/6890).
Compose is a tool for defining and running multi-container Docker applications.
With Compose, you use a Compose file to configure your application's services.
Then, using a single command, you create and start all the services

314
Release.Jenkinsfile Normal file
View File

@@ -0,0 +1,314 @@
#!groovy
def dockerVersions = ['19.03.5', '18.09.9']
def baseImages = ['alpine', 'debian']
def pythonVersions = ['py37']
pipeline {
agent none
options {
skipDefaultCheckout(true)
buildDiscarder(logRotator(daysToKeepStr: '30'))
timeout(time: 2, unit: 'HOURS')
timestamps()
}
stages {
stage('Build test images') {
// TODO use declarative 1.5.0 `matrix` once available on CI
parallel {
stage('alpine') {
agent {
label 'linux'
}
steps {
buildImage('alpine')
}
}
stage('debian') {
agent {
label 'linux'
}
steps {
buildImage('debian')
}
}
}
}
stage('Test') {
steps {
// TODO use declarative 1.5.0 `matrix` once available on CI
script {
def testMatrix = [:]
baseImages.each { baseImage ->
dockerVersions.each { dockerVersion ->
pythonVersions.each { pythonVersion ->
testMatrix["${baseImage}_${dockerVersion}_${pythonVersion}"] = runTests(dockerVersion, pythonVersion, baseImage)
}
}
}
parallel testMatrix
}
}
}
stage('Generate Changelog') {
agent {
label 'linux'
}
steps {
checkout scm
withCredentials([string(credentialsId: 'github-compose-release-test-token', variable: 'GITHUB_TOKEN')]) {
sh "./script/release/generate_changelog.sh"
}
archiveArtifacts artifacts: 'CHANGELOG.md'
stash( name: "changelog", includes: 'CHANGELOG.md' )
}
}
stage('Package') {
parallel {
stage('macosx binary') {
agent {
label 'mac-python'
}
steps {
checkout scm
sh './script/setup/osx'
sh 'tox -e py37 -- tests/unit'
sh './script/build/osx'
dir ('dist') {
checksum('docker-compose-Darwin-x86_64')
checksum('docker-compose-Darwin-x86_64.tgz')
}
archiveArtifacts artifacts: 'dist/*', fingerprint: true
dir("dist") {
stash name: "bin-darwin"
}
}
}
stage('linux binary') {
agent {
label 'linux'
}
steps {
checkout scm
sh ' ./script/build/linux'
dir ('dist') {
checksum('docker-compose-Linux-x86_64')
}
archiveArtifacts artifacts: 'dist/*', fingerprint: true
dir("dist") {
stash name: "bin-linux"
}
}
}
stage('windows binary') {
agent {
label 'windows-python'
}
environment {
PATH = "$PATH;C:\\Python37;C:\\Python37\\Scripts"
}
steps {
checkout scm
bat 'tox.exe -e py37 -- tests/unit'
powershell '.\\script\\build\\windows.ps1'
dir ('dist') {
checksum('docker-compose-Windows-x86_64.exe')
}
archiveArtifacts artifacts: 'dist/*', fingerprint: true
dir("dist") {
stash name: "bin-win"
}
}
}
stage('alpine image') {
agent {
label 'linux'
}
steps {
buildRuntimeImage('alpine')
}
}
stage('debian image') {
agent {
label 'linux'
}
steps {
buildRuntimeImage('debian')
}
}
}
}
stage('Release') {
when {
buildingTag()
}
parallel {
stage('Pushing images') {
agent {
label 'linux'
}
steps {
pushRuntimeImage('alpine')
pushRuntimeImage('debian')
}
}
stage('Creating Github Release') {
agent {
label 'linux'
}
steps {
checkout scm
sh 'mkdir -p dist'
dir("dist") {
unstash "bin-darwin"
unstash "bin-linux"
unstash "bin-win"
unstash "changelog"
githubRelease()
}
}
}
stage('Publishing Python packages') {
agent {
label 'linux'
}
steps {
checkout scm
withCredentials([file(credentialsId: 'pypirc-docker-dsg-cibot', variable: 'PYPIRC')]) {
sh """
pip install --user twine wheel
python setup.py sdist bdist_wheel
twine upload --config-file ${PYPIRC} ./dist/docker-compose-${env.TAG_NAME}.tar.gz ./dist/docker_compose-${env.TAG_NAME}-py2.py3-none-any.whl
"""
}
}
}
}
}
}
}
def buildImage(baseImage) {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
image = docker.image(imageName)
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
try {
image.pull()
} catch (Exception exc) {
ansiColor('xterm') {
sh """docker build -t ${imageName} \\
--target build \\
--build-arg BUILD_PLATFORM="${baseImage}" \\
--build-arg GIT_COMMIT="${scmvar.GIT_COMMIT}" \\
.\\
"""
sh "docker push ${imageName}"
}
echo "${imageName}"
return imageName
}
}
}
def runTests(dockerVersion, pythonVersion, baseImage) {
return {
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
node("linux") {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def storageDriver = sh(script: "docker info -f \'{{.Driver}}\'", returnStdout: true).trim()
echo "Using local system's storage driver: ${storageDriver}"
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
sh """docker run \\
-t \\
--rm \\
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
-e "TAG=${imageName}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersion}" \\
-e "BUILD_NUMBER=${env.BUILD_NUMBER}" \\
-e "PY_TEST_VERSIONS=${pythonVersion}" \\
--entrypoint="script/test/ci" \\
${imageName} \\
--verbose
"""
}
}
}
}
}
def buildRuntimeImage(baseImage) {
scmvar = checkout scm
def imageName = "docker/compose:${baseImage}-${env.BRANCH_NAME}"
ansiColor('xterm') {
sh """docker build -t ${imageName} \\
--build-arg BUILD_PLATFORM="${baseImage}" \\
--build-arg GIT_COMMIT="${scmvar.GIT_COMMIT.take(7)}" \\
.
"""
}
sh "mkdir -p dist"
sh "docker save ${imageName} -o dist/docker-compose-${baseImage}.tar"
stash name: "compose-${baseImage}", includes: "dist/docker-compose-${baseImage}.tar"
}
def pushRuntimeImage(baseImage) {
unstash "compose-${baseImage}"
sh "docker load -i dist/docker-compose-${baseImage}.tar"
withDockerRegistry(credentialsId: 'dockerbuildbot-hub.docker.com') {
sh "docker push docker/compose:${baseImage}-${env.TAG_NAME}"
if (baseImage == "alpine" && env.TAG_NAME != null) {
sh "docker tag docker/compose:alpine-${env.TAG_NAME} docker/compose:${env.TAG_NAME}"
sh "docker push docker/compose:${env.TAG_NAME}"
}
}
}
def githubRelease() {
withCredentials([string(credentialsId: 'github-compose-release-test-token', variable: 'GITHUB_TOKEN')]) {
def prerelease = !( env.TAG_NAME ==~ /v[0-9\.]+/ )
changelog = readFile "CHANGELOG.md"
def info = [:]
info.tag_name = env.TAG_NAME
info.name = env.TAG_NAME
info.draft = true
info.prerelease = prerelease
info.body = changelog
writeFile file: 'release.json', text: groovy.json.JsonOutput.toJson(info)
// debug
sh("cat release.json")
def url = "https://api.github.com/repos/docker/compose/releases"
def upload_url = sh(returnStdout: true, script: """
curl -sSf -H 'Authorization: token ${GITHUB_TOKEN}' -H 'Accept: application/json' -H 'Content-type: application/json' -X POST --data-binary '@release.json' $url) \\
| jq '.upload_url | .[:rindex("{")]'
""")
sh("""
for f in * ; do
curl -sf -H 'Authorization: token ${GITHUB_TOKEN}' -H 'Accept: application/json' -H 'Content-type: application/octet-stream' \\
-X POST --data-binary @\$f ${upload_url}?name=\$f;
done
""")
}
}
def checksum(filepath) {
if (isUnix()) {
sh "openssl sha256 -r -out ${filepath}.sha256 ${filepath}"
} else {
powershell "(Get-FileHash -Path ${filepath} -Algorithm SHA256 | % hash) + ' *${filepath}' > ${filepath}.sha256"
}
}

View File

@@ -1,24 +0,0 @@
version: '{branch}-{build}'
install:
- "SET PATH=C:\\Python37-x64;C:\\Python37-x64\\Scripts;%PATH%"
- "python --version"
- "pip install tox==2.9.1 virtualenv==16.2.0"
# Build the binary after tests
build: false
test_script:
- "tox -e py27,py37 -- tests/unit"
- ps: ".\\script\\build\\windows.ps1"
artifacts:
- path: .\dist\docker-compose-Windows-x86_64.exe
name: "Compose Windows binary"
deploy:
- provider: Environment
name: master-builds
on:
branch: master

View File

@@ -1,4 +1,4 @@
from __future__ import absolute_import
from __future__ import unicode_literals
__version__ = '1.25.0dev'
__version__ = '1.26.0dev'

View File

@@ -159,15 +159,25 @@ def get_project(project_dir, config_path=None, project_name=None, verbose=False,
def execution_context_labels(config_details, environment_file):
extra_labels = [
'{0}={1}'.format(LABEL_WORKING_DIR, os.path.abspath(config_details.working_dir)),
'{0}={1}'.format(LABEL_CONFIG_FILES, config_files_label(config_details)),
'{0}={1}'.format(LABEL_WORKING_DIR, os.path.abspath(config_details.working_dir))
]
if not use_config_from_stdin(config_details):
extra_labels.append('{0}={1}'.format(LABEL_CONFIG_FILES, config_files_label(config_details)))
if environment_file is not None:
extra_labels.append('{0}={1}'.format(LABEL_ENVIRONMENT_FILE,
os.path.normpath(environment_file)))
return extra_labels
def use_config_from_stdin(config_details):
for c in config_details.config_files:
if not c.filename:
return True
return False
def config_files_label(config_details):
return ",".join(
map(str, (os.path.normpath(c.filename) for c in config_details.config_files)))

View File

@@ -17,7 +17,12 @@ else:
def get_tty_width():
try:
width, _ = get_terminal_size()
# get_terminal_size can't determine the size if compose is piped
# to another command. But in such case it doesn't make sense to
# try format the output by terminal size as this output is consumed
# by another command. So let's pretend we have a huge terminal so
# output is single-lined
width, _ = get_terminal_size(fallback=(999, 0))
return int(width)
except OSError:
return 0

View File

@@ -5,6 +5,7 @@ import functools
import io
import logging
import os
import re
import string
import sys
from collections import namedtuple
@@ -214,6 +215,12 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
.format(self.filename, VERSION_EXPLANATION)
)
version_pattern = re.compile(r"^[2-9]+(\.\d+)?$")
if not version_pattern.match(version):
raise ConfigurationError(
'Version "{}" in "{}" is invalid.'
.format(version, self.filename))
if version == '2':
return const.COMPOSEFILE_V2_0

View File

@@ -114,3 +114,13 @@ def get_digest_from_push(events):
if digest:
return digest
return None
def read_status(event):
status = event['status'].lower()
if 'progressDetail' in event:
detail = event['progressDetail']
if 'current' in detail and 'total' in detail:
percentage = float(detail['current']) / float(detail['total'])
status = '{} ({:.1%})'.format(status, percentage)
return status

View File

@@ -11,6 +11,8 @@ from os import path
import enum
import six
from docker.errors import APIError
from docker.errors import ImageNotFound
from docker.errors import NotFound
from docker.utils import version_lt
from . import parallel
@@ -25,6 +27,7 @@ from .container import Container
from .network import build_networks
from .network import get_networks
from .network import ProjectNetworks
from .progress_stream import read_status
from .service import BuildAction
from .service import ContainerNetworkMode
from .service import ContainerPidMode
@@ -619,49 +622,68 @@ class Project(object):
def pull(self, service_names=None, ignore_pull_failures=False, parallel_pull=False, silent=False,
include_deps=False):
services = self.get_services(service_names, include_deps)
images_to_build = {service.image_name for service in services if service.can_be_built()}
services_to_pull = [service for service in services if service.image_name not in images_to_build]
msg = not silent and 'Pulling' or None
if parallel_pull:
def pull_service(service):
strm = service.pull(ignore_pull_failures, True, stream=True)
if strm is None: # Attempting to pull service with no `image` key is a no-op
return
self.parallel_pull(services, silent=silent)
else:
must_build = []
for service in services:
try:
service.pull(ignore_pull_failures, silent=silent)
except (ImageNotFound, NotFound):
if service.can_be_built():
must_build.append(service.name)
else:
raise
if len(must_build):
log.warning('Some service image(s) must be built from source by running:\n'
' docker-compose build {}'
.format(' '.join(must_build)))
def parallel_pull(self, services, ignore_pull_failures=False, silent=False):
msg = 'Pulling' if not silent else None
must_build = []
def pull_service(service):
strm = service.pull(ignore_pull_failures, True, stream=True)
if strm is None: # Attempting to pull service with no `image` key is a no-op
return
try:
writer = parallel.get_stream_writer()
for event in strm:
if 'status' not in event:
continue
status = event['status'].lower()
if 'progressDetail' in event:
detail = event['progressDetail']
if 'current' in detail and 'total' in detail:
percentage = float(detail['current']) / float(detail['total'])
status = '{} ({:.1%})'.format(status, percentage)
status = read_status(event)
writer.write(
msg, service.name, truncate_string(status), lambda s: s
)
except (ImageNotFound, NotFound):
if service.can_be_built():
must_build.append(service.name)
else:
raise
_, errors = parallel.parallel_execute(
services_to_pull,
pull_service,
operator.attrgetter('name'),
msg,
limit=5,
)
if len(errors):
combined_errors = '\n'.join([
e.decode('utf-8') if isinstance(e, six.binary_type) else e for e in errors.values()
])
raise ProjectError(combined_errors)
_, errors = parallel.parallel_execute(
services,
pull_service,
operator.attrgetter('name'),
msg,
limit=5,
)
else:
for service in services_to_pull:
service.pull(ignore_pull_failures, silent=silent)
if len(must_build):
log.warning('Some service image(s) must be built from source by running:\n'
' docker-compose build {}'
.format(' '.join(must_build)))
if len(errors):
combined_errors = '\n'.join([
e.decode('utf-8') if isinstance(e, six.binary_type) else e for e in errors.values()
])
raise ProjectError(combined_errors)
def push(self, service_names=None, ignore_push_failures=False):
unique_images = set()

View File

@@ -60,6 +60,7 @@ from .utils import parse_bytes
from .utils import parse_seconds_float
from .utils import truncate_id
from .utils import unique_everseen
from compose.cli.utils import binarystr_to_unicode
if six.PY2:
import subprocess32 as subprocess
@@ -343,7 +344,7 @@ class Service(object):
return Container.create(self.client, **container_options)
except APIError as ex:
raise OperationFailedError("Cannot create container for service %s: %s" %
(self.name, ex.explanation))
(self.name, binarystr_to_unicode(ex.explanation)))
def ensure_image_exists(self, do_build=BuildAction.none, silent=False, cli=False):
if self.can_be_built() and do_build == BuildAction.force:
@@ -624,9 +625,10 @@ class Service(object):
try:
container.start()
except APIError as ex:
if "driver failed programming external connectivity" in ex.explanation:
expl = binarystr_to_unicode(ex.explanation)
if "driver failed programming external connectivity" in expl:
log.warn("Host is already in use by another container")
raise OperationFailedError("Cannot start service %s: %s" % (self.name, ex.explanation))
raise OperationFailedError("Cannot start service %s: %s" % (self.name, expl))
return container
@property

108
docker-compose_darwin.spec Normal file
View File

@@ -0,0 +1,108 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['bin/docker-compose'],
pathex=['.'],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='docker-compose',
debug=False,
strip=False,
upx=True,
console=True,
bootloader_ignore_signals=True)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
[
(
'compose/config/config_schema_v1.json',
'compose/config/config_schema_v1.json',
'DATA'
),
(
'compose/config/config_schema_v2.0.json',
'compose/config/config_schema_v2.0.json',
'DATA'
),
(
'compose/config/config_schema_v2.1.json',
'compose/config/config_schema_v2.1.json',
'DATA'
),
(
'compose/config/config_schema_v2.2.json',
'compose/config/config_schema_v2.2.json',
'DATA'
),
(
'compose/config/config_schema_v2.3.json',
'compose/config/config_schema_v2.3.json',
'DATA'
),
(
'compose/config/config_schema_v2.4.json',
'compose/config/config_schema_v2.4.json',
'DATA'
),
(
'compose/config/config_schema_v3.0.json',
'compose/config/config_schema_v3.0.json',
'DATA'
),
(
'compose/config/config_schema_v3.1.json',
'compose/config/config_schema_v3.1.json',
'DATA'
),
(
'compose/config/config_schema_v3.2.json',
'compose/config/config_schema_v3.2.json',
'DATA'
),
(
'compose/config/config_schema_v3.3.json',
'compose/config/config_schema_v3.3.json',
'DATA'
),
(
'compose/config/config_schema_v3.4.json',
'compose/config/config_schema_v3.4.json',
'DATA'
),
(
'compose/config/config_schema_v3.5.json',
'compose/config/config_schema_v3.5.json',
'DATA'
),
(
'compose/config/config_schema_v3.6.json',
'compose/config/config_schema_v3.6.json',
'DATA'
),
(
'compose/config/config_schema_v3.7.json',
'compose/config/config_schema_v3.7.json',
'DATA'
),
(
'compose/GITSHA',
'compose/GITSHA',
'DATA'
)
],
strip=False,
upx=True,
upx_exclude=[],
name='docker-compose-Darwin-x86_64')

View File

@@ -1,6 +1,6 @@
coverage==4.4.2
coverage==4.5.4
ddt==1.2.0
flake8==3.5.0
flake8==3.7.9
mock==3.0.5
pytest==3.6.3
pytest-cov==2.5.1
pytest-cov==2.8.1

View File

@@ -20,6 +20,7 @@ PySocks==1.6.7
PyYAML==4.2b1
requests==2.22.0
six==1.12.0
subprocess32==3.5.4; python_version < '3.2'
texttable==1.6.2
urllib3==1.24.2; python_version == '3.3'
websocket-client==0.32.0

View File

@@ -1,20 +0,0 @@
pipeline {
agent any
stages {
stage("License Scan") {
agent {
label 'ubuntu-1604-aufs-edge'
}
steps {
withCredentials([
string(credentialsId: 'fossa-api-key', variable: 'FOSSA_API_KEY')
]) {
checkout scm
sh "FOSSA_API_KEY='${FOSSA_API_KEY}' BRANCH_NAME='${env.BRANCH_NAME}' make -f script/fossa.mk fossa-analyze"
sh "FOSSA_API_KEY='${FOSSA_API_KEY}' make -f script/fossa.mk fossa-test"
}
}
}
}
}

View File

@@ -11,6 +11,14 @@ venv/bin/pip install -r requirements-build.txt
venv/bin/pip install --no-deps .
DOCKER_COMPOSE_GITSHA="$(script/build/write-git-sha)"
echo "${DOCKER_COMPOSE_GITSHA}" > compose/GITSHA
# Build as a folder for macOS Catalina.
venv/bin/pyinstaller docker-compose_darwin.spec
dist/docker-compose-Darwin-x86_64/docker-compose version
(cd dist/docker-compose-Darwin-x86_64/ && tar zcvf ../docker-compose-Darwin-x86_64.tgz .)
rm -rf dist/docker-compose-Darwin-x86_64
# Build static binary for legacy.
venv/bin/pyinstaller docker-compose.spec
mv dist/docker-compose dist/docker-compose-Darwin-x86_64
dist/docker-compose-Darwin-x86_64 version

View File

@@ -25,3 +25,11 @@ curl -f -T dist/docker-compose-${OS_NAME}-x86_64 -u$BINTRAY_USERNAME:$BINTRAY_AP
-H "X-Bintray-Package: ${PKG_NAME}" -H "X-Bintray-Version: $CIRCLE_BRANCH" \
-H "X-Bintray-Override: 1" -H "X-Bintray-Publish: 1" -X PUT \
https://api.bintray.com/content/docker-compose/${CIRCLE_BRANCH}/docker-compose-${OS_NAME}-x86_64 || exit 1
# Upload folder format of docker-compose for macOS in addition to binary.
if [ "${OS_NAME}" == "Darwin" ]; then
curl -f -T dist/docker-compose-${OS_NAME}-x86_64.tgz -u$BINTRAY_USERNAME:$BINTRAY_API_KEY \
-H "X-Bintray-Package: ${PKG_NAME}" -H "X-Bintray-Version: $CIRCLE_BRANCH" \
-H "X-Bintray-Override: 1" -H "X-Bintray-Publish: 1" -X PUT \
https://api.bintray.com/content/docker-compose/${CIRCLE_BRANCH}/docker-compose-${OS_NAME}-x86_64.tgz || exit 1
fi

View File

@@ -1,16 +0,0 @@
# Variables for Fossa
BUILD_ANALYZER?=docker/fossa-analyzer
FOSSA_OPTS?=--option all-tags:true --option allow-unresolved:true
fossa-analyze:
docker run --rm -e FOSSA_API_KEY=$(FOSSA_API_KEY) \
-v $(CURDIR)/$*:/go/src/github.com/docker/compose \
-w /go/src/github.com/docker/compose \
$(BUILD_ANALYZER) analyze ${FOSSA_OPTS} --branch ${BRANCH_NAME}
# This command is used to run the fossa test command
fossa-test:
docker run -i -e FOSSA_API_KEY=$(FOSSA_API_KEY) \
-v $(CURDIR)/$*:/go/src/github.com/docker/compose \
-w /go/src/github.com/docker/compose \
$(BUILD_ANALYZER) test

View File

@@ -0,0 +1,39 @@
#!/bin/bash
set -e
set -x
## Usage :
## changelog PREVIOUS_TAG..HEAD
# configure refs so we get pull-requests metadata
git config --add remote.origin.fetch +refs/pull/*/head:refs/remotes/origin/pull/*
git fetch origin
RANGE=${1:-"$(git describe --tags --abbrev=0)..HEAD"}
echo "Generate changelog for range ${RANGE}"
echo
pullrequests() {
for commit in $(git log ${RANGE} --format='format:%H'); do
# Get the oldest remotes/origin/pull/* branch to include this commit, i.e. the one to introduce it
git branch -a --sort=committerdate --contains $commit --list 'origin/pull/*' | head -1 | cut -d'/' -f4
done
}
changes=$(pullrequests | uniq)
echo "pull requests merged within range:"
echo $changes
echo '#Features' > CHANGELOG.md
for pr in $changes; do
curl -fs -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/docker/compose/pulls/${pr} \
| jq -r ' select( .labels[].name | contains("kind/feature") ) | "* "+.title' >> CHANGELOG.md
done
echo '#Bugs' >> CHANGELOG.md
for pr in $changes; do
curl -fs -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/repos/docker/compose/pulls/${pr} \
| jq -r ' select( .labels[].name | contains("kind/bug") ) | "* "+.title' >> CHANGELOG.md
done

View File

@@ -204,7 +204,8 @@ def resume(args):
gh_release = create_release_draft(repository, args.release, pr_data, files)
delete_assets(gh_release)
upload_assets(gh_release, files)
img_manager = ImageManager(args.release)
tag_as_latest = is_tag_latest(args.release)
img_manager = ImageManager(args.release, tag_as_latest)
img_manager.build_images(repository)
except ScriptError as e:
print(e)
@@ -244,7 +245,8 @@ def start(args):
files = downloader.download_all(args.release)
gh_release = create_release_draft(repository, args.release, pr_data, files)
upload_assets(gh_release, files)
img_manager = ImageManager(args.release)
tag_as_latest = is_tag_latest(args.release)
img_manager = ImageManager(args.release, tag_as_latest)
img_manager.build_images(repository)
except ScriptError as e:
print(e)

View File

@@ -55,6 +55,7 @@ class BinaryDownloader(requests.Session):
def download_all(self, version):
files = {
'docker-compose-Darwin-x86_64.tgz': None,
'docker-compose-Darwin-x86_64': None,
'docker-compose-Linux-x86_64': None,
'docker-compose-Windows-x86_64.exe': None,

View File

@@ -15,7 +15,7 @@
set -e
VERSION="1.24.0"
VERSION="1.25.1"
IMAGE="docker/compose:$VERSION"
@@ -36,18 +36,18 @@ if [ "$(pwd)" != '/' ]; then
fi
if [ -n "$COMPOSE_FILE" ]; then
COMPOSE_OPTIONS="$COMPOSE_OPTIONS -e COMPOSE_FILE=$COMPOSE_FILE"
compose_dir=$(realpath $(dirname $COMPOSE_FILE))
compose_dir=$(realpath "$(dirname "$COMPOSE_FILE")")
fi
# TODO: also check --file argument
if [ -n "$compose_dir" ]; then
VOLUMES="$VOLUMES -v $compose_dir:$compose_dir"
fi
if [ -n "$HOME" ]; then
VOLUMES="$VOLUMES -v $HOME:$HOME -v $HOME:/root" # mount $HOME in /root to share docker.config
VOLUMES="$VOLUMES -v $HOME:$HOME -e HOME" # Pass in HOME to share docker.config and allow ~/-relative paths to work.
fi
# Only allocate tty if we detect one
if [ -t 0 -a -t 1 ]; then
if [ -t 0 ] && [ -t 1 ]; then
DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -t"
fi
@@ -56,8 +56,9 @@ DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS -i"
# Handle userns security
if [ ! -z "$(docker info 2>/dev/null | grep userns)" ]; then
if docker info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -q 'name=userns'; then
DOCKER_RUN_OPTIONS="$DOCKER_RUN_OPTIONS --userns=host"
fi
# shellcheck disable=SC2086
exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" $IMAGE "$@"

View File

@@ -36,7 +36,7 @@ if ! [ -x "$(command -v python3)" ]; then
brew install python3
fi
if ! [ -x "$(command -v virtualenv)" ]; then
pip install virtualenv==16.2.0
pip3 install virtualenv==16.2.0
fi
#

View File

@@ -48,6 +48,7 @@ BUILD_PULL_TEXT = 'Status: Image is up to date for busybox:1.27.2'
def start_process(base_dir, options):
proc = subprocess.Popen(
['docker-compose'] + options,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=base_dir)
@@ -55,8 +56,8 @@ def start_process(base_dir, options):
return proc
def wait_on_process(proc, returncode=0):
stdout, stderr = proc.communicate()
def wait_on_process(proc, returncode=0, stdin=None):
stdout, stderr = proc.communicate(input=stdin)
if proc.returncode != returncode:
print("Stderr: {}".format(stderr))
print("Stdout: {}".format(stdout))
@@ -64,10 +65,10 @@ def wait_on_process(proc, returncode=0):
return ProcessResult(stdout.decode('utf-8'), stderr.decode('utf-8'))
def dispatch(base_dir, options, project_options=None, returncode=0):
def dispatch(base_dir, options, project_options=None, returncode=0, stdin=None):
project_options = project_options or []
proc = start_process(base_dir, project_options + options)
return wait_on_process(proc, returncode=returncode)
return wait_on_process(proc, returncode=returncode, stdin=stdin)
def wait_on_condition(condition, delay=0.1, timeout=40):
@@ -156,8 +157,8 @@ class CLITestCase(DockerClientTestCase):
self._project = get_project(self.base_dir, override_dir=self.override_dir)
return self._project
def dispatch(self, options, project_options=None, returncode=0):
return dispatch(self.base_dir, options, project_options, returncode)
def dispatch(self, options, project_options=None, returncode=0, stdin=None):
return dispatch(self.base_dir, options, project_options, returncode, stdin)
def execute(self, container, cmd):
# Remove once Hijack and CloseNotifier sign a peace treaty
@@ -241,6 +242,17 @@ class CLITestCase(DockerClientTestCase):
self.base_dir = 'tests/fixtures/v2-full'
assert self.dispatch(['config', '--quiet']).stdout == ''
def test_config_stdin(self):
config = b"""version: "3.7"
services:
web:
image: nginx
other:
image: alpine
"""
result = self.dispatch(['-f', '-', 'config', '--services'], stdin=config)
assert set(result.stdout.rstrip().split('\n')) == {'web', 'other'}
def test_config_with_hash_option(self):
self.base_dir = 'tests/fixtures/v2-full'
result = self.dispatch(['config', '--hash=*'])
@@ -661,13 +673,6 @@ class CLITestCase(DockerClientTestCase):
'image library/nonexisting-image:latest not found' in result.stderr or
'pull access denied for nonexisting-image' in result.stderr)
def test_pull_with_build(self):
result = self.dispatch(['-f', 'pull-with-build.yml', 'pull'])
assert 'Pulling simple' not in result.stderr
assert 'Pulling from_simple' not in result.stderr
assert 'Pulling another ...' in result.stderr
def test_pull_with_quiet(self):
assert self.dispatch(['pull', '--quiet']).stderr == ''
assert self.dispatch(['pull', '--quiet']).stdout == ''
@@ -689,6 +694,14 @@ class CLITestCase(DockerClientTestCase):
result.stderr
)
def test_pull_can_build(self):
result = self.dispatch([
'-f', 'can-build-pull-failures.yml', 'pull'],
returncode=0
)
assert 'Some service image(s) must be built from source' in result.stderr
assert 'docker-compose build can_build' in result.stderr
def test_pull_with_no_deps(self):
self.base_dir = 'tests/fixtures/links-composefile'
result = self.dispatch(['pull', '--no-parallel', 'web'])

View File

@@ -0,0 +1,6 @@
version: '3'
services:
can_build:
image: nonexisting-image-but-can-build:latest
build: .
command: top

View File

@@ -13,6 +13,8 @@ from random import shuffle
import py
import pytest
import yaml
from ddt import data
from ddt import ddt
from ...helpers import build_config_details
from ...helpers import BUSYBOX_IMAGE_WITH_TAG
@@ -68,6 +70,7 @@ def secret_sort(secrets):
return sorted(secrets, key=itemgetter('source'))
@ddt
class ConfigTest(unittest.TestCase):
def test_load(self):
@@ -1885,6 +1888,26 @@ class ConfigTest(unittest.TestCase):
}
]
@data(
'2 ',
'3.',
'3.0.0',
'3.0.a',
'3.a',
'3a')
def test_invalid_version_formats(self, version):
content = {
'version': version,
'services': {
'web': {
'image': 'alpine',
}
}
}
with pytest.raises(ConfigurationError) as exc:
config.load(build_config_details(content))
assert 'Version "{}" in "filename.yml" is invalid.'.format(version) in exc.exconly()
def test_group_add_option(self):
actual = config.load(build_config_details({
'version': '2',

View File

@@ -521,7 +521,37 @@ class ServiceTest(unittest.TestCase):
assert 'was built because it did not already exist' in args[0]
assert self.mock_client.build.call_count == 1
self.mock_client.build.call_args[1]['tag'] == 'default_foo'
assert self.mock_client.build.call_args[1]['tag'] == 'default_foo'
def test_create_container_binary_string_error(self):
service = Service('foo', client=self.mock_client, build={'context': '.'})
service.image = lambda: {'Id': 'abc123'}
self.mock_client.create_container.side_effect = APIError(None,
None,
b"Test binary string explanation")
with pytest.raises(OperationFailedError) as ex:
service.create_container()
assert ex.value.msg == "Cannot create container for service foo: Test binary string explanation"
def test_start_binary_string_error(self):
service = Service('foo', client=self.mock_client)
container = Container(self.mock_client, {'Id': 'abc123'})
self.mock_client.start.side_effect = APIError(None,
None,
b"Test binary string explanation with "
b"driver failed programming external "
b"connectivity")
with mock.patch('compose.service.log', autospec=True) as mock_log:
with pytest.raises(OperationFailedError) as ex:
service.start_container(container)
assert ex.value.msg == "Cannot start service foo: " \
"Test binary string explanation " \
"with driver failed programming external connectivity"
mock_log.warn.assert_called_once_with("Host is already in use by another container")
def test_ensure_image_exists_no_build(self):
service = Service('foo', client=self.mock_client, build={'context': '.'})