mirror of
https://github.com/docker/compose.git
synced 2025-07-28 16:14:06 +02:00
Merge branch 'master' into 1.28.x
This commit is contained in:
commit
31b95cfc12
@ -1,7 +1,6 @@
|
|||||||
Change log
|
Change log
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
||||||
1.28.2 (2021-01-26)
|
1.28.2 (2021-01-26)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
@ -81,6 +80,10 @@ Change log
|
|||||||
|
|
||||||
- Updates of READMEs
|
- Updates of READMEs
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
|
||||||
|
>>>>>>> master
|
||||||
1.27.4 (2020-09-24)
|
1.27.4 (2020-09-24)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
6
Jenkinsfile
vendored
6
Jenkinsfile
vendored
@ -62,7 +62,7 @@ pipeline {
|
|||||||
|
|
||||||
def buildImage(baseImage) {
|
def buildImage(baseImage) {
|
||||||
def scmvar = checkout(scm)
|
def scmvar = checkout(scm)
|
||||||
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
|
def imageName = "dockerpinata/compose:${baseImage}-${scmvar.GIT_COMMIT}"
|
||||||
image = docker.image(imageName)
|
image = docker.image(imageName)
|
||||||
|
|
||||||
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
||||||
@ -89,7 +89,7 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
|
|||||||
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
|
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
|
||||||
node("ubuntu && amd64 && !zfs") {
|
node("ubuntu && amd64 && !zfs") {
|
||||||
def scmvar = checkout(scm)
|
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()
|
def storageDriver = sh(script: "docker info -f \'{{.Driver}}\'", returnStdout: true).trim()
|
||||||
echo "Using local system's storage driver: ${storageDriver}"
|
echo "Using local system's storage driver: ${storageDriver}"
|
||||||
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
||||||
@ -99,6 +99,8 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
|
|||||||
--privileged \\
|
--privileged \\
|
||||||
--volume="\$(pwd)/.git:/code/.git" \\
|
--volume="\$(pwd)/.git:/code/.git" \\
|
||||||
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
|
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
|
||||||
|
--volume="\${DOCKER_CONFIG}/config.json:/code/.docker/config.json" \\
|
||||||
|
-e "DOCKER_TLS_CERTDIR=" \\
|
||||||
-e "TAG=${imageName}" \\
|
-e "TAG=${imageName}" \\
|
||||||
-e "STORAGE_DRIVER=${storageDriver}" \\
|
-e "STORAGE_DRIVER=${storageDriver}" \\
|
||||||
-e "DOCKER_VERSIONS=${dockerVersion}" \\
|
-e "DOCKER_VERSIONS=${dockerVersion}" \\
|
||||||
|
@ -222,7 +222,7 @@ pipeline {
|
|||||||
|
|
||||||
def buildImage(baseImage) {
|
def buildImage(baseImage) {
|
||||||
def scmvar = checkout(scm)
|
def scmvar = checkout(scm)
|
||||||
def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
|
def imageName = "dockerpinata/compose:${baseImage}-${scmvar.GIT_COMMIT}"
|
||||||
image = docker.image(imageName)
|
image = docker.image(imageName)
|
||||||
|
|
||||||
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
||||||
@ -249,7 +249,7 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
|
|||||||
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
|
stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
|
||||||
node("linux && docker && ubuntu-2004 && cgroup1") {
|
node("linux && docker && ubuntu-2004 && cgroup1") {
|
||||||
def scmvar = checkout(scm)
|
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()
|
def storageDriver = sh(script: "docker info -f \'{{.Driver}}\'", returnStdout: true).trim()
|
||||||
echo "Using local system's storage driver: ${storageDriver}"
|
echo "Using local system's storage driver: ${storageDriver}"
|
||||||
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
|
||||||
@ -259,6 +259,8 @@ def runTests(dockerVersion, pythonVersion, baseImage) {
|
|||||||
--privileged \\
|
--privileged \\
|
||||||
--volume="\$(pwd)/.git:/code/.git" \\
|
--volume="\$(pwd)/.git:/code/.git" \\
|
||||||
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
|
--volume="/var/run/docker.sock:/var/run/docker.sock" \\
|
||||||
|
--volume="\${DOCKER_CONFIG}/config.json:/code/.docker/config.json" \\
|
||||||
|
-e "DOCKER_TLS_CERTDIR=" \\
|
||||||
-e "TAG=${imageName}" \\
|
-e "TAG=${imageName}" \\
|
||||||
-e "STORAGE_DRIVER=${storageDriver}" \\
|
-e "STORAGE_DRIVER=${storageDriver}" \\
|
||||||
-e "DOCKER_VERSIONS=${dockerVersion}" \\
|
-e "DOCKER_VERSIONS=${dockerVersion}" \\
|
||||||
|
@ -129,7 +129,7 @@ def get_profiles_from_options(options, environment):
|
|||||||
if profile_option:
|
if profile_option:
|
||||||
return profile_option
|
return profile_option
|
||||||
|
|
||||||
profiles = environment.get('COMPOSE_PROFILE')
|
profiles = environment.get('COMPOSE_PROFILES')
|
||||||
if profiles:
|
if profiles:
|
||||||
return profiles.split(',')
|
return profiles.split(',')
|
||||||
|
|
||||||
|
@ -158,10 +158,8 @@ class QueueItem(namedtuple('_QueueItem', 'item is_stop exc')):
|
|||||||
|
|
||||||
|
|
||||||
def tail_container_logs(container, presenter, queue, log_args):
|
def tail_container_logs(container, presenter, queue, log_args):
|
||||||
generator = get_log_generator(container)
|
|
||||||
|
|
||||||
try:
|
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)))
|
queue.put(QueueItem.new(presenter.present(container, item)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
queue.put(QueueItem.exception(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))
|
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):
|
def build_log_generator(container, log_args):
|
||||||
# if the container doesn't have a log_stream we need to attach to container
|
# if the container doesn't have a log_stream we need to attach to container
|
||||||
# before log printer starts running
|
# before log printer starts running
|
||||||
|
@ -1121,7 +1121,7 @@ class TopLevelCommand:
|
|||||||
detached = options.get('--detach')
|
detached = options.get('--detach')
|
||||||
no_start = options.get('--no-start')
|
no_start = options.get('--no-start')
|
||||||
attach_dependencies = options.get('--attach-dependencies')
|
attach_dependencies = options.get('--attach-dependencies')
|
||||||
keep_prefix = not options['--no-log-prefix']
|
keep_prefix = not options.get('--no-log-prefix')
|
||||||
|
|
||||||
if detached and (cascade_stop or exit_value_from or attach_dependencies):
|
if detached and (cascade_stop or exit_value_from or attach_dependencies):
|
||||||
raise UserError(
|
raise UserError(
|
||||||
|
@ -186,11 +186,6 @@ class Container:
|
|||||||
def log_driver(self):
|
def log_driver(self):
|
||||||
return self.get('HostConfig.LogConfig.Type')
|
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
|
@property
|
||||||
def human_readable_health_status(self):
|
def human_readable_health_status(self):
|
||||||
""" Generate UP status string with up time and health
|
""" Generate UP status string with up time and health
|
||||||
@ -204,11 +199,7 @@ class Container:
|
|||||||
return status_string
|
return status_string
|
||||||
|
|
||||||
def attach_log_stream(self):
|
def attach_log_stream(self):
|
||||||
"""A log stream can only be attached if the container uses a
|
self.log_stream = self.attach(stdout=True, stderr=True, stream=True)
|
||||||
json-file, journald or local log driver.
|
|
||||||
"""
|
|
||||||
if self.has_api_logs:
|
|
||||||
self.log_stream = self.attach(stdout=True, stderr=True, stream=True)
|
|
||||||
|
|
||||||
def get(self, key):
|
def get(self, key):
|
||||||
"""Return a value from the container or None if the value is not set.
|
"""Return a value from the container or None if the value is not set.
|
||||||
|
@ -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 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 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 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 h -l help -d 'Print usage'
|
||||||
complete -c docker-compose -s v -l version -d 'Print version and exit'
|
complete -c docker-compose -s v -l version -d 'Print version and exit'
|
||||||
|
@ -3,7 +3,7 @@ appdirs==1.4.4
|
|||||||
attrs==20.3.0
|
attrs==20.3.0
|
||||||
bcrypt==3.2.0
|
bcrypt==3.2.0
|
||||||
cffi==1.14.4
|
cffi==1.14.4
|
||||||
cryptography==3.2.1
|
cryptography==3.3.2
|
||||||
distlib==0.3.1
|
distlib==0.3.1
|
||||||
entrypoints==0.3
|
entrypoints==0.3
|
||||||
filelock==3.0.12
|
filelock==3.0.12
|
||||||
|
@ -4,7 +4,7 @@ certifi==2020.6.20
|
|||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
colorama==0.4.3; sys_platform == 'win32'
|
colorama==0.4.3; sys_platform == 'win32'
|
||||||
distro==1.5.0
|
distro==1.5.0
|
||||||
docker==4.4.1
|
docker==4.4.2
|
||||||
docker-pycreds==0.4.0
|
docker-pycreds==0.4.0
|
||||||
dockerpty==0.4.1
|
dockerpty==0.4.1
|
||||||
docopt==0.6.2
|
docopt==0.6.2
|
||||||
|
@ -38,17 +38,19 @@ for version in $DOCKER_VERSIONS; do
|
|||||||
|
|
||||||
trap "on_exit" EXIT
|
trap "on_exit" EXIT
|
||||||
|
|
||||||
repo="dockerswarm/dind"
|
|
||||||
|
|
||||||
docker run \
|
docker run \
|
||||||
-d \
|
-d \
|
||||||
--name "$daemon_container" \
|
--name "$daemon_container" \
|
||||||
--privileged \
|
--privileged \
|
||||||
--volume="/var/lib/docker" \
|
--volume="/var/lib/docker" \
|
||||||
"$repo:$version" \
|
-v $DOCKER_CONFIG/config.json:/code/.docker/config.json \
|
||||||
|
-e "DOCKER_TLS_CERTDIR=" \
|
||||||
|
"docker:$version-dind" \
|
||||||
dockerd -H tcp://0.0.0.0:2375 $DOCKER_DAEMON_ARGS \
|
dockerd -H tcp://0.0.0.0:2375 $DOCKER_DAEMON_ARGS \
|
||||||
2>&1 | tail -n 10
|
2>&1 | tail -n 10
|
||||||
|
|
||||||
|
docker exec "$daemon_container" sh -c "apk add --no-cache git"
|
||||||
|
|
||||||
docker run \
|
docker run \
|
||||||
--rm \
|
--rm \
|
||||||
--tty \
|
--tty \
|
||||||
|
@ -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_generator
|
||||||
from compose.cli.log_printer import build_log_presenters
|
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 consume_queue
|
||||||
from compose.cli.log_printer import QueueItem
|
from compose.cli.log_printer import QueueItem
|
||||||
from compose.cli.log_printer import wait_on_exit
|
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)
|
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:
|
class TestBuildLogGenerator:
|
||||||
|
|
||||||
def test_no_log_stream(self, mock_container):
|
def test_no_log_stream(self, mock_container):
|
||||||
|
@ -221,34 +221,6 @@ class ContainerTest(unittest.TestCase):
|
|||||||
container = Container(None, self.container_dict, has_been_inspected=True)
|
container = Container(None, self.container_dict, has_been_inspected=True)
|
||||||
assert container.short_id == self.container_id[:12]
|
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):
|
class GetContainerNameTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user