|
@@ -6,7 +6,9 @@ import contextlib
|
|
|
import functools
|
|
|
import json
|
|
|
import logging
|
|
|
+import pipes
|
|
|
import re
|
|
|
+import subprocess
|
|
|
import sys
|
|
|
from inspect import getdoc
|
|
|
from operator import attrgetter
|
|
@@ -406,11 +408,6 @@ class TopLevelCommand(object):
|
|
|
service = self.project.get_service(options['SERVICE'])
|
|
|
detach = options['-d']
|
|
|
|
|
|
- if IS_WINDOWS_PLATFORM and not detach:
|
|
|
- raise UserError(
|
|
|
- "Interactive mode is not yet supported on Windows.\n"
|
|
|
- "Please pass the -d flag when using `docker-compose exec`."
|
|
|
- )
|
|
|
try:
|
|
|
container = service.get_container(number=index)
|
|
|
except ValueError as e:
|
|
@@ -418,6 +415,28 @@ class TopLevelCommand(object):
|
|
|
command = [options['COMMAND']] + options['ARGS']
|
|
|
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))
|
|
|
+
|
|
|
create_exec_options = {
|
|
|
"privileged": options["--privileged"],
|
|
|
"user": options["--user"],
|
|
@@ -675,12 +694,6 @@ class TopLevelCommand(object):
|
|
|
service = self.project.get_service(options['SERVICE'])
|
|
|
detach = options['-d']
|
|
|
|
|
|
- if IS_WINDOWS_PLATFORM and not detach:
|
|
|
- raise UserError(
|
|
|
- "Interactive mode is not yet supported on Windows.\n"
|
|
|
- "Please pass the -d flag when using `docker-compose run`."
|
|
|
- )
|
|
|
-
|
|
|
if options['--publish'] and options['--service-ports']:
|
|
|
raise UserError(
|
|
|
'Service port mapping and manual port mapping '
|
|
@@ -969,17 +982,20 @@ def run_one_off_container(container_options, project, service, options):
|
|
|
signals.set_signal_handler_to_shutdown()
|
|
|
try:
|
|
|
try:
|
|
|
- operation = RunOperation(
|
|
|
- project.client,
|
|
|
- container.id,
|
|
|
- interactive=not options['-T'],
|
|
|
- logs=False,
|
|
|
- )
|
|
|
- pty = PseudoTerminal(project.client, operation)
|
|
|
- sockets = pty.sockets()
|
|
|
- service.start_container(container)
|
|
|
- pty.start(sockets)
|
|
|
- exit_code = container.wait()
|
|
|
+ if IS_WINDOWS_PLATFORM:
|
|
|
+ exit_code = call_docker(["start", "--attach", "--interactive", container.id])
|
|
|
+ else:
|
|
|
+ operation = RunOperation(
|
|
|
+ project.client,
|
|
|
+ container.id,
|
|
|
+ interactive=not options['-T'],
|
|
|
+ logs=False,
|
|
|
+ )
|
|
|
+ pty = PseudoTerminal(project.client, operation)
|
|
|
+ sockets = pty.sockets()
|
|
|
+ service.start_container(container)
|
|
|
+ pty.start(sockets)
|
|
|
+ exit_code = container.wait()
|
|
|
except signals.ShutdownException:
|
|
|
project.client.stop(container.id)
|
|
|
exit_code = 1
|
|
@@ -1044,3 +1060,15 @@ def exit_if(condition, message, exit_code):
|
|
|
if condition:
|
|
|
log.error(message)
|
|
|
raise SystemExit(exit_code)
|
|
|
+
|
|
|
+
|
|
|
+def call_docker(args):
|
|
|
+ try:
|
|
|
+ executable_path = subprocess.check_output(["which", "docker"]).strip()
|
|
|
+ except subprocess.CalledProcessError:
|
|
|
+ raise UserError(errors.docker_not_found_msg("Couldn't find `docker` binary."))
|
|
|
+
|
|
|
+ args = [executable_path] + args
|
|
|
+ log.debug(" ".join(map(pipes.quote, args)))
|
|
|
+
|
|
|
+ return subprocess.call(args)
|