Skip to content

Instantly share code, notes, and snippets.

@nakamuray
Created June 4, 2014 15:28
Show Gist options
  • Save nakamuray/9b6b9bf20ab009cd6dc6 to your computer and use it in GitHub Desktop.
Save nakamuray/9b6b9bf20ab009cd6dc6 to your computer and use it in GitHub Desktop.
implement docker attach like command using twisted
# vim: fileencoding=utf-8
from __future__ import print_function
import sys
from twisted.internet import defer
from twisted.internet.protocol import Protocol
from twisted.internet.stdio import StandardIO
from docker import dockerAPI
class ResponsePrinter(Protocol):
def __init__(self):
self.finished = defer.Deferred()
def dataReceived(self, data):
print(data, end='')
sys.stdout.flush()
def connectionLost(self, reason):
self.finished.callback(None)
class InputSender(Protocol):
def __init__(self, transport):
self.docker_transport = transport
def dataReceived(self, data):
self.docker_transport.write(data)
@defer.inlineCallbacks
def main(reactor, container_id):
response = yield dockerAPI('/containers/{}/attach'.format(container_id),
method=b'POST', stdin=1, stdout=1, stream=1)
printer = ResponsePrinter()
response.deliverBody(printer)
# XXX: how can I get raw transport decently?
stdio = StandardIO(InputSender(response._transport._producer))
yield printer.finished
if __name__ == '__main__':
from twisted.internet.task import react
react(main, sys.argv[1:])
# vim: fileencoding=utf-8
"""Docker Remote API client
"""
from __future__ import print_function
import urllib
from cStringIO import StringIO
from twisted.internet import defer
from twisted.internet.endpoints import UNIXClientEndpoint
from twisted.web.client import Agent, FileBodyProducer
DOCKER_SOCKET = '/var/run/docker.sock'
class DockerAgent(Agent):
#def _getEndpoint(self, scheme, host, post):
def _getEndpoint(self, *args):
return UNIXClientEndpoint(self._reactor, DOCKER_SOCKET)
def dockerAPI(path, method=b'GET', reactor=None, **params):
if reactor is None:
from twisted.internet import reactor
if False and method.upper() == b'POST':
postdata = FileBodyProducer(StringIO(urllib.urlencode(params)))
else:
path += '?' + urllib.urlencode(params)
postdata = None
agent = DockerAgent(reactor)
return agent.request(method, path, bodyProducer=postdata)
@defer.inlineCallbacks
def main(reactor, path):
from twisted.internet.protocol import Protocol
class ResponsePrinter(Protocol):
def __init__(self):
self.finished = defer.Deferred()
def dataReceived(self, data):
print(data, end='')
print(self.transport)
def connectionLost(self, reason):
self.finished.callback(None)
# TODO: POST
response = yield dockerAPI(path)
printer = ResponsePrinter()
response.deliverBody(printer)
yield printer.finished
if __name__ == '__main__':
import sys
from twisted.internet.task import react
react(main, sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment