From 18338606143971b5ba64250cb0eca49d1a516c1d Mon Sep 17 00:00:00 2001 From: Gustavo Pantuza Coelho Pinto Date: Tue, 24 Oct 2017 19:24:06 -0200 Subject: [PATCH 1/3] CLI: Add --detach option for up, run and exec commands This contribution allows the usage of --detach option when running: docker-compose run --detach docker-compose exec --detach docker-compose up --detach The behavior is the same as the -d option. Signed-off-by: Gustavo Pantuza Coelho Pinto --- compose/cli/main.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compose/cli/main.py b/compose/cli/main.py index edc07d426..7b6ca98c4 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -424,7 +424,7 @@ class TopLevelCommand(object): Usage: exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...] Options: - -d Detached mode: Run command in the background. + -d, --detach Detached mode: Run command in the background. --privileged Give extended privileges to the process. -u, --user USER Run the command as this user. -T Disable pseudo-tty allocation. By default `docker-compose exec` @@ -438,7 +438,7 @@ class TopLevelCommand(object): use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') index = int(options.get('--index')) service = self.project.get_service(options['SERVICE']) - detach = options['-d'] + detach = options.get('-d') or options.get('--detach') if options['--env'] and docker.utils.version_lt(self.project.client.api_version, '1.25'): raise UserError("Setting environment for exec is not supported in API < 1.25'") @@ -762,7 +762,7 @@ class TopLevelCommand(object): SERVICE [COMMAND] [ARGS...] Options: - -d Detached mode: Run container in the background, print + -d --detach Detached mode: Run container in the background, print new container name. --name NAME Assign a name to the container --entrypoint CMD Override the entrypoint of the image. @@ -780,7 +780,7 @@ class TopLevelCommand(object): -w, --workdir="" Working directory inside the container """ service = self.project.get_service(options['SERVICE']) - detach = options['-d'] + detach = options.get('-d') or options.get('--detach') if options['--publish'] and options['--service-ports']: raise UserError( @@ -928,7 +928,7 @@ class TopLevelCommand(object): Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...] Options: - -d Detached mode: Run containers in the background, + -d, --detach Detached mode: Run containers in the background, print new container names. Incompatible with --abort-on-container-exit. --no-color Produce monochrome output. @@ -963,7 +963,7 @@ class TopLevelCommand(object): service_names = options['SERVICE'] timeout = timeout_from_opts(options) remove_orphans = options['--remove-orphans'] - detached = options.get('-d') + detached = options.get('-d') or options.get('--detach') no_start = options.get('--no-start') if detached and (cascade_stop or exit_value_from): @@ -975,7 +975,7 @@ class TopLevelCommand(object): if ignore_orphans and remove_orphans: raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.") - opts = ['-d', '--abort-on-container-exit', '--exit-code-from'] + opts = ['--detach', '--abort-on-container-exit', '--exit-code-from'] 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)) @@ -1245,7 +1245,7 @@ def run_one_off_container(container_options, project, service, options, project_ one_off=True, **container_options) - if options['-d']: + if options.get('-d') or options.get('--detach'): service.start_container(container) print(container.name) return From c6fe564ed579d8150efa2ec5613734de09d8dc45 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Wed, 21 Feb 2018 16:42:49 -0800 Subject: [PATCH 2/3] Add --detach tests Signed-off-by: Joffrey F --- compose/cli/main.py | 12 ++++++------ tests/acceptance/cli_test.py | 22 ++++++++++++++++++++++ tests/unit/cli_test.py | 8 ++++---- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/compose/cli/main.py b/compose/cli/main.py index 7b6ca98c4..460786489 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -438,7 +438,7 @@ class TopLevelCommand(object): use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') index = int(options.get('--index')) service = self.project.get_service(options['SERVICE']) - detach = options.get('-d') or options.get('--detach') + detach = options.get('--detach') if options['--env'] and docker.utils.version_lt(self.project.client.api_version, '1.25'): raise UserError("Setting environment for exec is not supported in API < 1.25'") @@ -762,7 +762,7 @@ class TopLevelCommand(object): SERVICE [COMMAND] [ARGS...] Options: - -d --detach Detached mode: Run container in the background, print + -d, --detach Detached mode: Run container in the background, print new container name. --name NAME Assign a name to the container --entrypoint CMD Override the entrypoint of the image. @@ -780,7 +780,7 @@ class TopLevelCommand(object): -w, --workdir="" Working directory inside the container """ service = self.project.get_service(options['SERVICE']) - detach = options.get('-d') or options.get('--detach') + detach = options.get('--detach') if options['--publish'] and options['--service-ports']: raise UserError( @@ -963,7 +963,7 @@ class TopLevelCommand(object): service_names = options['SERVICE'] timeout = timeout_from_opts(options) remove_orphans = options['--remove-orphans'] - detached = options.get('-d') or options.get('--detach') + detached = options.get('--detach') no_start = options.get('--no-start') if detached and (cascade_stop or exit_value_from): @@ -1245,7 +1245,7 @@ def run_one_off_container(container_options, project, service, options, project_ one_off=True, **container_options) - if options.get('-d') or options.get('--detach'): + if options.get('--detach'): service.start_container(container) print(container.name) return @@ -1372,7 +1372,7 @@ def parse_scale_args(options): def build_exec_command(options, container_id, command): args = ["exec"] - if options["-d"]: + if options["--detach"]: args += ["--detach"] else: args += ["--interactive"] diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 134485c40..63122e743 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -884,6 +884,19 @@ class CLITestCase(DockerClientTestCase): assert not container.get('Config.AttachStdout') assert not container.get('Config.AttachStdin') + def test_up_detached_long_form(self): + self.dispatch(['up', '--detach']) + service = self.project.get_service('simple') + another = self.project.get_service('another') + assert len(service.containers()) == 1 + assert len(another.containers()) == 1 + + # Ensure containers don't have stdin and stdout connected in -d mode + container, = service.containers() + assert not container.get('Config.AttachStderr') + assert not container.get('Config.AttachStdout') + assert not container.get('Config.AttachStdin') + def test_up_attached(self): self.base_dir = 'tests/fixtures/echo-services' result = self.dispatch(['up', '--no-color']) @@ -1463,6 +1476,15 @@ class CLITestCase(DockerClientTestCase): assert stderr == "" assert stdout == "/\n" + def test_exec_detach_long_form(self): + self.base_dir = 'tests/fixtures/links-composefile' + self.dispatch(['up', '--detach', 'console']) + assert len(self.project.containers()) == 1 + + stdout, stderr = self.dispatch(['exec', '-T', 'console', 'ls', '-1d', '/']) + assert stderr == "" + assert stdout == "/\n" + def test_exec_custom_user(self): self.base_dir = 'tests/fixtures/links-composefile' self.dispatch(['up', '-d', 'console']) diff --git a/tests/unit/cli_test.py b/tests/unit/cli_test.py index d078614e6..6399bef89 100644 --- a/tests/unit/cli_test.py +++ b/tests/unit/cli_test.py @@ -119,7 +119,7 @@ class CLITestCase(unittest.TestCase): '--label': [], '--user': None, '--no-deps': None, - '-d': False, + '--detach': False, '-T': None, '--entrypoint': None, '--service-ports': None, @@ -156,7 +156,7 @@ class CLITestCase(unittest.TestCase): '--label': [], '--user': None, '--no-deps': None, - '-d': True, + '--detach': True, '-T': None, '--entrypoint': None, '--service-ports': None, @@ -177,7 +177,7 @@ class CLITestCase(unittest.TestCase): '--label': [], '--user': None, '--no-deps': None, - '-d': True, + '--detach': True, '-T': None, '--entrypoint': None, '--service-ports': None, @@ -208,7 +208,7 @@ class CLITestCase(unittest.TestCase): '--label': [], '--user': None, '--no-deps': None, - '-d': True, + '--detach': True, '-T': None, '--entrypoint': None, '--service-ports': True, From c16820eca093f2bbf573c31f7390220565aa5937 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Wed, 21 Feb 2018 16:45:29 -0800 Subject: [PATCH 3/3] Update bash completion Signed-off-by: Joffrey F --- contrib/completion/bash/docker-compose | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/completion/bash/docker-compose b/contrib/completion/bash/docker-compose index fc51f604e..29853b089 100644 --- a/contrib/completion/bash/docker-compose +++ b/contrib/completion/bash/docker-compose @@ -245,7 +245,7 @@ _docker_compose_exec() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "-d --help --index --privileged -T --user -u" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "-d --detach --help --index --privileged -T --user -u" -- "$cur" ) ) ;; *) __docker_compose_services_running @@ -444,7 +444,7 @@ _docker_compose_run() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "-d --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --user -u --volume -v --workdir -w" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "-d --detach --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --user -u --volume -v --workdir -w" -- "$cur" ) ) ;; *) __docker_compose_services_all @@ -552,7 +552,7 @@ _docker_compose_up() { case "$cur" in -*) - COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --build -d --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 --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_services_all