-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
d11wtq/dockerpty#13 is actually a docker-py bug: a docker-py client communicating over TLS will always return a closed socket from attach_socket()
. This appears to be because the response object (returned by self.post
) is garbage-collected at the end of the method, which presumably causes the connection to be closed:
return self._get_raw_response_socket(self.post(
u, None, params=self._attach_params(params), stream=True))
This is speculation, but maybe the TLS socket object (an instance of ssl.SSLSocket
) doesn't keep a back-reference to whatever's managing the connection, so the response object is the only thing holding on to it. All I know is, I can make it work in a test script if I replicate attach_socket()
's behaviour but hold on to the response by assigning it to a local variable:
# `client` is a docker.Client with TLS enabled
container = client.create_container(image='busybox', command=['echo', 'hello', 'world']).get('Id')
params = {'stdout': 1, 'stderr': 1, 'logs': 1, 'stream': 1}
# this breaks
# socket = client.attach_socket(container, params)
# this works
url = client._url("/containers/{0}/attach".format(container))
response = client.post(url, None, params=client._attach_params(params), stream=True)
socket = client._get_raw_response_socket(response)
client.start(container)
while True:
chunk = socket.recv(4096)
if chunk == '':
break
print 'got chunk:', repr(chunk)
I'm thinking about possible fixes. It might be necessary to return an object which wraps the SSLSocket
and keeps a reference to the response - annoying/icky to be adding another layer of wrapping, though.
In any case, this is a complete blocker for any program hoping to attach over TLS - such as Fig.