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 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,
) )

View File

@ -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:

View File

@ -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,