mirror of https://github.com/docker/compose.git
Merge pull request #6950 from benthorner/master
Add "--attach-dependencies" to command "up" for attaching to dependencies
This commit is contained in:
commit
f0e5926ea7
|
@ -1012,6 +1012,7 @@ class TopLevelCommand(object):
|
|||
--build Build images before starting containers.
|
||||
--abort-on-container-exit Stops all containers if any container was
|
||||
stopped. Incompatible with -d.
|
||||
--attach-dependencies Attach to dependent containers
|
||||
-t, --timeout TIMEOUT Use this timeout in seconds for container
|
||||
shutdown when attached or when containers are
|
||||
already running. (default: 10)
|
||||
|
@ -1033,16 +1034,18 @@ class TopLevelCommand(object):
|
|||
remove_orphans = options['--remove-orphans']
|
||||
detached = options.get('--detach')
|
||||
no_start = options.get('--no-start')
|
||||
attach_dependencies = options.get('--attach-dependencies')
|
||||
|
||||
if detached and (cascade_stop or exit_value_from):
|
||||
raise UserError("--abort-on-container-exit and -d cannot be combined.")
|
||||
if detached and (cascade_stop or exit_value_from or attach_dependencies):
|
||||
raise UserError(
|
||||
"-d cannot be combined with --abort-on-container-exit or --attach-dependencies.")
|
||||
|
||||
ignore_orphans = self.toplevel_environment.get_boolean('COMPOSE_IGNORE_ORPHANS')
|
||||
|
||||
if ignore_orphans and remove_orphans:
|
||||
raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.")
|
||||
|
||||
opts = ['--detach', '--abort-on-container-exit', '--exit-code-from']
|
||||
opts = ['--detach', '--abort-on-container-exit', '--exit-code-from', '--attach-dependencies']
|
||||
for excluded in [x for x in opts if options.get(x) and no_start]:
|
||||
raise UserError('--no-start and {} cannot be combined.'.format(excluded))
|
||||
|
||||
|
@ -1087,7 +1090,10 @@ class TopLevelCommand(object):
|
|||
if detached or no_start:
|
||||
return
|
||||
|
||||
attached_containers = filter_containers_to_service_names(to_attach, service_names)
|
||||
attached_containers = filter_attached_containers(
|
||||
to_attach,
|
||||
service_names,
|
||||
attach_dependencies)
|
||||
|
||||
log_printer = log_printer_from_project(
|
||||
self.project,
|
||||
|
@ -1392,8 +1398,8 @@ def log_printer_from_project(
|
|||
log_args=log_args)
|
||||
|
||||
|
||||
def filter_containers_to_service_names(containers, service_names):
|
||||
if not service_names:
|
||||
def filter_attached_containers(containers, service_names, attach_dependencies=False):
|
||||
if attach_dependencies or not service_names:
|
||||
return containers
|
||||
|
||||
return [
|
||||
|
|
|
@ -545,7 +545,7 @@ _docker_compose_up() {
|
|||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --build -d --detach --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --no-start --renew-anon-volumes -V --remove-orphans --scale --timeout -t" -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --attach-dependencies --build -d --detach --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --no-start --renew-anon-volumes -V --remove-orphans --scale --timeout -t" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
__docker_compose_complete_services
|
||||
|
|
|
@ -284,7 +284,7 @@ __docker-compose_subcommand() {
|
|||
(up)
|
||||
_arguments \
|
||||
$opts_help \
|
||||
'(--abort-on-container-exit)-d[Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit.]' \
|
||||
'(--abort-on-container-exit)-d[Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit and --attach-dependencies.]' \
|
||||
$opts_no_color \
|
||||
$opts_no_deps \
|
||||
$opts_force_recreate \
|
||||
|
@ -292,6 +292,7 @@ __docker-compose_subcommand() {
|
|||
$opts_no_build \
|
||||
"(--no-build)--build[Build images before starting containers.]" \
|
||||
"(-d)--abort-on-container-exit[Stops all containers if any container was stopped. Incompatible with -d.]" \
|
||||
"(-d)--attach-dependencies[Attach to dependent containers. Incompatible with -d.]" \
|
||||
'(-t --timeout)'{-t,--timeout}"[Use this timeout in seconds for container shutdown when attached or when containers are already running. (default: 10)]:seconds: " \
|
||||
'--scale[SERVICE=NUM Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.]:service scale SERVICE=NUM: ' \
|
||||
'--exit-code-from=[Return the exit code of the selected service container. Implies --abort-on-container-exit]:service:__docker-compose_services' \
|
||||
|
|
|
@ -1571,6 +1571,26 @@ services:
|
|||
assert len(db.containers()) == 0
|
||||
assert len(console.containers()) == 0
|
||||
|
||||
def test_up_with_attach_dependencies(self):
|
||||
self.base_dir = 'tests/fixtures/echo-services-dependencies'
|
||||
result = self.dispatch(['up', '--attach-dependencies', '--no-color', 'simple'], None)
|
||||
simple_name = self.project.get_service('simple').containers(stopped=True)[0].name_without_project
|
||||
another_name = self.project.get_service('another').containers(
|
||||
stopped=True
|
||||
)[0].name_without_project
|
||||
|
||||
assert '{} | simple'.format(simple_name) in result.stdout
|
||||
assert '{} | another'.format(another_name) in result.stdout
|
||||
|
||||
def test_up_handles_aborted_dependencies(self):
|
||||
self.base_dir = 'tests/fixtures/abort-on-container-exit-dependencies'
|
||||
proc = start_process(
|
||||
self.base_dir,
|
||||
['up', 'simple', '--attach-dependencies', '--abort-on-container-exit'])
|
||||
wait_on_condition(ContainerCountCondition(self.project, 0))
|
||||
proc.wait()
|
||||
assert proc.returncode == 1
|
||||
|
||||
def test_up_with_force_recreate(self):
|
||||
self.dispatch(['up', '-d'], None)
|
||||
service = self.project.get_service('simple')
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
version: "2.0"
|
||||
services:
|
||||
simple:
|
||||
image: busybox:1.31.0-uclibc
|
||||
command: top
|
||||
depends_on:
|
||||
- another
|
||||
another:
|
||||
image: busybox:1.31.0-uclibc
|
||||
command: ls /thecakeisalie
|
|
@ -0,0 +1,10 @@
|
|||
version: "2.0"
|
||||
services:
|
||||
simple:
|
||||
image: busybox:1.31.0-uclibc
|
||||
command: echo simple
|
||||
depends_on:
|
||||
- another
|
||||
another:
|
||||
image: busybox:1.31.0-uclibc
|
||||
command: echo another
|
|
@ -12,7 +12,7 @@ from compose.cli.formatter import ConsoleWarningFormatter
|
|||
from compose.cli.main import build_one_off_container_options
|
||||
from compose.cli.main import call_docker
|
||||
from compose.cli.main import convergence_strategy_from_opts
|
||||
from compose.cli.main import filter_containers_to_service_names
|
||||
from compose.cli.main import filter_attached_containers
|
||||
from compose.cli.main import get_docker_start_call
|
||||
from compose.cli.main import setup_console_handler
|
||||
from compose.cli.main import warn_for_swarm_mode
|
||||
|
@ -37,7 +37,7 @@ def logging_handler():
|
|||
|
||||
class TestCLIMainTestCase(object):
|
||||
|
||||
def test_filter_containers_to_service_names(self):
|
||||
def test_filter_attached_containers(self):
|
||||
containers = [
|
||||
mock_container('web', 1),
|
||||
mock_container('web', 2),
|
||||
|
@ -46,17 +46,29 @@ class TestCLIMainTestCase(object):
|
|||
mock_container('another', 1),
|
||||
]
|
||||
service_names = ['web', 'db']
|
||||
actual = filter_containers_to_service_names(containers, service_names)
|
||||
actual = filter_attached_containers(containers, service_names)
|
||||
assert actual == containers[:3]
|
||||
|
||||
def test_filter_containers_to_service_names_all(self):
|
||||
def test_filter_attached_containers_with_dependencies(self):
|
||||
containers = [
|
||||
mock_container('web', 1),
|
||||
mock_container('web', 2),
|
||||
mock_container('db', 1),
|
||||
mock_container('other', 1),
|
||||
mock_container('another', 1),
|
||||
]
|
||||
service_names = ['web', 'db']
|
||||
actual = filter_attached_containers(containers, service_names, attach_dependencies=True)
|
||||
assert actual == containers
|
||||
|
||||
def test_filter_attached_containers_all(self):
|
||||
containers = [
|
||||
mock_container('web', 1),
|
||||
mock_container('db', 1),
|
||||
mock_container('other', 1),
|
||||
]
|
||||
service_names = []
|
||||
actual = filter_containers_to_service_names(containers, service_names)
|
||||
actual = filter_attached_containers(containers, service_names)
|
||||
assert actual == containers
|
||||
|
||||
def test_warning_in_swarm_mode(self):
|
||||
|
|
Loading…
Reference in New Issue