From fc1bbb45b1a9a72d8f4d3fa00eeb1f8a3ebb3eb8 Mon Sep 17 00:00:00 2001 From: Ben Firshman Date: Sun, 19 Jan 2014 20:33:06 +0000 Subject: [PATCH 1/3] Add option to disable pseudo-tty on fig run Also disable tty if stdin is not a tty. --- fig/cli/main.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fig/cli/main.py b/fig/cli/main.py index 44422777f..1696a7c98 100644 --- a/fig/cli/main.py +++ b/fig/cli/main.py @@ -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) @@ -217,7 +224,7 @@ class TopLevelCommand(Command): container.id, interactive=True, logs=True, - raw=True + raw=tty ) as c: service.start_container(container, ports=None) c.run() From 405079f744fb6901a97a1910218ee008a03607de Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Mon, 20 Jan 2014 15:52:07 +0000 Subject: [PATCH 2/3] Use raw socket in 'fig run', simplify _attach_to_container --- fig/cli/main.py | 41 ++++++++--------------------------------- fig/cli/socketclient.py | 14 +++++++------- 2 files changed, 15 insertions(+), 40 deletions(-) diff --git a/fig/cli/main.py b/fig/cli/main.py index 1696a7c98..66d2bdf28 100644 --- a/fig/cli/main.py +++ b/fig/cli/main.py @@ -220,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=tty - ) as c: + with self._attach_to_container(container.id, raw=tty) as c: service.start_container(container, ports=None) c.run() @@ -317,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, ) diff --git a/fig/cli/socketclient.py b/fig/cli/socketclient.py index bbae60e6d..842c9c6a4 100644 --- a/fig/cli/socketclient.py +++ b/fig/cli/socketclient.py @@ -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: From 084db337a00ad10224c12ab6aebf21a3bdff8476 Mon Sep 17 00:00:00 2001 From: Aanand Prasad Date: Mon, 20 Jan 2014 18:09:25 +0000 Subject: [PATCH 3/3] Update docker-py Brought in changes from https://github.com/dotcloud/docker-py/pull/145 --- fig/packages/docker/client.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fig/packages/docker/client.py b/fig/packages/docker/client.py index 3fc2b0846..7bc46aacf 100644 --- a/fig/packages/docker/client.py +++ b/fig/packages/docker/client.py @@ -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,