Ver código fonte

Merge pull request #34 from orchardup/better-tty-handling-for-fig-run

Add option to disable pseudo-tty on fig run
Ben Firshman 11 anos atrás
pai
commit
8773bad99a
3 arquivos alterados com 28 adições e 43 exclusões
  1. 18 36
      fig/cli/main.py
  2. 7 7
      fig/cli/socketclient.py
  3. 3 0
      fig/packages/docker/client.py

+ 18 - 36
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)
@@ -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,
         )
 

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

+ 3 - 0
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,