summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fig/cli/main.py19
-rw-r--r--fig/cli/socketclient.py126
-rw-r--r--requirements.txt1
3 files changed, 4 insertions, 142 deletions
diff --git a/fig/cli/main.py b/fig/cli/main.py
index 9e4e4669..fdac8a2f 100644
--- a/fig/cli/main.py
+++ b/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)
diff --git a/fig/cli/socketclient.py b/fig/cli/socketclient.py
deleted file mode 100644
index 6cc1f2c5..00000000
--- a/fig/cli/socketclient.py
+++ /dev/null
@@ -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()
diff --git a/requirements.txt b/requirements.txt
index bec41811..4eea6cd3 100644
--- a/requirements.txt
+++ b/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