Prechádzať zdrojové kódy

Use dockerpty instead for pseudo-tty behaviour.

Signed-off-by: Chris Corbyn <[email protected]>
Chris Corbyn 11 rokov pred
rodič
commit
3770aac1af
3 zmenil súbory, kde vykonal 4 pridanie a 142 odobranie
  1. 3 16
      fig/cli/main.py
  2. 0 126
      fig/cli/socketclient.py
  3. 1 0
      requirements.txt

+ 3 - 16
fig/cli/main.py

@@ -6,6 +6,7 @@ import re
 import signal
 
 from inspect import getdoc
+import dockerpty
 
 from .. import __version__
 from ..project import NoSuchService, ConfigurationError
@@ -18,7 +19,6 @@ from .utils import yesno
 from ..packages.docker.errors import APIError
 from .errors import UserError
 from .docopt_command import NoSuchCommand
-from .socketclient import SocketClient
 
 log = logging.getLogger(__name__)
 
@@ -240,9 +240,8 @@ class TopLevelCommand(Command):
             service.start_container(container, ports=None, one_off=True)
             print(container.name)
         else:
-            with self._attach_to_container(container.id, raw=tty) as c:
-                service.start_container(container, ports=None, one_off=True)
-                c.run()
+            service.start_container(container, ports=None, one_off=True)
+            dockerpty.start(self.client, container.id)
             exit_code = container.wait()
             if options['--rm']:
                 log.info("Removing %s..." % container.name)
@@ -341,17 +340,5 @@ class TopLevelCommand(Command):
                 print("Gracefully stopping... (press Ctrl+C again to force)")
                 self.project.stop(service_names=service_names)
 
-    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=socket_in,
-            socket_out=socket_out,
-            socket_err=socket_err,
-            raw=raw,
-        )
-
 def list_containers(containers):
     return ", ".join(c.name for c in containers)

+ 0 - 126
fig/cli/socketclient.py

@@ -1,126 +0,0 @@
-from __future__ import print_function
-# Adapted from https://github.com/benthor/remotty/blob/master/socketclient.py
-
-import sys
-import tty
-import fcntl
-import os
-import termios
-import threading
-import errno
-
-import logging
-log = logging.getLogger(__name__)
-
-
-class SocketClient:
-    def __init__(self,
-        socket_in=None,
-        socket_out=None,
-        socket_err=None,
-        raw=True,
-    ):
-        self.socket_in = socket_in
-        self.socket_out = socket_out
-        self.socket_err = socket_err
-        self.raw = raw
-
-        self.stdin_fileno = sys.stdin.fileno()
-
-    def __enter__(self):
-        self.create()
-        return self
-
-    def __exit__(self, type, value, trace):
-        self.destroy()
-
-    def create(self):
-        if os.isatty(sys.stdin.fileno()):
-            self.settings = termios.tcgetattr(sys.stdin.fileno())
-        else:
-            self.settings = None
-
-        if self.socket_in is not None:
-            self.set_blocking(sys.stdin, False)
-            self.set_blocking(sys.stdout, True)
-            self.set_blocking(sys.stderr, True)
-
-        if self.raw:
-            tty.setraw(sys.stdin.fileno())
-
-    def set_blocking(self, file, blocking):
-        fd = file.fileno()
-        flags = fcntl.fcntl(fd, fcntl.F_GETFL)
-        flags = (flags & ~os.O_NONBLOCK) if blocking else (flags | os.O_NONBLOCK)
-        fcntl.fcntl(fd, fcntl.F_SETFL, flags)
-
-    def run(self):
-        if self.socket_in is not None:
-            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, args=(self.socket_out, sys.stdout)))
-
-        if self.socket_err is not None:
-            recv_threads.append(self.start_background_thread(target=self.recv, args=(self.socket_err, sys.stderr)))
-
-        for t in recv_threads:
-            t.join()
-
-    def start_background_thread(self, **kwargs):
-        thread = threading.Thread(**kwargs)
-        thread.daemon = True
-        thread.start()
-        return thread
-
-    def recv(self, socket, stream):
-        try:
-            while True:
-                chunk = socket.recv(4096)
-
-                if chunk:
-                    stream.write(chunk)
-                    stream.flush()
-                else:
-                    break
-        except Exception as e:
-            log.debug(e)
-
-    def send(self, socket, stream):
-        while True:
-            chunk = stream.read(1)
-
-            if chunk == '':
-                socket.close()
-                break
-            else:
-                try:
-                    socket.send(chunk)
-                except Exception as e:
-                    if hasattr(e, 'errno') and e.errno == errno.EPIPE:
-                        break
-                    else:
-                        raise e
-
-    def destroy(self):
-        if self.settings is not None:
-            termios.tcsetattr(self.stdin_fileno, termios.TCSADRAIN, self.settings)
-
-        sys.stdout.flush()
-
-if __name__ == '__main__':
-    import websocket
-
-    if len(sys.argv) != 2:
-        sys.stderr.write("Usage: python socketclient.py WEBSOCKET_URL\n")
-        sys.exit(1)
-
-    url = sys.argv[1]
-    socket = websocket.create_connection(url)
-
-    print("connected\r")
-
-    with SocketClient(socket, interactive=True) as client:
-        client.run()

+ 1 - 0
requirements.txt

@@ -3,3 +3,4 @@ PyYAML==3.10
 requests==2.2.1
 texttable==0.8.1
 websocket-client==0.11.0
+dockerpty==0.0.8