Compare commits

..

110 Commits

Author SHA1 Message Date
Anca Iordache
0773730525 "Bump 1.29.0"
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-04-06 20:54:33 +02:00
Anca Iordache
c81046aac0 Merge pull request #8239 from timoxley/patch-1
Mention `--ansi never` in `--no-ansi` deprecation
2021-04-06 19:04:25 +01:00
Tim Kevin Oxley
84c816e887 Mention --ansi never in --no-ansi deprecation
Ideally deprecation messages should point users directly at the non-deprecated alternative so it's a no-brainer for someone to switch to it.

Signed-off-by: Tim Kevin Oxley <secoif@gmail.com>
2021-04-06 14:59:34 -03:00
Anca Iordache
1607674374 Merge pull request #8256 from ulyssessouza/bump-py-5
Bump docker-py to 5.0.0 and PyYAML to 5.4.1
2021-04-06 18:48:20 +01:00
Anca Iordache
683fac0dbf Merge pull request #8122 from ojab/add_init_containers
Add init container support
2021-04-06 18:25:24 +01:00
Ulysses Souza
ddee2958ec Bump docker-py to 5.0.0 and PyYAML to 5.4.1
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-04-06 14:24:48 -03:00
Anca Iordache
1ab1cd202b Merge pull request #8091 from docker/dependabot/pip/packaging-20.9
Bump packaging from 20.4 to 20.9
2021-04-06 18:18:25 +01:00
Anca Iordache
1752927dcd Merge pull request #8183 from docker/dependabot/pip/coverage-5.5
Bump coverage from 5.2.1 to 5.5
2021-04-06 18:13:21 +01:00
Anca Iordache
c2ddd71e5f Merge pull request #8232 from aiordache/release_1.28.6
Update changelog for 1.28.6
2021-04-06 18:11:52 +01:00
Anca Iordache
72bbd9c3a6 Merge pull request #8253 from docker/dependabot/pip/python-dotenv-0.17.0
Bump python-dotenv from 0.14.0 to 0.17.0
2021-04-06 18:10:04 +01:00
Anca Iordache
3c9ee678e7 Merge pull request #8247 from ulyssessouza/scan-suggestion
Add Snyk scan suggestion when building
2021-04-06 10:09:07 +01:00
dependabot-preview[bot]
92fefbc9cc Bump python-dotenv from 0.14.0 to 0.17.0
Bumps [python-dotenv](https://github.com/theskumar/python-dotenv) from 0.14.0 to 0.17.0.
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v0.14.0...v0.17.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-05 21:23:08 +00:00
Ulysses Souza
e496c64127 Add Snyk scan suggestion when building
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-04-05 12:34:45 -03:00
Chris Crone
84afa518e8 Merge pull request #8061 from albers/completion-profiles
Add bash completion for profiles and a command to list profiles
2021-03-30 09:33:50 +02:00
Anca Iordache
0f6a55e036 Update changelog for 1.28.6
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-23 15:18:15 +01:00
Anca Iordache
8ce5e235e4 Add back storage_opts as service property
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-23 11:02:51 +01:00
Anca Iordache
c1dddbe608 Merge pull request #8213 from ulyssessouza/fix-exec-error-msg
Fix on removing error message on 'exec' error
2021-03-19 09:45:34 +01:00
Anca Iordache
981b0cd641 Merge pull request #8178 from mgorny/cached-prop-dep
Use built-in functools.cached_property when possible
2021-03-18 20:17:49 +01:00
Ulysses Souza
5ec8af582c Fix on removing error message on 'exec' error
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-03-17 17:49:15 -03:00
Anca Iordache
f5342b600c Add compose.yaml/.yml to default filenames
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-16 18:04:51 +01:00
Anca Iordache
4a26d95de4 Make --env-file paths relative to current working directory
Look up compose files in project dir as fallback to no compose file in current working directory
Update config and env-file tests
 - get_default_config does not raise error anymore, returns None if no compose file is found

Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-16 18:04:51 +01:00
Ulysses Souza
5b7851f55b Merge pull request #8188 from aiordache/build_context
Do not use context as base dir for Dockerfile when context is a git url
2021-03-11 13:01:07 +01:00
Anca Iordache
eaa22df151 Do not use context as base dir for Dockerfile when context is a git url
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-09 19:21:08 +01:00
Ulysses Souza
551f680751 Merge pull request #8187 from aiordache/build_opts
Fix build.extra_hosts list format
2021-03-09 19:20:51 +01:00
Anca Iordache
3e071ec8d9 Fix build.extra_hosts list format
Signed-off-by: Anca Iordache <anca.iordache@docker.com>
2021-03-09 18:30:47 +01:00
dependabot-preview[bot]
858ff26731 Bump coverage from 5.2.1 to 5.5
Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.2.1 to 5.5.
- [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-5.2.1...coverage-5.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 22:20:16 +00:00
Michał Górny
2a7c06a050 Use built-in functools.cached_property when possible
The cached_property decorator is built-in in functools module since
Python 3.8.  Use the external cached_property package only for older
versions of Python.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
2021-03-06 18:45:59 +01:00
Ulysses Souza
d0b7bc3110 Merge pull request #8160 from aiordache/changelog_1.28.5
Update changelog for 1.28.5
2021-03-02 14:14:56 -03:00
Anca Iordache
fe4f16e448 Merge pull request #8166 from ulyssessouza/advertise-space-compose
Advertise `docker compose` for non linux users
2021-03-02 18:05:10 +01:00
Ulysses Souza
1da4301650 Advertise docker compose for non linux users
This adds messages on:
- Root command (only `docker-compose`)
- Command not found
- `help` command

Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-03-02 11:14:07 -03:00
aiordache
c594cb3fc3 Update changelog post-release 1.28.5
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-26 10:38:59 +01:00
Anca Iordache
89ad637d50 Merge pull request #8158 from ulyssessouza/fix-log-driver-none
Stop logging when log_driver is set to 'none'
2021-02-25 17:47:35 +01:00
Ulysses Souza
6ca2aed7ec Stop logging when log_driver is set to 'none'
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-25 13:16:39 -03:00
Anca Iordache
fc744a0cc9 Merge pull request #8156 from ulyssessouza/remove-native-log
Remove log.info for native build
2021-02-25 16:05:32 +01:00
Anca Iordache
245ede1d75 Merge pull request #8113 from joselfr/master
Add missing --add-host args to the build command
2021-02-25 15:54:54 +01:00
José Rodrigues
72f7b086d7 Add missing --add-host args to the build command
Signed-off-by: José Rodrigues <contact.jrodrigues@gmail.com>
2021-02-25 11:23:38 -03:00
Ulysses Souza
2f48b6f5e9 Remove log.info for native build
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-25 11:18:31 -03:00
Anca Iordache
e6fcde422c Merge pull request #8153 from aiordache/openssl_mismatch_bug
Fix openssl mismatch bug via docker-py bump (fix in docker-py 4.4.4)
2021-02-25 14:21:53 +01:00
Anca Iordache
75b2d7905f Merge pull request #8138 from aiordache/changelog_update_1.28.4
Update changelog for release 1.28.4
2021-02-24 18:33:04 +01:00
aiordache
efa5969086 Bump docker-py version to 4.4.4
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-24 18:26:12 +01:00
Ulysses Souza
2a4aca7f54 Merge pull request #8147 from aiordache/platform_build
Set `platform` and `isolation` options for cli builder
2021-02-23 09:11:10 -03:00
aiordache
9c8f5a5705 Set platform and isolation options for cli builder
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-23 09:50:45 +01:00
aiordache
62bbc5cfe2 Changelog update post-release 1.28.4
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-19 09:54:39 +01:00
Anca Iordache
66375c2871 Merge pull request #8135 from aiordache/test_auth
Fix docker/config path in the test containers
2021-02-18 19:36:21 +01:00
aiordache
c760600a65 fix config path for authentication
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-18 19:22:13 +01:00
Slava Kardakov
4daad056c4 Add init container support
Fixes #6855

See https://github.com/compose-spec/compose-spec/pull/134

Signed-off-by: Slava Kardakov <ojab@ojab.ru>
2021-02-18 17:47:59 +00:00
Ulysses Souza
74c09cac66 Merge pull request #8134 from aiordache/bump_docker_setup
Bump docker-py to 4.4.3 in setup.py
2021-02-18 13:27:42 -03:00
aiordache
36e470d640 Bump docker-py to 4.4.3 in setup.py
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-18 17:19:46 +01:00
aiordache
d28d717884 Fix SSH port parsing via docker-py bump
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-18 12:52:29 -03:00
Anca Iordache
42c2cfd7a6 Merge pull request #8133 from docker/fix-release-jenkins
Add cgroup1 as filter label
2021-02-18 16:51:55 +01:00
Ulysses Souza
5b983ac653 Add cgroup1 as filter label
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-18 12:24:04 -03:00
Anca Iordache
93425218eb Merge pull request #8130 from docker/fix-release-jenkins
Add label amd64 to filter the agents
2021-02-18 15:58:19 +01:00
aiordache
49d0ee2de5 Update changelog for release 1.28.3
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-18 11:48:29 -03:00
Ulysses Souza
a92c6d7e17 Add label amd64 to filter the agents
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-18 11:34:03 -03:00
Anca Iordache
b8800db52e Merge pull request #8129 from ulyssessouza/bump-python
Bump python to 3.7.10
2021-02-18 15:09:42 +01:00
Ulysses Souza
ccabfde353 Bump python to 3.7.10
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-18 11:04:25 -03:00
aiordache
3297bb50bb Update dind setup for tests
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-17 12:52:14 -03:00
Anca Iordache
e688006444 Merge pull request #8123 from ulyssessouza/fix-dict-access
Fix dics access on keep-prefix option for up
2021-02-16 20:16:50 +01:00
Ulysses Souza
e4a83c15ff Fix dics access on keep-prefix option for up
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-16 15:55:39 -03:00
Anca Iordache
824b9f138e Merge pull request #8094 from Agrendalath/agrendalath/fix_fish_completion
Fix fish completion
2021-02-16 19:48:09 +01:00
Anca Iordache
8654eb2ea3 Merge pull request #8120 from ulyssessouza/bump-docker-py
Bump docker-py
2021-02-15 18:54:30 +01:00
Ulysses Souza
9407ee65e5 Bump docker-py
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-02-15 14:19:37 -03:00
Anca Iordache
66c6d2757a Merge pull request #8082 from thaJeztah/remove_log_driver_check
Remove local check for log-driver read support
2021-02-15 17:07:34 +01:00
Anca Iordache
17daa93edf Merge pull request #8109 from docker/dependabot/pip/cryptography-3.3.2
[Security] Bump cryptography from 3.2.1 to 3.3.2
2021-02-15 16:41:42 +01:00
dependabot-preview[bot]
9795e39d0c [Security] Bump cryptography from 3.2.1 to 3.3.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 3.2.1 to 3.3.2. **This update includes a security fix.**
- [Release notes](https://github.com/pyca/cryptography/releases)
- [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/3.2.1...3.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-12 10:45:09 +00:00
Anca Iordache
393abc5b33 Merge pull request #8112 from aiordache/update_Jenkinsfile
Update test base image in Jenkinsfile
2021-02-12 11:33:06 +01:00
aiordache
d0866c8c18 Update test base image in Jenkinsfile
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-02-10 15:06:06 +01:00
Anca Iordache
546133c977 Merge pull request #8093 from JimCronqvist/master
Fix incorrect CLI env variable name for service profiles
2021-02-10 12:24:02 +01:00
Ulysses Souza
9a2f94713e Merge pull request #8080 from aiordache/update_changelog_1.28.2
Post-release 1.28.2 changelog updates
2021-02-09 16:36:27 -03:00
Agrendalath
b88f635514 Fix fish completion
Signed-off-by: Agrendalath <piotr@surowiec.it>
2021-02-03 00:29:16 +01:00
Jim Cronqvist
31002aeacd Fix incorrect CLI variable name for service profiles
Changed from singular to plural as defined in the docs, i.e. "COMPOSE_PROFILES"

Signed-off-by: Jim Cronqvist <jim.cronqvist@gmail.com>
2021-02-02 21:41:57 +01:00
dependabot-preview[bot]
6209baccf3 Bump packaging from 20.4 to 20.9
Bumps [packaging](https://github.com/pypa/packaging) from 20.4 to 20.9.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/20.4...20.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-01 22:22:56 +00:00
Sebastiaan van Stijn
28f8b8549d Remove local check for log-driver read support
Starting with Docker 20.10, the docker daemon has support for
"dual logging", which allows reading back logs, irregardless of
the logging-driver that is configured (except for "none" as logging
driver).

This patch removes the local check, which used a hard-coded list of
logging drivers that are expected to support reading logs.

When using an older version of Docker, the API should return an
error that reading logs is not supported, so no local check should
be needed.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-01-28 16:55:36 +01:00
aiordache
76a19ec8c5 Post-release changelog update
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-01-28 10:28:47 +01:00
Anca Iordache
bba8cd0322 Merge pull request #8045 from aiordache/changelog_1.28.0
Post-release 1.28.0: Update changelog and version
2021-01-26 21:07:24 +01:00
Anca Iordache
f2ec6a2176 Merge pull request #8070 from aiordache/Jenkins_cgroup1_label
Add `cgroup1` label to Release.Jenkinsfile
2021-01-25 19:11:50 +01:00
aiordache
7f7f1607de Add cgroup1 label to Release.Jenkinsfile
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-01-25 19:00:39 +01:00
Anca Iordache
4990a7f935 Merge pull request #8067 from albers/completion-no-log-prefix
Add bash completion for `docker-compose logs|up --no-log-prefix`, fix formatting of help message
2021-01-25 15:06:34 +01:00
Anca Iordache
72f8551466 Merge pull request #8058 from docker/py-37-revert
Revert to Python 3.7 bump for Linux static builds
2021-01-25 14:34:42 +01:00
Harald Albers
487779960c Fix formatting of help output for up|logs --no-log-prefix
Signed-off-by: Harald Albers <github@albersweb.de>
2021-01-24 22:19:37 +00:00
Harald Albers
99b6776fd2 Add bash completion for logs|up --no-log-prefix
This adds bash completion for https://github.com/docker/compose/pull/7435

Signed-off-by: Harald Albers <github@albersweb.de>
2021-01-24 22:18:36 +00:00
Harald Albers
4e382b9c28 Add bash completion for --profile
Signed-off-by: Harald Albers <github@albersweb.de>
2021-01-22 19:24:15 +00:00
Harald Albers
862107a32a Add option for listing service profiles
For command completion of `docker-compose --profile`, we need a portable
way to get a list of profiles used in the current config.

This commit adds a new option `docker-compose config --profiles`.

Signed-off-by: Harald Albers <github@albersweb.de>
2021-01-22 19:24:15 +00:00
Chris Crone
6a3af5b707 build.linux: Revert to Python 3.7
This allows us to revert from Debian Buster to Stretch which allows
us to relax the glibc version requirements.

Signed-off-by: Chris Crone <christopher.crone@docker.com>
2021-01-22 11:35:37 +01:00
aiordache
205d520805 Post-release 1.28.0: update changelog and version
Signed-off-by: aiordache <anca.iordache@docker.com>
2021-01-20 11:30:25 +01:00
Anca Iordache
8f2bb66e73 Merge pull request #8043 from docker/update-compose-spec
Update compose-spec
2021-01-19 19:00:43 +01:00
Ulysses Souza
af4eaae006 Update compose-spec
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-01-19 14:57:59 -03:00
Anca Iordache
1c547b270e Merge pull request #8042 from docker/fix-docker-version
Remove restriction on docker version
2021-01-19 18:37:22 +01:00
Ulysses Souza
1c499bb2eb Remove restriction on docker version
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-01-19 14:33:16 -03:00
Mike Seplowitz
4fa72a066a Improve control over ANSI output (#6858)
* Move global console_handler into function scope

Signed-off-by: Mike Seplowitz <mseplowitz@bloomberg.net>

* Improve control over ANSI output

- Disabled parallel logger ANSI output if not attached to a tty.
  The console handler and progress stream already checked whether the
  output stream is a tty, but ParallelStreamWriter did not.

- Added --ansi=(never|always|auto) option to allow clearer control over
  ANSI output. Since --no-ansi is the same as --ansi=never, --no-ansi is
  now deprecated.

Signed-off-by: Mike Seplowitz <mseplowitz@bloomberg.net>
2021-01-19 18:17:55 +01:00
Anca Iordache
b9249168bd Merge pull request #7926 from maaarghk/no_build_cache_from_duplicate_check
Remove duplicate values check for build.cache_from
2021-01-11 18:33:16 +01:00
Anca Iordache
e36ac32120 Merge pull request #7978 from thaJeztah/default_to_cli_build
Make COMPOSE_DOCKER_CLI_BUILD=1 the default
2021-01-11 18:29:42 +01:00
Guillaume Tardif
5be6bde76c Merge pull request #7989 from docker/add-metrics
Add metrics capturing
2021-01-06 09:38:52 +01:00
guillaume.tardif
c380604a9e Support windows npipe, set content type & corrrect URL /usage. Also fixed socket name for desktop mac
Signed-off-by: guillaume.tardif <guillaume.tardif@gmail.com>
2021-01-05 15:45:10 +01:00
Ulysses Souza
369eb3220a Add metrics
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-01-04 15:16:51 -03:00
Ulysses Souza
2e273c5029 Merge pull request #8005 from asterite3/up-only-attach-foreground-services
Only attach services we're going to read logs from in "up"
2021-01-04 13:44:12 +00:00
Anca Iordache
21e196f20a Merge pull request #8009 from ulyssessouza/fix-windows-popen
Avoid setting unsuported parameter for subprocess.Popen on Windows
2021-01-04 09:55:53 +01:00
Ulysses Souza
b9d86f4b51 Avoid setting unsuported parameter for subprocess.Popen on Windows
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-12-22 17:52:24 -03:00
Daniil Sigalov
1b5278f977 Only attach services we'll read logs from in up
When 'up' is run with explicit list of services, compose will
start them together with their dependencies. It will attach to all
started services, but won't read output from dependencies (their
logs are not printed by 'up') - so the receive buffer of
dependencies will fill and at some point will start blocking those
services. Fix that by only attaching to services given in the
list.
To do that, move logic of choosing which services to attach from
cli/main.py to utils.py and use it from project.py to decide if
service should be attached.

Fixes #6018

Signed-off-by: Daniil Sigalov <asterite@seclab.cs.msu.ru>
2020-12-20 15:58:58 +03:00
Sebastiaan van Stijn
affb0d504d Make COMPOSE_DOCKER_CLI_BUILD=1 the default
This changes compose to use "native" build through the CLI
by default. With this, docker-compose can take advantage of
BuildKit (which is now enabled by default on Docker Desktop
2.5 and up).

Users that want to use the python client for building can
opt-out of this feature by setting COMPOSE_DOCKER_CLI_BUILD=0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-12-08 12:26:41 +01:00
Anca Iordache
8034bc3bd6 Merge pull request #7977 from docker/bumps-virtenv-gitpython
Bump virtualenv from 20.0.30 to 20.2.2 and gitpython to 3.1.11
2020-12-07 19:59:16 +01:00
dependabot-preview[bot]
89fcfc5499 Bump virtualenv from 20.0.30 to 20.2.2
Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
(cherry picked from commit 8785279ffd)
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2020-12-07 15:57:24 -03:00
Anca Iordache
40a4ec1624 Merge pull request #7679 from docker/dependabot/pip/bcrypt-3.2.0
Bump bcrypt from 3.1.7 to 3.2.0
2020-12-07 19:18:30 +01:00
Anca Iordache
6c55ef6a5d Revert "Bump virtualenv from 20.0.30 to 20.2.1" (#7975)
This reverts commit 8785279ffd.

Signed-off-by: aiordache <anca.iordache@docker.com>
2020-12-04 17:32:14 +01:00
Anca Iordache
3f46dc1d76 Revert "Bump gitpython from 3.1.7 to 3.1.11" (#7974)
Signed-off-by: aiordache <anca.iordache@docker.com>
2020-12-04 17:22:31 +01:00
Anca Iordache
f2bc89a876 Merge pull request #7971 from aiordache/update_docker_setup
Bump docker-py in setup.py
2020-12-03 19:23:30 +01:00
aiordache
fee4756e33 Bump docker-py in setup.py
Signed-off-by: aiordache <anca.iordache@docker.com>
2020-12-03 19:00:39 +01:00
Anca Iordache
030b347673 Merge pull request #7965 from docker/fix-project-dir
Fix project_dir to take first file in account
2020-12-03 14:21:01 +01:00
dependabot-preview[bot]
4139d701f3 Bump bcrypt from 3.1.7 to 3.2.0
Bumps [bcrypt](https://github.com/pyca/bcrypt) from 3.1.7 to 3.2.0.
- [Release notes](https://github.com/pyca/bcrypt/releases)
- [Changelog](https://github.com/pyca/bcrypt/blob/master/release.py)
- [Commits](https://github.com/pyca/bcrypt/compare/3.1.7...3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-02 19:01:24 +00:00
Mark Gallagher
3ebfa4b089 Remove duplicate values check for build.cache_from
The `docker` command accepts duplicate values, so there is no benefit to
performing this check.

Fixes #7342.

Signed-off-by: Mark Gallagher <mark@fts.scot>
2020-11-13 01:56:37 +00:00
35 changed files with 522 additions and 132 deletions

View File

@@ -1,6 +1,96 @@
Change log
==========
1.29.0 (2021-04-06)
-------------------
[List of PRs / issues for this release](https://github.com/docker/compose/milestone/56?closed=1)
### Features
- Add profile filter to `docker-compose config`
- Add a `depends_on` condition to wait for successful service completion
### Miscellaneous
- Add image scan message on build
- Update warning message for `--no-ansi` to mention `--ansi never` as alternative
- Bump docker-py to 5.0.0
- Bump PyYAML to 5.4.1
- Bump python-dotenv to 0.17.0
1.28.6 (2021-03-23)
-------------------
[List of PRs / issues for this release](https://github.com/docker/compose/milestone/57?closed=1)
### Bugs
- Make `--env-file` relative to the current working directory and error out for invalid paths. Environment file paths set with `--env-file` are relative to the current working directory while the default `.env` file is located in the project directory which by default is the base directory of the Compose file.
- Fix missing service property `storage_opt` by updating the compose schema
- Fix build `extra_hosts` list format
- Remove extra error message on `exec`
### Miscellaneous
- Add `compose.yml` and `compose.yaml` to default filename list
1.28.5 (2021-02-25)
-------------------
[List of PRs / issues for this release](https://github.com/docker/compose/milestone/55?closed=1)
### Bugs
- Fix OpenSSL version mismatch error when shelling out to the ssh client (via bump to docker-py 4.4.4 which contains the fix)
- Add missing build flags to the native builder: `platform`, `isolation` and `extra_hosts`
- Remove info message on native build
- Avoid fetching logs when service logging driver is set to 'none'
1.28.4 (2021-02-18)
-------------------
[List of PRs / issues for this release](https://github.com/docker/compose/milestone/54?closed=1)
### Bugs
- Fix SSH port parsing by bumping docker-py to 4.4.3
### Miscellaneous
- Bump Python to 3.7.10
1.28.3 (2021-02-17)
-------------------
[List of PRs / issues for this release](https://github.com/docker/compose/milestone/53?closed=1)
### Bugs
- Fix SSH hostname parsing when it contains leading s/h, and remove the quiet option that was hiding the error (via docker-py bump to 4.4.2)
- Fix key error for '--no-log-prefix' option
- Fix incorrect CLI environment variable name for service profiles: `COMPOSE_PROFILES` instead of `COMPOSE_PROFILE`
- Fix fish completion
### Miscellaneous
- Bump cryptography to 3.3.2
- Remove log driver filter
1.28.2 (2021-01-26)
-------------------
@@ -81,6 +171,7 @@ Change log
- Updates of READMEs
1.27.4 (2020-09-24)
-------------------

View File

@@ -1,5 +1,5 @@
ARG DOCKER_VERSION=19.03
ARG PYTHON_VERSION=3.7.9
ARG PYTHON_VERSION=3.7.10
ARG BUILD_ALPINE_VERSION=3.12
ARG BUILD_CENTOS_VERSION=7

10
Jenkinsfile vendored
View File

@@ -23,7 +23,7 @@ pipeline {
parallel {
stage('alpine') {
agent {
label 'ubuntu && amd64 && !zfs'
label 'ubuntu-2004 && amd64 && !zfs && cgroup1'
}
steps {
buildImage('alpine')
@@ -31,7 +31,7 @@ pipeline {
}
stage('debian') {
agent {
label 'ubuntu && amd64 && !zfs'
label 'ubuntu-2004 && amd64 && !zfs && cgroup1'
}
steps {
buildImage('debian')
@@ -62,7 +62,7 @@ pipeline {
def buildImage(baseImage) {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def imageName = "dockerpinata/compose:${baseImage}-${scmvar.GIT_COMMIT}"
image = docker.image(imageName)
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
@@ -89,7 +89,7 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
node("ubuntu && amd64 && !zfs") {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def imageName = "dockerpinata/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') {
@@ -99,6 +99,8 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
--volume="\${DOCKER_CONFIG}/config.json:/root/.docker/config.json" \\
-e "DOCKER_TLS_CERTDIR=" \\
-e "TAG=${imageName}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersion}" \\

View File

@@ -23,7 +23,7 @@ pipeline {
parallel {
stage('alpine') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
buildImage('alpine')
@@ -31,7 +31,7 @@ pipeline {
}
stage('debian') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
buildImage('debian')
@@ -41,7 +41,7 @@ pipeline {
}
stage('Test') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
// TODO use declarative 1.5.0 `matrix` once available on CI
@@ -61,7 +61,7 @@ pipeline {
}
stage('Generate Changelog') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
checkout scm
@@ -98,7 +98,7 @@ pipeline {
}
stage('linux binary') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
checkout scm
@@ -134,7 +134,7 @@ pipeline {
}
stage('alpine image') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
buildRuntimeImage('alpine')
@@ -142,7 +142,7 @@ pipeline {
}
stage('debian image') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
buildRuntimeImage('debian')
@@ -157,7 +157,7 @@ pipeline {
parallel {
stage('Pushing images') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
steps {
pushRuntimeImage('alpine')
@@ -166,7 +166,7 @@ pipeline {
}
stage('Creating Github Release') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
environment {
GITHUB_TOKEN = credentials('github-release-token')
@@ -198,7 +198,7 @@ pipeline {
}
stage('Publishing Python packages') {
agent {
label 'linux && docker && ubuntu-2004 && cgroup1'
label 'linux && docker && ubuntu-2004 && amd64 && cgroup1'
}
environment {
PYPIRC = credentials('pypirc-docker-dsg-cibot')
@@ -222,7 +222,7 @@ pipeline {
def buildImage(baseImage) {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def imageName = "dockerpinata/compose:${baseImage}-${scmvar.GIT_COMMIT}"
image = docker.image(imageName)
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
@@ -247,9 +247,9 @@ def buildImage(baseImage) {
def runTests(dockerVersion, pythonVersion, baseImage) {
return {
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
node("linux && docker && ubuntu-2004 && cgroup1") {
node("linux && docker && ubuntu-2004 && amd64 && cgroup1") {
def scmvar = checkout(scm)
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
def imageName = "dockerpinata/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') {
@@ -259,6 +259,8 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
--privileged \\
--volume="\$(pwd)/.git:/code/.git" \\
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
--volume="\${DOCKER_CONFIG}/config.json:/root/.docker/config.json" \\
-e "DOCKER_TLS_CERTDIR=" \\
-e "TAG=${imageName}" \\
-e "STORAGE_DRIVER=${storageDriver}" \\
-e "DOCKER_VERSIONS=${dockerVersion}" \\

View File

@@ -1 +1 @@
__version__ = '1.28.2'
__version__ = '1.29.0'

View File

@@ -129,7 +129,7 @@ def get_profiles_from_options(options, environment):
if profile_option:
return profile_option
profiles = environment.get('COMPOSE_PROFILE')
profiles = environment.get('COMPOSE_PROFILES')
if profiles:
return profiles.split(',')

View File

@@ -158,10 +158,8 @@ class QueueItem(namedtuple('_QueueItem', 'item is_stop exc')):
def tail_container_logs(container, presenter, queue, log_args):
generator = get_log_generator(container)
try:
for item in generator(container, log_args):
for item in build_log_generator(container, log_args):
queue.put(QueueItem.new(presenter.present(container, item)))
except Exception as e:
queue.put(QueueItem.exception(e))
@@ -171,20 +169,6 @@ def tail_container_logs(container, presenter, queue, log_args):
queue.put(QueueItem.stop(container.name))
def get_log_generator(container):
if container.has_api_logs:
return build_log_generator
return build_no_log_generator
def build_no_log_generator(container, log_args):
"""Return a generator that prints a warning about logs and waits for
container to exit.
"""
yield "WARNING: no logs are available with the '{}' log driver\n".format(
container.log_driver)
def build_log_generator(container, log_args):
# if the container doesn't have a log_stream we need to attach to container
# before log printer starts running

View File

@@ -23,6 +23,7 @@ from ..config import resolve_build_args
from ..config.environment import Environment
from ..config.serialize import serialize_config
from ..config.types import VolumeSpec
from ..const import IS_LINUX_PLATFORM
from ..const import IS_WINDOWS_PLATFORM
from ..errors import StreamParseError
from ..metrics.decorator import metrics
@@ -78,6 +79,8 @@ def main(): # noqa: C901
try:
command_func = dispatch()
command_func()
if not IS_LINUX_PLATFORM and command == 'help':
print("\nDocker Compose is now in the Docker CLI, try `docker compose` help")
except (KeyboardInterrupt, signals.ShutdownException):
exit_with_metrics(command, "Aborting.", status=Status.FAILURE)
except (UserError, NoSuchService, ConfigurationError,
@@ -98,6 +101,8 @@ def main(): # noqa: C901
e.service.name), status=Status.FAILURE)
except NoSuchCommand as e:
commands = "\n".join(parse_doc_section("commands:", getdoc(e.supercommand)))
if not IS_LINUX_PLATFORM:
commands += "\n\nDocker Compose is now in the Docker CLI, try `docker compose`"
exit_with_metrics(e.command, "No such command: {}\n\n{}".format(e.command, commands))
except (errors.ConnectionError, StreamParseError):
exit_with_metrics(command, status=Status.FAILURE)
@@ -116,6 +121,10 @@ def main(): # noqa: C901
code = 0
if isinstance(e.code, int):
code = e.code
if not IS_LINUX_PLATFORM and not command:
msg += "\n\nDocker Compose is now in the Docker CLI, try `docker compose`"
exit_with_metrics(command, log_msg=msg, status=status,
exit_code=code)
@@ -128,7 +137,7 @@ def get_filtered_args(args):
def exit_with_metrics(command, log_msg=None, status=Status.SUCCESS, exit_code=1):
if log_msg:
if log_msg and command != 'exec':
if not exit_code:
log.info(log_msg)
else:
@@ -162,7 +171,8 @@ def dispatch():
if options.get("--no-ansi"):
if options.get("--ansi"):
raise UserError("--no-ansi and --ansi cannot be combined.")
log.warning('--no-ansi option is deprecated and will be removed in future versions.')
log.warning('--no-ansi option is deprecated and will be removed in future versions. '
'Use `--ansi never` instead.')
ansi_mode = AnsiMode.NEVER
setup_console_handler(console_handler,
@@ -381,6 +391,7 @@ class TopLevelCommand:
--no-interpolate Don't interpolate environment variables.
-q, --quiet Only validate the configuration, don't print
anything.
--profiles Print the profile names, one per line.
--services Print the service names, one per line.
--volumes Print the volume names, one per line.
--hash="*" Print the service config hash, one per line.
@@ -400,6 +411,15 @@ class TopLevelCommand:
if options['--quiet']:
return
if options['--profiles']:
profiles = set()
for service in compose_config.services:
if 'profiles' in service:
for profile in service['profiles']:
profiles.add(profile)
print('\n'.join(sorted(profiles)))
return
if options['--services']:
print('\n'.join(service['name'] for service in compose_config.services))
return
@@ -1121,7 +1141,10 @@ class TopLevelCommand:
detached = options.get('--detach')
no_start = options.get('--no-start')
attach_dependencies = options.get('--attach-dependencies')
keep_prefix = not options['--no-log-prefix']
keep_prefix = not options.get('--no-log-prefix')
if not IS_LINUX_PLATFORM:
print('Docker Compose is now in the Docker CLI, try `docker compose up`\n')
if detached and (cascade_stop or exit_value_from or attach_dependencies):
raise UserError(
@@ -1482,7 +1505,7 @@ def log_printer_from_project(
keep_prefix=True,
):
return LogPrinter(
containers,
[c for c in containers if c.log_driver not in (None, 'none')],
build_log_presenters(project.service_names, monochrome, keep_prefix),
event_stream or project.events(),
cascade_stop=cascade_stop,

View File

@@ -0,0 +1,85 @@
import json
import logging
import os
from distutils.util import strtobool
from docker.constants import IS_WINDOWS_PLATFORM
from docker.utils.config import find_config_file
SCAN_BINARY_NAME = "docker-scan" + (".exe" if IS_WINDOWS_PLATFORM else "")
log = logging.getLogger(__name__)
class ScanConfig:
def __init__(self, d):
self.optin = False
vars(self).update(d)
def display_scan_suggest_msg():
if environment_scan_avoid_suggest() or \
scan_available() is None or \
scan_already_invoked():
return
log.info("Use 'docker scan' to run Snyk tests against images to find vulnerabilities "
"and learn how to fix them")
def environment_scan_avoid_suggest():
return os.getenv('DOCKER_SCAN_SUGGEST', 'true').lower() == 'false'
def scan_already_invoked():
docker_folder = docker_config_folder()
if docker_folder is None:
return False
scan_config_file = os.path.join(docker_folder, 'scan', "config.json")
if not os.path.exists(scan_config_file):
return False
try:
data = ''
with open(scan_config_file) as f:
data = f.read()
scan_config = json.loads(data, object_hook=ScanConfig)
return scan_config.optin if isinstance(scan_config.optin, bool) else strtobool(scan_config.optin)
except Exception: # pylint:disable=broad-except
return True
def scan_available():
docker_folder = docker_config_folder()
if docker_folder:
home_scan_bin = os.path.join(docker_folder, 'cli-plugins', SCAN_BINARY_NAME)
if os.path.isfile(home_scan_bin) or os.path.islink(home_scan_bin):
return home_scan_bin
if IS_WINDOWS_PLATFORM:
program_data_scan_bin = os.path.join('C:\\', 'ProgramData', 'Docker', 'cli-plugins',
SCAN_BINARY_NAME)
if os.path.isfile(program_data_scan_bin) or os.path.islink(program_data_scan_bin):
return program_data_scan_bin
else:
lib_scan_bin = os.path.join('/usr', 'local', 'lib', 'docker', 'cli-plugins', SCAN_BINARY_NAME)
if os.path.isfile(lib_scan_bin) or os.path.islink(lib_scan_bin):
return lib_scan_bin
lib_exec_scan_bin = os.path.join('/usr', 'local', 'libexec', 'docker', 'cli-plugins',
SCAN_BINARY_NAME)
if os.path.isfile(lib_exec_scan_bin) or os.path.islink(lib_exec_scan_bin):
return lib_exec_scan_bin
lib_scan_bin = os.path.join('/usr', 'lib', 'docker', 'cli-plugins', SCAN_BINARY_NAME)
if os.path.isfile(lib_scan_bin) or os.path.islink(lib_scan_bin):
return lib_scan_bin
lib_exec_scan_bin = os.path.join('/usr', 'libexec', 'docker', 'cli-plugins', SCAN_BINARY_NAME)
if os.path.isfile(lib_exec_scan_bin) or os.path.islink(lib_exec_scan_bin):
return lib_exec_scan_bin
return None
def docker_config_folder():
docker_config_file = find_config_file()
return None if not docker_config_file \
else os.path.dirname(os.path.abspath(docker_config_file))

View File

@@ -188,7 +188,7 @@
"properties": {
"condition": {
"type": "string",
"enum": ["service_started", "service_healthy"]
"enum": ["service_started", "service_healthy", "service_completed_successfully"]
}
},
"required": ["condition"]
@@ -335,7 +335,6 @@
"read_only": {"type": "boolean"},
"restart": {"type": "string"},
"runtime": {
"deprecated": true,
"type": "string"
},
"scale": {
@@ -367,6 +366,7 @@
"stdin_open": {"type": "boolean"},
"stop_grace_period": {"type": "string", "format": "duration"},
"stop_signal": {"type": "string"},
"storage_opt": {"type": "object"},
"tmpfs": {"$ref": "#/definitions/string_or_list"},
"tty": {"type": "boolean"},
"ulimits": {

View File

@@ -10,7 +10,11 @@ from operator import attrgetter
from operator import itemgetter
import yaml
from cached_property import cached_property
try:
from functools import cached_property
except ImportError:
from cached_property import cached_property
from . import types
from ..const import COMPOSE_SPEC as VERSION
@@ -149,9 +153,14 @@ DOCKER_VALID_URL_PREFIXES = (
SUPPORTED_FILENAMES = [
'docker-compose.yml',
'docker-compose.yaml',
'compose.yml',
'compose.yaml',
]
DEFAULT_OVERRIDE_FILENAMES = ('docker-compose.override.yml', 'docker-compose.override.yaml')
DEFAULT_OVERRIDE_FILENAMES = ('docker-compose.override.yml',
'docker-compose.override.yaml',
'compose.override.yml',
'compose.override.yaml')
log = logging.getLogger(__name__)
@@ -304,7 +313,16 @@ def find(base_dir, filenames, environment, override_dir=None):
if filenames:
filenames = [os.path.join(base_dir, f) for f in filenames]
else:
# search for compose files in the base dir and its parents
filenames = get_default_config_files(base_dir)
if not filenames and not override_dir:
# none found in base_dir and no override_dir defined
raise ComposeFileNotFound(SUPPORTED_FILENAMES)
if not filenames:
# search for compose files in the project directory and its parents
filenames = get_default_config_files(override_dir)
if not filenames:
raise ComposeFileNotFound(SUPPORTED_FILENAMES)
log.debug("Using configuration files: {}".format(",".join(filenames)))
return ConfigDetails(
@@ -335,7 +353,7 @@ def get_default_config_files(base_dir):
(candidates, path) = find_candidates_in_parent_dirs(SUPPORTED_FILENAMES, base_dir)
if not candidates:
raise ComposeFileNotFound(SUPPORTED_FILENAMES)
return None
winner = candidates[0]
@@ -556,8 +574,7 @@ def process_config_section(config_file, config, section, environment, interpolat
config_file.version,
config,
section,
environment
)
environment)
else:
return config

View File

@@ -54,9 +54,10 @@ class Environment(dict):
if base_dir is None:
return result
if env_file:
env_file_path = os.path.join(base_dir, env_file)
else:
env_file_path = os.path.join(base_dir, '.env')
env_file_path = os.path.join(os.getcwd(), env_file)
return cls(env_vars_from_file(env_file_path))
env_file_path = os.path.join(base_dir, '.env')
try:
return cls(env_vars_from_file(env_file_path))
except EnvFileNotFound:

View File

@@ -5,6 +5,7 @@ from .version import ComposeVersion
DEFAULT_TIMEOUT = 10
HTTP_TIMEOUT = 60
IS_WINDOWS_PLATFORM = (sys.platform == "win32")
IS_LINUX_PLATFORM = (sys.platform == "linux")
LABEL_CONTAINER_NUMBER = 'com.docker.compose.container-number'
LABEL_ONE_OFF = 'com.docker.compose.oneoff'
LABEL_PROJECT = 'com.docker.compose.project'

View File

@@ -186,11 +186,6 @@ class Container:
def log_driver(self):
return self.get('HostConfig.LogConfig.Type')
@property
def has_api_logs(self):
log_type = self.log_driver
return not log_type or log_type in ('json-file', 'journald', 'local')
@property
def human_readable_health_status(self):
""" Generate UP status string with up time and health
@@ -204,11 +199,7 @@ class Container:
return status_string
def attach_log_stream(self):
"""A log stream can only be attached if the container uses a
json-file, journald or local log driver.
"""
if self.has_api_logs:
self.log_stream = self.attach(stdout=True, stderr=True, stream=True)
self.log_stream = self.attach(stdout=True, stderr=True, stream=True)
def get(self, key):
"""Return a value from the container or None if the value is not set.

View File

@@ -27,3 +27,8 @@ class NoHealthCheckConfigured(HealthCheckException):
service_name
)
)
class CompletedUnsuccessfully(Exception):
def __init__(self, container_id, exit_code):
self.msg = 'Container "{}" exited with code {}.'.format(container_id, exit_code)

View File

@@ -16,6 +16,7 @@ from compose.cli.colors import green
from compose.cli.colors import red
from compose.cli.signals import ShutdownException
from compose.const import PARALLEL_LIMIT
from compose.errors import CompletedUnsuccessfully
from compose.errors import HealthCheckFailed
from compose.errors import NoHealthCheckConfigured
from compose.errors import OperationFailedError
@@ -61,7 +62,8 @@ def parallel_execute_watch(events, writer, errors, results, msg, get_name, fail_
elif isinstance(exception, APIError):
errors[get_name(obj)] = exception.explanation
writer.write(msg, get_name(obj), 'error', red)
elif isinstance(exception, (OperationFailedError, HealthCheckFailed, NoHealthCheckConfigured)):
elif isinstance(exception, (OperationFailedError, HealthCheckFailed, NoHealthCheckConfigured,
CompletedUnsuccessfully)):
errors[get_name(obj)] = exception.msg
writer.write(msg, get_name(obj), 'error', red)
elif isinstance(exception, UpstreamError):
@@ -241,6 +243,12 @@ def feed_queue(objects, func, get_deps, results, state, limiter):
'not processing'.format(obj)
)
results.put((obj, None, e))
except CompletedUnsuccessfully as e:
log.debug(
'Service(s) upstream of {} did not completed successfully - '
'not processing'.format(obj)
)
results.put((obj, None, e))
if state.is_done():
results.put(STOP)

View File

@@ -13,6 +13,7 @@ from docker.utils import version_lt
from . import parallel
from .cli.errors import UserError
from .cli.scan_suggest import display_scan_suggest_msg
from .config import ConfigurationError
from .config.config import V1
from .config.sort_services import get_container_name_from_network_mode
@@ -490,8 +491,6 @@ class Project:
log.info('%s uses an image, skipping' % service.name)
if cli:
log.info("Building with native build. Learn about native build in Compose here: "
"https://docs.docker.com/go/compose-native-build/")
if parallel_build:
log.warning("Flag '--parallel' is ignored when building with "
"COMPOSE_DOCKER_CLI_BUILD=1")
@@ -520,6 +519,9 @@ class Project:
for service in services:
build_service(service)
if services:
display_scan_suggest_msg()
def create(
self,
service_names=None,
@@ -651,10 +653,6 @@ class Project:
override_options=None,
):
if cli:
log.info("Building with native build. Learn about native build in Compose here: "
"https://docs.docker.com/go/compose-native-build/")
self.initialize()
if not ignore_orphans:
self.find_orphan_containers(remove_orphans)
@@ -666,8 +664,15 @@ class Project:
service_names,
include_deps=start_deps)
must_build = False
for svc in services:
if svc.must_build(do_build=do_build):
must_build = True
svc.ensure_image_exists(do_build=do_build, silent=silent, cli=cli)
if must_build:
display_scan_suggest_msg()
plans = self._get_convergence_plans(
services,
strategy,

View File

@@ -45,6 +45,7 @@ from .const import LABEL_VERSION
from .const import NANOCPUS_SCALE
from .const import WINDOWS_LONGPATH_PREFIX
from .container import Container
from .errors import CompletedUnsuccessfully
from .errors import HealthCheckFailed
from .errors import NoHealthCheckConfigured
from .errors import OperationFailedError
@@ -112,6 +113,7 @@ HOST_CONFIG_KEYS = [
CONDITION_STARTED = 'service_started'
CONDITION_HEALTHY = 'service_healthy'
CONDITION_COMPLETED_SUCCESSFULLY = 'service_completed_successfully'
class BuildError(Exception):
@@ -366,6 +368,24 @@ class Service:
"rebuild this image you must use `docker-compose build` or "
"`docker-compose up --build`.".format(self.name))
def must_build(self, do_build=BuildAction.none):
if self.can_be_built() and do_build == BuildAction.force:
return True
try:
self.image()
return False
except NoSuchImageError:
pass
if not self.can_be_built():
return False
if do_build == BuildAction.skip:
return False
return True
def get_image_registry_data(self):
try:
return self.client.inspect_distribution(self.image_name)
@@ -753,6 +773,8 @@ class Service:
configs[svc] = lambda s: True
elif config['condition'] == CONDITION_HEALTHY:
configs[svc] = lambda s: s.is_healthy()
elif config['condition'] == CONDITION_COMPLETED_SUCCESSFULLY:
configs[svc] = lambda s: s.is_completed_successfully()
else:
# The config schema already prevents this, but it might be
# bypassed if Compose is called programmatically.
@@ -1304,6 +1326,21 @@ class Service:
raise HealthCheckFailed(ctnr.short_id)
return result
def is_completed_successfully(self):
""" Check that all containers for this service has completed successfully
Returns false if at least one container does not exited and
raises CompletedUnsuccessfully exception if at least one container
exited with non-zero exit code.
"""
result = True
for ctnr in self.containers(stopped=True):
ctnr.inspect()
if ctnr.get('State.Status') != 'exited':
result = False
elif ctnr.exit_code != 0:
raise CompletedUnsuccessfully(ctnr.short_id, ctnr.exit_code)
return result
def _parse_proxy_config(self):
client = self.client
if 'proxies' not in client._general_configs:
@@ -1855,7 +1892,7 @@ class _CLIBuilder:
Returns:
A generator for the build output.
"""
if dockerfile:
if dockerfile and os.path.isdir(path):
dockerfile = os.path.join(path, dockerfile)
iidfile = tempfile.mktemp()
@@ -1873,6 +1910,15 @@ class _CLIBuilder:
command_builder.add_arg("--tag", tag)
command_builder.add_arg("--target", target)
command_builder.add_arg("--iidfile", iidfile)
command_builder.add_arg("--platform", platform)
command_builder.add_arg("--isolation", isolation)
if extra_hosts:
if isinstance(extra_hosts, dict):
extra_hosts = ["{}:{}".format(host, ip) for host, ip in extra_hosts.items()]
for host in extra_hosts:
command_builder.add_arg("--add-host", "{}".format(host))
args = command_builder.build([path])
magic_word = "Successfully built "

View File

@@ -138,7 +138,7 @@ _docker_compose_config() {
;;
esac
COMPREPLY=( $( compgen -W "--hash --help --no-interpolate --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--hash --help --no-interpolate --profiles --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
}
@@ -172,6 +172,10 @@ _docker_compose_docker_compose() {
COMPREPLY=( $( compgen -W "debug info warning error critical" -- "$cur" ) )
return
;;
--profile)
COMPREPLY=( $( compgen -W "$(__docker_compose_q config --profiles)" -- "$cur" ) )
return
;;
--project-directory)
_filedir -d
return
@@ -618,10 +622,11 @@ _docker_compose() {
--tlskey
"
# These options are require special treatment when searching the command.
# These options require special treatment when searching the command.
local top_level_options_with_args="
--ansi
--log-level
--profile
"
COMPREPLY=()

View File

@@ -22,6 +22,6 @@ complete -c docker-compose -l tlskey -r -d 'Path to TLS key fi
complete -c docker-compose -l tlsverify -d 'Use TLS and verify the remote'
complete -c docker-compose -l skip-hostname-check -d "Don't check the daemon's hostname against the name specified in the client certificate (for example if your docker host is an IP address)"
complete -c docker-compose -l no-ansi -d 'Do not print ANSI control characters'
complete -c docker-compose -l ansi -a never always auto -d 'Control when to print ANSI control characters'
complete -c docker-compose -l ansi -a 'never always auto' -d 'Control when to print ANSI control characters'
complete -c docker-compose -s h -l help -d 'Print usage'
complete -c docker-compose -s v -l version -d 'Print version and exit'

View File

@@ -1,5 +1,5 @@
Click==7.1.2
coverage==5.2.1
coverage==5.5
ddt==1.4.1
flake8==3.8.3
gitpython==3.1.11
@@ -7,4 +7,3 @@ mock==3.0.5
pytest==6.0.1; python_version >= '3.5'
pytest==4.6.5; python_version < '3.5'
pytest-cov==2.10.1
PyYAML==5.3.1

View File

@@ -3,7 +3,7 @@ appdirs==1.4.4
attrs==20.3.0
bcrypt==3.2.0
cffi==1.14.4
cryptography==3.2.1
cryptography==3.3.2
distlib==0.3.1
entrypoints==0.3
filelock==3.0.12
@@ -11,7 +11,7 @@ gitdb2==4.0.2
mccabe==0.6.1
more-itertools==8.6.0; python_version >= '3.5'
more-itertools==5.0.0; python_version < '3.5'
packaging==20.4
packaging==20.9
pluggy==0.13.1
py==1.9.0
pycodestyle==2.6.0

View File

@@ -1,10 +1,10 @@
backports.shutil_get_terminal_size==1.0.0
cached-property==1.5.1
cached-property==1.5.1; python_version < '3.8'
certifi==2020.6.20
chardet==3.0.4
colorama==0.4.3; sys_platform == 'win32'
distro==1.5.0
docker==4.4.1
docker==5.0.0
docker-pycreds==0.4.0
dockerpty==0.4.1
docopt==0.6.2
@@ -13,9 +13,9 @@ ipaddress==1.0.23
jsonschema==3.2.0
paramiko==2.7.1
PySocks==1.7.1
python-dotenv==0.14.0
python-dotenv==0.17.0
pywin32==227; sys_platform == 'win32'
PyYAML==5.3.1
PyYAML==5.4.1
requests==2.24.0
texttable==1.6.2
urllib3==1.25.10; python_version == '3.3'

View File

@@ -15,7 +15,7 @@
set -e
VERSION="1.28.2"
VERSION="1.29.0"
IMAGE="docker/compose:$VERSION"

View File

@@ -38,17 +38,19 @@ for version in $DOCKER_VERSIONS; do
trap "on_exit" EXIT
repo="dockerswarm/dind"
docker run \
-d \
--name "$daemon_container" \
--privileged \
--volume="/var/lib/docker" \
"$repo:$version" \
-v $DOCKER_CONFIG/config.json:/root/.docker/config.json \
-e "DOCKER_TLS_CERTDIR=" \
"docker:$version-dind" \
dockerd -H tcp://0.0.0.0:2375 $DOCKER_DAEMON_ARGS \
2>&1 | tail -n 10
docker exec "$daemon_container" sh -c "apk add --no-cache git"
docker run \
--rm \
--tty \

View File

@@ -25,14 +25,13 @@ def find_version(*file_paths):
install_requires = [
'cached-property >= 1.2.0, < 2',
'docopt >= 0.6.1, < 1',
'PyYAML >= 3.10, < 6',
'requests >= 2.20.0, < 3',
'texttable >= 0.9.0, < 2',
'websocket-client >= 0.32.0, < 1',
'distro >= 1.5.0, < 2',
'docker[ssh] >= 4.4.0, < 5',
'docker[ssh] >= 5',
'dockerpty >= 0.4.1, < 1',
'jsonschema >= 2.5.1, < 4',
'python-dotenv >= 0.13.0, < 1',
@@ -50,6 +49,7 @@ if sys.version_info[:2] < (3, 4):
extras_require = {
':python_version < "3.5"': ['backports.ssl_match_hostname >= 3.5, < 4'],
':python_version < "3.8"': ['cached-property >= 1.2.0, < 2'],
':sys_platform == "win32"': ['colorama >= 0.4, < 1'],
'socks': ['PySocks >= 1.5.6, != 1.5.7, < 2'],
'tests': tests_require,

View File

@@ -237,6 +237,11 @@ class CLITestCase(DockerClientTestCase):
result = self.dispatch(['-H=tcp://doesnotexist:8000', 'ps'], returncode=1)
assert "Couldn't connect to Docker daemon" in result.stderr
def test_config_list_profiles(self):
self.base_dir = 'tests/fixtures/config-profiles'
result = self.dispatch(['config', '--profiles'])
assert set(result.stdout.rstrip().split('\n')) == {'debug', 'frontend', 'gui'}
def test_config_list_services(self):
self.base_dir = 'tests/fixtures/v2-full'
result = self.dispatch(['config', '--services'])

View File

@@ -0,0 +1,15 @@
version: '3.8'
services:
frontend:
image: frontend
profiles: ["frontend", "gui"]
phpmyadmin:
image: phpmyadmin
depends_on:
- db
profiles:
- debug
backend:
image: backend
db:
image: mysql

1
tests/fixtures/env-file-override/.env vendored Normal file
View File

@@ -0,0 +1 @@
WHEREAMI=default

View File

@@ -1,5 +1,6 @@
import tempfile
import pytest
from ddt import data
from ddt import ddt
@@ -8,6 +9,7 @@ from ..acceptance.cli_test import dispatch
from compose.cli.command import get_project
from compose.cli.command import project_from_options
from compose.config.environment import Environment
from compose.config.errors import EnvFileNotFound
from tests.integration.testcases import DockerClientTestCase
@@ -55,13 +57,36 @@ services:
class EnvironmentOverrideFileTest(DockerClientTestCase):
def test_env_file_override(self):
base_dir = 'tests/fixtures/env-file-override'
# '--env-file' are relative to the current working dir
env = Environment.from_env_file(base_dir, base_dir+'/.env.override')
dispatch(base_dir, ['--env-file', '.env.override', 'up'])
project = get_project(project_dir=base_dir,
config_path=['docker-compose.yml'],
environment=Environment.from_env_file(base_dir, '.env.override'),
environment=env,
override_dir=base_dir)
containers = project.containers(stopped=True)
assert len(containers) == 1
assert "WHEREAMI=override" in containers[0].get('Config.Env')
assert "DEFAULT_CONF_LOADED=true" in containers[0].get('Config.Env')
dispatch(base_dir, ['--env-file', '.env.override', 'down'], None)
def test_env_file_not_found_error(self):
base_dir = 'tests/fixtures/env-file-override'
with pytest.raises(EnvFileNotFound) as excinfo:
Environment.from_env_file(base_dir, '.env.override')
assert "Couldn't find env file" in excinfo.exconly()
def test_dot_env_file(self):
base_dir = 'tests/fixtures/env-file-override'
# '.env' is relative to the project_dir (base_dir)
env = Environment.from_env_file(base_dir, None)
dispatch(base_dir, ['up'])
project = get_project(project_dir=base_dir,
config_path=['docker-compose.yml'],
environment=env,
override_dir=base_dir)
containers = project.containers(stopped=True)
assert len(containers) == 1
assert "WHEREAMI=default" in containers[0].get('Config.Env')
dispatch(base_dir, ['down'], None)

View File

@@ -25,6 +25,7 @@ from compose.const import COMPOSE_SPEC as VERSION
from compose.const import LABEL_PROJECT
from compose.const import LABEL_SERVICE
from compose.container import Container
from compose.errors import CompletedUnsuccessfully
from compose.errors import HealthCheckFailed
from compose.errors import NoHealthCheckConfigured
from compose.project import Project
@@ -1899,6 +1900,110 @@ class ProjectTest(DockerClientTestCase):
with pytest.raises(NoHealthCheckConfigured):
svc1.is_healthy()
def test_project_up_completed_successfully_dependency(self):
config_dict = {
'version': '2.1',
'services': {
'svc1': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'true'
},
'svc2': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'top',
'depends_on': {
'svc1': {'condition': 'service_completed_successfully'},
}
}
}
}
config_data = load_config(config_dict)
project = Project.from_config(
name='composetest', config_data=config_data, client=self.client
)
project.up()
svc1 = project.get_service('svc1')
svc2 = project.get_service('svc2')
assert 'svc1' in svc2.get_dependency_names()
assert svc2.containers()[0].is_running
assert len(svc1.containers()) == 0
assert svc1.is_completed_successfully()
def test_project_up_completed_unsuccessfully_dependency(self):
config_dict = {
'version': '2.1',
'services': {
'svc1': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'false'
},
'svc2': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'top',
'depends_on': {
'svc1': {'condition': 'service_completed_successfully'},
}
}
}
}
config_data = load_config(config_dict)
project = Project.from_config(
name='composetest', config_data=config_data, client=self.client
)
with pytest.raises(ProjectError):
project.up()
containers = project.containers()
assert len(containers) == 0
svc1 = project.get_service('svc1')
svc2 = project.get_service('svc2')
assert 'svc1' in svc2.get_dependency_names()
with pytest.raises(CompletedUnsuccessfully):
svc1.is_completed_successfully()
def test_project_up_completed_differently_dependencies(self):
config_dict = {
'version': '2.1',
'services': {
'svc1': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'true'
},
'svc2': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'false'
},
'svc3': {
'image': BUSYBOX_IMAGE_WITH_TAG,
'command': 'top',
'depends_on': {
'svc1': {'condition': 'service_completed_successfully'},
'svc2': {'condition': 'service_completed_successfully'},
}
}
}
}
config_data = load_config(config_dict)
project = Project.from_config(
name='composetest', config_data=config_data, client=self.client
)
with pytest.raises(ProjectError):
project.up()
containers = project.containers()
assert len(containers) == 0
svc1 = project.get_service('svc1')
svc2 = project.get_service('svc2')
svc3 = project.get_service('svc3')
assert ['svc1', 'svc2'] == svc3.get_dependency_names()
assert svc1.is_completed_successfully()
with pytest.raises(CompletedUnsuccessfully):
svc2.is_completed_successfully()
def test_project_up_seccomp_profile(self):
seccomp_data = {
'defaultAction': 'SCMP_ACT_ALLOW',

View File

@@ -8,7 +8,6 @@ from docker.errors import APIError
from compose.cli.log_printer import build_log_generator
from compose.cli.log_printer import build_log_presenters
from compose.cli.log_printer import build_no_log_generator
from compose.cli.log_printer import consume_queue
from compose.cli.log_printer import QueueItem
from compose.cli.log_printer import wait_on_exit
@@ -75,14 +74,6 @@ def test_wait_on_exit_raises():
assert expected in wait_on_exit(mock_container)
def test_build_no_log_generator(mock_container):
mock_container.has_api_logs = False
mock_container.log_driver = 'none'
output, = build_no_log_generator(mock_container, None)
assert "WARNING: no logs are available with the 'none' log driver\n" in output
assert "exited with code" not in output
class TestBuildLogGenerator:
def test_no_log_stream(self, mock_container):

View File

@@ -2397,7 +2397,8 @@ web:
'image': 'busybox',
'depends_on': {
'app1': {'condition': 'service_started'},
'app2': {'condition': 'service_healthy'}
'app2': {'condition': 'service_healthy'},
'app3': {'condition': 'service_completed_successfully'}
}
}
override = {}
@@ -2409,11 +2410,12 @@ web:
'image': 'busybox',
'depends_on': {
'app1': {'condition': 'service_started'},
'app2': {'condition': 'service_healthy'}
'app2': {'condition': 'service_healthy'},
'app3': {'condition': 'service_completed_successfully'}
}
}
override = {
'depends_on': ['app3']
'depends_on': ['app4']
}
actual = config.merge_service_dicts(base, override, VERSION)
@@ -2422,7 +2424,8 @@ web:
'depends_on': {
'app1': {'condition': 'service_started'},
'app2': {'condition': 'service_healthy'},
'app3': {'condition': 'service_started'}
'app3': {'condition': 'service_completed_successfully'},
'app4': {'condition': 'service_started'},
}
}
@@ -3567,9 +3570,11 @@ class InterpolationTest(unittest.TestCase):
@mock.patch.dict(os.environ)
def test_config_file_with_options_environment_file(self):
project_dir = 'tests/fixtures/default-env-file'
# env-file is relative to current working dir
env = Environment.from_env_file(project_dir, project_dir + '/.env2')
service_dicts = config.load(
config.find(
project_dir, None, Environment.from_env_file(project_dir, '.env2')
project_dir, None, env
)
).services
@@ -5233,6 +5238,8 @@ class GetDefaultConfigFilesTestCase(unittest.TestCase):
files = [
'docker-compose.yml',
'docker-compose.yaml',
'compose.yml',
'compose.yaml',
]
def test_get_config_path_default_file_in_basedir(self):
@@ -5266,8 +5273,10 @@ def get_config_filename_for_files(filenames, subdir=None):
base_dir = tempfile.mkdtemp(dir=project_dir)
else:
base_dir = project_dir
filename, = config.get_default_config_files(base_dir)
return os.path.basename(filename)
filenames = config.get_default_config_files(base_dir)
if not filenames:
raise config.ComposeFileNotFound(config.SUPPORTED_FILENAMES)
return os.path.basename(filenames[0])
finally:
shutil.rmtree(project_dir)

View File

@@ -221,34 +221,6 @@ class ContainerTest(unittest.TestCase):
container = Container(None, self.container_dict, has_been_inspected=True)
assert container.short_id == self.container_id[:12]
def test_has_api_logs(self):
container_dict = {
'HostConfig': {
'LogConfig': {
'Type': 'json-file'
}
}
}
container = Container(None, container_dict, has_been_inspected=True)
assert container.has_api_logs is True
container_dict['HostConfig']['LogConfig']['Type'] = 'none'
container = Container(None, container_dict, has_been_inspected=True)
assert container.has_api_logs is False
container_dict['HostConfig']['LogConfig']['Type'] = 'syslog'
container = Container(None, container_dict, has_been_inspected=True)
assert container.has_api_logs is False
container_dict['HostConfig']['LogConfig']['Type'] = 'journald'
container = Container(None, container_dict, has_been_inspected=True)
assert container.has_api_logs is True
container_dict['HostConfig']['LogConfig']['Type'] = 'foobar'
container = Container(None, container_dict, has_been_inspected=True)
assert container.has_api_logs is False
class GetContainerNameTestCase(unittest.TestCase):

View File

@@ -50,7 +50,7 @@ directory = coverage-html
[flake8]
max-line-length = 105
# Set this high for now
max-complexity = 11
max-complexity = 12
exclude = compose/packages
[pytest]