mirror of https://github.com/docker/compose.git
Merge pull request #34 from orchardup/better-tty-handling-for-fig-run
Add option to disable pseudo-tty on fig run
This commit is contained in:
commit
8773bad99a
|
@ -4,7 +4,6 @@ import logging
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
import sys
|
|
||||||
|
|
||||||
from inspect import getdoc
|
from inspect import getdoc
|
||||||
|
|
||||||
|
@ -200,12 +199,20 @@ class TopLevelCommand(Command):
|
||||||
Usage: run [options] SERVICE COMMAND [ARGS...]
|
Usage: run [options] SERVICE COMMAND [ARGS...]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-d Detached mode: Run container in the background, print new container name
|
-d Detached mode: Run container in the background, print new
|
||||||
|
container name
|
||||||
|
-T Disable pseudo-tty allocation. By default `fig run`
|
||||||
|
allocates a TTY.
|
||||||
"""
|
"""
|
||||||
service = self.project.get_service(options['SERVICE'])
|
service = self.project.get_service(options['SERVICE'])
|
||||||
|
|
||||||
|
tty = True
|
||||||
|
if options['-d'] or options['-T'] or not sys.stdin.isatty():
|
||||||
|
tty = False
|
||||||
|
|
||||||
container_options = {
|
container_options = {
|
||||||
'command': [options['COMMAND']] + options['ARGS'],
|
'command': [options['COMMAND']] + options['ARGS'],
|
||||||
'tty': not options['-d'],
|
'tty': tty,
|
||||||
'stdin_open': not options['-d'],
|
'stdin_open': not options['-d'],
|
||||||
}
|
}
|
||||||
container = service.create_container(one_off=True, **container_options)
|
container = service.create_container(one_off=True, **container_options)
|
||||||
|
@ -213,12 +220,7 @@ class TopLevelCommand(Command):
|
||||||
service.start_container(container, ports=None)
|
service.start_container(container, ports=None)
|
||||||
print(container.name)
|
print(container.name)
|
||||||
else:
|
else:
|
||||||
with self._attach_to_container(
|
with self._attach_to_container(container.id, raw=tty) as c:
|
||||||
container.id,
|
|
||||||
interactive=True,
|
|
||||||
logs=True,
|
|
||||||
raw=True
|
|
||||||
) as c:
|
|
||||||
service.start_container(container, ports=None)
|
service.start_container(container, ports=None)
|
||||||
c.run()
|
c.run()
|
||||||
|
|
||||||
|
@ -310,35 +312,15 @@ class TopLevelCommand(Command):
|
||||||
print("Gracefully stopping... (press Ctrl+C again to force)")
|
print("Gracefully stopping... (press Ctrl+C again to force)")
|
||||||
self.project.stop(service_names=options['SERVICE'])
|
self.project.stop(service_names=options['SERVICE'])
|
||||||
|
|
||||||
def _attach_to_container(self, container_id, interactive, logs=False, stream=True, raw=False):
|
def _attach_to_container(self, container_id, raw=False):
|
||||||
stdio = self.client.attach_socket(
|
socket_in = self.client.attach_socket(container_id, params={'stdin': 1, 'stream': 1})
|
||||||
container_id,
|
socket_out = self.client.attach_socket(container_id, params={'stdout': 1, 'logs': 1, 'stream': 1})
|
||||||
params={
|
socket_err = self.client.attach_socket(container_id, params={'stderr': 1, 'logs': 1, 'stream': 1})
|
||||||
'stdin': 1 if interactive else 0,
|
|
||||||
'stdout': 1,
|
|
||||||
'stderr': 0,
|
|
||||||
'logs': 1 if logs else 0,
|
|
||||||
'stream': 1 if stream else 0
|
|
||||||
},
|
|
||||||
ws=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
stderr = self.client.attach_socket(
|
|
||||||
container_id,
|
|
||||||
params={
|
|
||||||
'stdin': 0,
|
|
||||||
'stdout': 0,
|
|
||||||
'stderr': 1,
|
|
||||||
'logs': 1 if logs else 0,
|
|
||||||
'stream': 1 if stream else 0
|
|
||||||
},
|
|
||||||
ws=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
return SocketClient(
|
return SocketClient(
|
||||||
socket_in=stdio,
|
socket_in=socket_in,
|
||||||
socket_out=stdio,
|
socket_out=socket_out,
|
||||||
socket_err=stderr,
|
socket_err=socket_err,
|
||||||
raw=raw,
|
raw=raw,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -57,15 +57,15 @@ class SocketClient:
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if self.socket_in is not None:
|
if self.socket_in is not None:
|
||||||
self.start_background_thread(target=self.send_ws, args=(self.socket_in, sys.stdin))
|
self.start_background_thread(target=self.send, args=(self.socket_in, sys.stdin))
|
||||||
|
|
||||||
recv_threads = []
|
recv_threads = []
|
||||||
|
|
||||||
if self.socket_out is not None:
|
if self.socket_out is not None:
|
||||||
recv_threads.append(self.start_background_thread(target=self.recv_ws, args=(self.socket_out, sys.stdout)))
|
recv_threads.append(self.start_background_thread(target=self.recv, args=(self.socket_out, sys.stdout)))
|
||||||
|
|
||||||
if self.socket_err is not None:
|
if self.socket_err is not None:
|
||||||
recv_threads.append(self.start_background_thread(target=self.recv_ws, args=(self.socket_err, sys.stderr)))
|
recv_threads.append(self.start_background_thread(target=self.recv, args=(self.socket_err, sys.stderr)))
|
||||||
|
|
||||||
for t in recv_threads:
|
for t in recv_threads:
|
||||||
t.join()
|
t.join()
|
||||||
|
@ -76,10 +76,10 @@ class SocketClient:
|
||||||
thread.start()
|
thread.start()
|
||||||
return thread
|
return thread
|
||||||
|
|
||||||
def recv_ws(self, socket, stream):
|
def recv(self, socket, stream):
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
chunk = socket.recv()
|
chunk = socket.recv(4096)
|
||||||
|
|
||||||
if chunk:
|
if chunk:
|
||||||
stream.write(chunk)
|
stream.write(chunk)
|
||||||
|
@ -89,7 +89,7 @@ class SocketClient:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug(e)
|
log.debug(e)
|
||||||
|
|
||||||
def send_ws(self, socket, stream):
|
def send(self, socket, stream):
|
||||||
while True:
|
while True:
|
||||||
r, w, e = select([stream.fileno()], [], [])
|
r, w, e = select([stream.fileno()], [], [])
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ class SocketClient:
|
||||||
chunk = stream.read(1)
|
chunk = stream.read(1)
|
||||||
|
|
||||||
if chunk == '':
|
if chunk == '':
|
||||||
socket.send_close()
|
socket.close()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -152,6 +152,7 @@ class Client(requests.Session):
|
||||||
attach_stdin = False
|
attach_stdin = False
|
||||||
attach_stdout = False
|
attach_stdout = False
|
||||||
attach_stderr = False
|
attach_stderr = False
|
||||||
|
stdin_once = False
|
||||||
|
|
||||||
if not detach:
|
if not detach:
|
||||||
attach_stdout = True
|
attach_stdout = True
|
||||||
|
@ -159,6 +160,7 @@ class Client(requests.Session):
|
||||||
|
|
||||||
if stdin_open:
|
if stdin_open:
|
||||||
attach_stdin = True
|
attach_stdin = True
|
||||||
|
stdin_once = True
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'Hostname': hostname,
|
'Hostname': hostname,
|
||||||
|
@ -166,6 +168,7 @@ class Client(requests.Session):
|
||||||
'User': user,
|
'User': user,
|
||||||
'Tty': tty,
|
'Tty': tty,
|
||||||
'OpenStdin': stdin_open,
|
'OpenStdin': stdin_open,
|
||||||
|
'StdinOnce': stdin_once,
|
||||||
'Memory': mem_limit,
|
'Memory': mem_limit,
|
||||||
'AttachStdin': attach_stdin,
|
'AttachStdin': attach_stdin,
|
||||||
'AttachStdout': attach_stdout,
|
'AttachStdout': attach_stdout,
|
||||||
|
|
Loading…
Reference in New Issue