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:
Ben Firshman 2014-01-20 10:19:13 -08:00
commit 8773bad99a
3 changed files with 28 additions and 43 deletions

View File

@ -4,7 +4,6 @@ import logging
import sys
import re
import signal
import sys
from inspect import getdoc
@ -200,12 +199,20 @@ class TopLevelCommand(Command):
Usage: run [options] SERVICE COMMAND [ARGS...]
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'])
tty = True
if options['-d'] or options['-T'] or not sys.stdin.isatty():
tty = False
container_options = {
'command': [options['COMMAND']] + options['ARGS'],
'tty': not options['-d'],
'tty': tty,
'stdin_open': not options['-d'],
}
container = service.create_container(one_off=True, **container_options)
@ -213,12 +220,7 @@ class TopLevelCommand(Command):
service.start_container(container, ports=None)
print(container.name)
else:
with self._attach_to_container(
container.id,
interactive=True,
logs=True,
raw=True
) as c:
with self._attach_to_container(container.id, raw=tty) as c:
service.start_container(container, ports=None)
c.run()
@ -310,35 +312,15 @@ class TopLevelCommand(Command):
print("Gracefully stopping... (press Ctrl+C again to force)")
self.project.stop(service_names=options['SERVICE'])
def _attach_to_container(self, container_id, interactive, logs=False, stream=True, raw=False):
stdio = self.client.attach_socket(
container_id,
params={
'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,
)
def _attach_to_container(self, container_id, raw=False):
socket_in = self.client.attach_socket(container_id, params={'stdin': 1, 'stream': 1})
socket_out = self.client.attach_socket(container_id, params={'stdout': 1, 'logs': 1, 'stream': 1})
socket_err = self.client.attach_socket(container_id, params={'stderr': 1, 'logs': 1, 'stream': 1})
return SocketClient(
socket_in=stdio,
socket_out=stdio,
socket_err=stderr,
socket_in=socket_in,
socket_out=socket_out,
socket_err=socket_err,
raw=raw,
)

View File

@ -57,15 +57,15 @@ class SocketClient:
def run(self):
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 = []
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:
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:
t.join()
@ -76,10 +76,10 @@ class SocketClient:
thread.start()
return thread
def recv_ws(self, socket, stream):
def recv(self, socket, stream):
try:
while True:
chunk = socket.recv()
chunk = socket.recv(4096)
if chunk:
stream.write(chunk)
@ -89,7 +89,7 @@ class SocketClient:
except Exception as e:
log.debug(e)
def send_ws(self, socket, stream):
def send(self, socket, stream):
while True:
r, w, e = select([stream.fileno()], [], [])
@ -97,7 +97,7 @@ class SocketClient:
chunk = stream.read(1)
if chunk == '':
socket.send_close()
socket.close()
break
else:
try:

View File

@ -152,6 +152,7 @@ class Client(requests.Session):
attach_stdin = False
attach_stdout = False
attach_stderr = False
stdin_once = False
if not detach:
attach_stdout = True
@ -159,6 +160,7 @@ class Client(requests.Session):
if stdin_open:
attach_stdin = True
stdin_once = True
return {
'Hostname': hostname,
@ -166,6 +168,7 @@ class Client(requests.Session):
'User': user,
'Tty': tty,
'OpenStdin': stdin_open,
'StdinOnce': stdin_once,
'Memory': mem_limit,
'AttachStdin': attach_stdin,
'AttachStdout': attach_stdout,