docker-compose exec doesn't have -e option (fixes #4551)

Signed-off-by: Guillermo Arribas <garribas@gmail.com>
This commit is contained in:
Guillermo Arribas 2017-10-19 22:07:30 -03:00 committed by Joffrey F
parent 8c0b03a2f5
commit b30cb77a7b
3 changed files with 74 additions and 21 deletions

View File

@ -14,6 +14,8 @@ from distutils.spawn import find_executable
from inspect import getdoc
from operator import attrgetter
import docker
from . import errors
from . import signals
from .. import __version__
@ -402,7 +404,7 @@ class TopLevelCommand(object):
"""
Execute a command in a running container
Usage: exec [options] SERVICE COMMAND [ARGS...]
Usage: exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...]
Options:
-d Detached mode: Run command in the background.
@ -412,11 +414,16 @@ class TopLevelCommand(object):
allocates a TTY.
--index=index index of the container if there are multiple
instances of a service [default: 1]
-e, --env KEY=VAL Set environment variables (can be used multiple times,
not supported in API < 1.25)
"""
index = int(options.get('--index'))
service = self.project.get_service(options['SERVICE'])
detach = options['-d']
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'")
try:
container = service.get_container(number=index)
except ValueError as e:
@ -425,26 +432,7 @@ class TopLevelCommand(object):
tty = not options["-T"]
if IS_WINDOWS_PLATFORM and not detach:
args = ["exec"]
if options["-d"]:
args += ["--detach"]
else:
args += ["--interactive"]
if not options["-T"]:
args += ["--tty"]
if options["--privileged"]:
args += ["--privileged"]
if options["--user"]:
args += ["--user", options["--user"]]
args += [container.id]
args += command
sys.exit(call_docker(args))
sys.exit(call_docker(build_exec_command(options, container.id, command)))
create_exec_options = {
"privileged": options["--privileged"],
@ -453,6 +441,9 @@ class TopLevelCommand(object):
"stdin": tty,
}
if docker.utils.version_gte(self.project.client.api_version, '1.25'):
create_exec_options["environment"] = options["--env"]
exec_id = container.create_exec(command, **create_exec_options)
if detach:
@ -1295,3 +1286,29 @@ def parse_scale_args(options):
)
res[service_name] = num
return res
def build_exec_command(options, container_id, command):
args = ["exec"]
if options["-d"]:
args += ["--detach"]
else:
args += ["--interactive"]
if not options["-T"]:
args += ["--tty"]
if options["--privileged"]:
args += ["--privileged"]
if options["--user"]:
args += ["--user", options["--user"]]
if options["--env"]:
for env_variable in options["--env"]:
args += ["--env", env_variable]
args += [container_id]
args += command
return args

View File

@ -33,6 +33,7 @@ from tests.integration.testcases import no_cluster
from tests.integration.testcases import pull_busybox
from tests.integration.testcases import SWARM_SKIP_RM_VOLUMES
from tests.integration.testcases import v2_1_only
from tests.integration.testcases import v2_2_only
from tests.integration.testcases import v2_only
from tests.integration.testcases import v3_only
@ -1369,6 +1370,31 @@ class CLITestCase(DockerClientTestCase):
self.assertEqual(stdout, "operator\n")
self.assertEqual(stderr, "")
@v2_2_only()
def test_exec_service_with_environment_overridden(self):
name = 'service'
self.base_dir = 'tests/fixtures/environment-exec'
self.dispatch(['up', '-d'])
self.assertEqual(len(self.project.containers()), 1)
stdout, stderr = self.dispatch([
'exec',
'-T',
'-e', 'foo=notbar',
'--env', 'alpha=beta',
name,
'env',
])
# env overridden
assert 'foo=notbar' in stdout
# keep environment from yaml
assert 'hello=world' in stdout
# added option from command line
assert 'alpha=beta' in stdout
self.assertEqual(stderr, '')
def test_run_service_without_links(self):
self.base_dir = 'tests/fixtures/links-composefile'
self.dispatch(['run', 'console', '/bin/true'])

View File

@ -0,0 +1,10 @@
version: "2.2"
services:
service:
image: busybox:latest
command: top
environment:
foo: bar
hello: world