|
|
5b57c4 |
From 7761a8cf3568f25243e7881b315b9fc922237673 Mon Sep 17 00:00:00 2001
|
|
|
5b57c4 |
From: Tomas Tomecek <ttomecek@redhat.com>
|
|
|
5b57c4 |
Date: Thu, 10 May 2018 16:10:36 +0200
|
|
|
5b57c4 |
Subject: [PATCH] asd
|
|
|
5b57c4 |
|
|
|
5b57c4 |
---
|
|
|
5b57c4 |
docker/api/container.py | 4 +++-
|
|
|
5b57c4 |
docker/api/exec_api.py | 2 +-
|
|
|
5b57c4 |
docker/client.py | 22 ++++++++++++++++------
|
|
|
5b57c4 |
docker/utils/socket.py | 31 +++++++++++++++++++++++++++----
|
|
|
5b57c4 |
tests/unit/api_test.py | 2 +-
|
|
|
5b57c4 |
5 files changed, 48 insertions(+), 13 deletions(-)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
diff --git a/docker/api/container.py b/docker/api/container.py
|
|
|
5b57c4 |
index b8507d8..a164e7d 100644
|
|
|
5b57c4 |
--- a/docker/api/container.py
|
|
|
5b57c4 |
+++ b/docker/api/container.py
|
|
|
5b57c4 |
@@ -26,7 +26,9 @@ class ContainerApiMixin(object):
|
|
|
5b57c4 |
u = self._url("/containers/{0}/attach", container)
|
|
|
5b57c4 |
response = self._post(u, headers=headers, params=params, stream=stream)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
- return self._read_from_socket(response, stream)
|
|
|
5b57c4 |
+ return self._read_from_socket(
|
|
|
5b57c4 |
+ response, stream, self._check_is_tty(container)
|
|
|
5b57c4 |
+ )
|
|
|
5b57c4 |
|
|
|
5b57c4 |
@utils.check_resource
|
|
|
5b57c4 |
def attach_socket(self, container, params=None, ws=False):
|
|
|
5b57c4 |
diff --git a/docker/api/exec_api.py b/docker/api/exec_api.py
|
|
|
5b57c4 |
index 6e49996..9468f46 100644
|
|
|
5b57c4 |
--- a/docker/api/exec_api.py
|
|
|
5b57c4 |
+++ b/docker/api/exec_api.py
|
|
|
5b57c4 |
@@ -78,4 +78,4 @@ class ExecApiMixin(object):
|
|
|
5b57c4 |
|
|
|
5b57c4 |
if socket:
|
|
|
5b57c4 |
return self._get_raw_response_socket(res)
|
|
|
5b57c4 |
- return self._read_from_socket(res, stream)
|
|
|
5b57c4 |
+ return self._read_from_socket(res, stream, tty)
|
|
|
5b57c4 |
diff --git a/docker/client.py b/docker/client.py
|
|
|
5b57c4 |
index 3fa19e0..eb928c6 100644
|
|
|
5b57c4 |
--- a/docker/client.py
|
|
|
5b57c4 |
+++ b/docker/client.py
|
|
|
5b57c4 |
@@ -16,7 +16,7 @@ from .ssladapter import ssladapter
|
|
|
5b57c4 |
from .tls import TLSConfig
|
|
|
5b57c4 |
from .transport import UnixAdapter
|
|
|
5b57c4 |
from .utils import utils, check_resource, update_headers, kwargs_from_env
|
|
|
5b57c4 |
-from .utils.socket import frames_iter
|
|
|
5b57c4 |
+from .utils.socket import frames_iter, socket_raw_iter
|
|
|
5b57c4 |
try:
|
|
|
5b57c4 |
from .transport import NpipeAdapter
|
|
|
5b57c4 |
except ImportError:
|
|
|
5b57c4 |
@@ -317,13 +317,19 @@ class Client(
|
|
|
5b57c4 |
for out in response.iter_content(chunk_size=1, decode_unicode=True):
|
|
|
5b57c4 |
yield out
|
|
|
5b57c4 |
|
|
|
5b57c4 |
- def _read_from_socket(self, response, stream):
|
|
|
5b57c4 |
+ def _read_from_socket(self, response, stream, tty=False):
|
|
|
5b57c4 |
socket = self._get_raw_response_socket(response)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
+ gen = None
|
|
|
5b57c4 |
+ if tty is False:
|
|
|
5b57c4 |
+ gen = frames_iter(socket)
|
|
|
5b57c4 |
+ else:
|
|
|
5b57c4 |
+ gen = socket_raw_iter(socket)
|
|
|
5b57c4 |
+
|
|
|
5b57c4 |
if stream:
|
|
|
5b57c4 |
- return frames_iter(socket)
|
|
|
5b57c4 |
+ return gen
|
|
|
5b57c4 |
else:
|
|
|
5b57c4 |
- return six.binary_type().join(frames_iter(socket))
|
|
|
5b57c4 |
+ return six.binary_type().join(gen)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
def _disable_socket_timeout(self, socket):
|
|
|
5b57c4 |
""" Depending on the combination of python version and whether we're
|
|
|
5b57c4 |
@@ -353,9 +359,13 @@ class Client(
|
|
|
5b57c4 |
|
|
|
5b57c4 |
s.settimeout(None)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
- def _get_result(self, container, stream, res):
|
|
|
5b57c4 |
+ @check_resource
|
|
|
5b57c4 |
+ def _check_is_tty(self, container):
|
|
|
5b57c4 |
cont = self.inspect_container(container)
|
|
|
5b57c4 |
- return self._get_result_tty(stream, res, cont['Config']['Tty'])
|
|
|
5b57c4 |
+ return cont['Config']['Tty']
|
|
|
5b57c4 |
+
|
|
|
5b57c4 |
+ def _get_result(self, container, stream, res):
|
|
|
5b57c4 |
+ return self._get_result_tty(stream, res, self._check_is_tty(container))
|
|
|
5b57c4 |
|
|
|
5b57c4 |
def _get_result_tty(self, stream, res, is_tty):
|
|
|
5b57c4 |
# Stream multi-plexing was only introduced in API v1.6. Anything
|
|
|
5b57c4 |
diff --git a/docker/utils/socket.py b/docker/utils/socket.py
|
|
|
5b57c4 |
index 164b845..c3a5f90 100644
|
|
|
5b57c4 |
--- a/docker/utils/socket.py
|
|
|
5b57c4 |
+++ b/docker/utils/socket.py
|
|
|
5b57c4 |
@@ -59,7 +59,7 @@ def next_frame_size(socket):
|
|
|
5b57c4 |
try:
|
|
|
5b57c4 |
data = read_exactly(socket, 8)
|
|
|
5b57c4 |
except SocketError:
|
|
|
5b57c4 |
- return 0
|
|
|
5b57c4 |
+ return -1
|
|
|
5b57c4 |
|
|
|
5b57c4 |
_, actual = struct.unpack('>BxxxL', data)
|
|
|
5b57c4 |
return actual
|
|
|
5b57c4 |
@@ -69,7 +69,30 @@ def frames_iter(socket):
|
|
|
5b57c4 |
"""
|
|
|
5b57c4 |
Returns a generator of frames read from socket
|
|
|
5b57c4 |
"""
|
|
|
5b57c4 |
- n = next_frame_size(socket)
|
|
|
5b57c4 |
- while n > 0:
|
|
|
5b57c4 |
- yield read(socket, n)
|
|
|
5b57c4 |
+ while True:
|
|
|
5b57c4 |
n = next_frame_size(socket)
|
|
|
5b57c4 |
+ if n < 0:
|
|
|
5b57c4 |
+ break
|
|
|
5b57c4 |
+ while n > 0:
|
|
|
5b57c4 |
+ result = read(socket, n)
|
|
|
5b57c4 |
+ if result is None:
|
|
|
5b57c4 |
+ continue
|
|
|
5b57c4 |
+ data_length = len(result)
|
|
|
5b57c4 |
+ if data_length == 0:
|
|
|
5b57c4 |
+ # We have reached EOF
|
|
|
5b57c4 |
+ return
|
|
|
5b57c4 |
+ n -= data_length
|
|
|
5b57c4 |
+ yield result
|
|
|
5b57c4 |
+
|
|
|
5b57c4 |
+
|
|
|
5b57c4 |
+def socket_raw_iter(socket):
|
|
|
5b57c4 |
+ """
|
|
|
5b57c4 |
+ Returns a generator of data read from the socket.
|
|
|
5b57c4 |
+ This is used for non-multiplexed streams.
|
|
|
5b57c4 |
+ """
|
|
|
5b57c4 |
+ while True:
|
|
|
5b57c4 |
+ result = read(socket)
|
|
|
5b57c4 |
+ if len(result) == 0:
|
|
|
5b57c4 |
+ # We have reached EOF
|
|
|
5b57c4 |
+ return
|
|
|
5b57c4 |
+ yield result
|
|
|
5b57c4 |
diff --git a/tests/unit/api_test.py b/tests/unit/api_test.py
|
|
|
5b57c4 |
index 8faca6b..3aeff85 100644
|
|
|
5b57c4 |
--- a/tests/unit/api_test.py
|
|
|
5b57c4 |
+++ b/tests/unit/api_test.py
|
|
|
5b57c4 |
@@ -83,7 +83,7 @@ def fake_delete(self, url, *args, **kwargs):
|
|
|
5b57c4 |
return fake_request('DELETE', url, *args, **kwargs)
|
|
|
5b57c4 |
|
|
|
5b57c4 |
|
|
|
5b57c4 |
-def fake_read_from_socket(self, response, stream):
|
|
|
5b57c4 |
+def fake_read_from_socket(self, response, stream, tty=False):
|
|
|
5b57c4 |
return six.binary_type()
|
|
|
5b57c4 |
|
|
|
5b57c4 |
url_base = '{0}/'.format(fake_api.prefix)
|
|
|
5b57c4 |
--
|
|
|
5b57c4 |
2.17.0
|
|
|
5b57c4 |
|