diff options
author | Alexandru DAMIAN <alexandru.damian@intel.com> | 2013-05-28 13:55:09 +0000 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-05-30 10:44:00 +0100 |
commit | 0fc3a1eddfbab5cbf61c028cf8bc0d6b27b6c420 (patch) | |
tree | 7ad43bd30a1d39a4968debc06d728cd03d79bd5e /bitbake | |
parent | b6b30095de0f5549a6cd3526170c70f39e803de6 (diff) | |
download | ast2050-yocto-poky-0fc3a1eddfbab5cbf61c028cf8bc0d6b27b6c420.zip ast2050-yocto-poky-0fc3a1eddfbab5cbf61c028cf8bc0d6b27b6c420.tar.gz |
bitbake: bitbake: xmlrpc transport has identification token
In order to be able to identify different clients over a
stateless XMLRPC connection, we add a custom header named
Bitbake-token, which identifies each client.
We refactor the rest of the code to use the new transport.
Based on a patch by Bogdan Marinescu <bogdan.a.marinescu@intel.com>
(Bitbake rev: a00c2186bffe848a7cedf31969b904f8f7322ae6)
Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/server/xmlrpc.py | 166 |
1 files changed, 100 insertions, 66 deletions
diff --git a/bitbake/lib/bb/server/xmlrpc.py b/bitbake/lib/bb/server/xmlrpc.py index ca3a401..e9c106b 100644 --- a/bitbake/lib/bb/server/xmlrpc.py +++ b/bitbake/lib/bb/server/xmlrpc.py @@ -54,82 +54,104 @@ if sys.hexversion < 0x020600F0: # Upstream Python bug is #8194 (http://bugs.python.org/issue8194) # This bug is relevant for Python 2.7.0 and 2.7.1 but was fixed for # Python > 2.7.2 +# +# To implement a simple form of client control, we use a special transport +# that adds a HTTP header field ("Bitbake-token") to ensure that a server +# can communicate with only a client at a given time (the client must use +# the same token). ## +if (2, 7, 0) <= sys.version_info < (2, 7, 2): + class BBTransport(xmlrpclib.Transport): + def __init__(self): + self.connection_token = None + xmlrpclib.Transport.__init__(self) + + def request(self, host, handler, request_body, verbose=0): + h = self.make_connection(host) + if verbose: + h.set_debuglevel(1) + + self.send_request(h, handler, request_body) + self.send_host(h, host) + self.send_user_agent(h) + if self.connection_token: + h.putheader("Bitbake-token", self.connection_token) + self.send_content(h, request_body) + + errcode, errmsg, headers = h.getreply() + + if errcode != 200: + raise ProtocolError( + host + handler, + errcode, errmsg, + headers + ) + + self.verbose = verbose -class BBTransport(xmlrpclib.Transport): - def request(self, host, handler, request_body, verbose=0): - h = self.make_connection(host) - if verbose: - h.set_debuglevel(1) - - self.send_request(h, handler, request_body) - self.send_host(h, host) - self.send_user_agent(h) - self.send_content(h, request_body) - - errcode, errmsg, headers = h.getreply() - - if errcode != 200: - raise ProtocolError( - host + handler, - errcode, errmsg, - headers - ) - - self.verbose = verbose - - try: - sock = h._conn.sock - except AttributeError: - sock = None - - return self._parse_response(h.getfile(), sock) - - def make_connection(self, host): - import httplib - host, extra_headers, x509 = self.get_host_info(host) - return httplib.HTTP(host) - - def _parse_response(self, file, sock): - p, u = self.getparser() - - while 1: - if sock: - response = sock.recv(1024) - else: - response = file.read(1024) - if not response: - break - if self.verbose: - print("body:", repr(response)) - p.feed(response) - - file.close() - p.close() - - return u.close() + try: + sock = h._conn.sock + except AttributeError: + sock = None + + return self._parse_response(h.getfile(), sock) + + def make_connection(self, host): + import httplib + host, extra_headers, x509 = self.get_host_info(host) + return httplib.HTTP(host) + + def _parse_response(self, file, sock): + p, u = self.getparser() + + while 1: + if sock: + response = sock.recv(1024) + else: + response = file.read(1024) + if not response: + break + if self.verbose: + print("body:", repr(response)) + p.feed(response) + + file.close() + p.close() + + return u.close() + + def set_connection_token(self, token): + self.connection_token = token +else: + class BBTransport(xmlrpclib.Transport): + def __init__(self): + self.connection_token = None + xmlrpclib.Transport.__init__(self) + + def set_connection_token(self, token): + self.connection_token = token + + def send_content(self, h, body): + if self.connection_token: + h.putheader("Bitbake-token", self.connection_token) + xmlrpclib.Transport.send_content(self, h, body) def _create_server(host, port): - # Python 2.7.0 and 2.7.1 have a buggy Transport implementation - # For those versions of Python, and only those versions, use our - # own copy/paste BBTransport class. - if (2, 7, 0) <= sys.version_info < (2, 7, 2): - t = BBTransport() - s = xmlrpclib.Server("http://%s:%d/" % (host, port), transport=t, allow_none=True) - else: - s = xmlrpclib.Server("http://%s:%d/" % (host, port), allow_none=True) - - return s + t = BBTransport() + s = xmlrpclib.Server("http://%s:%d/" % (host, port), transport=t, allow_none=True) + return s, t class BitBakeServerCommands(): + def __init__(self, server): self.server = server + self.has_client = False def registerEventHandler(self, host, port): """ Register a remote UI Event Handler """ - s = _create_server(host, port) + s, t = _create_server(host, port) return bb.event.register_UIHhandler(s) @@ -248,10 +270,22 @@ class BitbakeServerInfo(): class BitBakeServerConnection(): def __init__(self, serverinfo, clientinfo=("localhost", 0)): - self.connection = _create_server(serverinfo.host, serverinfo.port) - self.events = uievent.BBUIEventQueue(self.connection, clientinfo) + self.connection, self.transport = _create_server(serverinfo.host, serverinfo.port) + self.clientinfo = clientinfo + self.serverinfo = serverinfo + + def connect(self): + token = self.connection.addClient() + if token is None: + return None + self.transport.set_connection_token(token) + self.events = uievent.BBUIEventQueue(self.connection, self.clientinfo) for event in bb.event.ui_queue: self.events.queue_event(event) + return self + + def removeClient(self): + self.connection.removeClient() def terminate(self): # Don't wait for server indefinitely @@ -277,7 +311,7 @@ class BitBakeServer(object): def getServerIdleCB(self): return self.server.register_idle_function - def saveConnectionDetails(self): + def saveConnectionDetails(self): self.serverinfo = BitbakeServerInfo(self.server.host, self.server.port) def detach(self): |