summaryrefslogtreecommitdiffstats
path: root/bitbake-dev/lib/bb/xmlrpcserver.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake-dev/lib/bb/xmlrpcserver.py')
-rw-r--r--bitbake-dev/lib/bb/xmlrpcserver.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/bitbake-dev/lib/bb/xmlrpcserver.py b/bitbake-dev/lib/bb/xmlrpcserver.py
new file mode 100644
index 0000000000..075eda0573
--- /dev/null
+++ b/bitbake-dev/lib/bb/xmlrpcserver.py
@@ -0,0 +1,157 @@
1#
2# BitBake XMLRPC Server
3#
4# Copyright (C) 2006 - 2007 Michael 'Mickey' Lauer
5# Copyright (C) 2006 - 2008 Richard Purdie
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20"""
21 This module implements an xmlrpc server for BitBake.
22
23 Use this by deriving a class from BitBakeXMLRPCServer and then adding
24 methods which you want to "export" via XMLRPC. If the methods have the
25 prefix xmlrpc_, then registering those function will happen automatically,
26 if not, you need to call register_function.
27
28 Use register_idle_function() to add a function which the xmlrpc server
29 calls from within server_forever when no requests are pending. Make sure
30 that those functions are non-blocking or else you will introduce latency
31 in the server's main loop.
32"""
33
34import bb
35import xmlrpclib
36
37DEBUG = False
38
39from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
40import os, sys, inspect, select
41
42class BitBakeServerCommands():
43 def __init__(self, server, cooker):
44 self.cooker = cooker
45 self.server = server
46
47 def registerEventHandler(self, host, port):
48 """
49 Register a remote UI Event Handler
50 """
51 s = xmlrpclib.Server("http://%s:%d" % (host, port), allow_none=True)
52 return bb.event.register_UIHhandler(s)
53
54 def unregisterEventHandler(self, handlerNum):
55 """
56 Unregister a remote UI Event Handler
57 """
58 return bb.event.unregister_UIHhandler(handlerNum)
59
60 def runCommand(self, command):
61 """
62 Run a cooker command on the server
63 """
64 return self.cooker.command.runCommand(command)
65
66 def terminateServer(self):
67 """
68 Trigger the server to quit
69 """
70 self.server.quit = True
71 print "Server (cooker) exitting"
72 return
73
74 def ping(self):
75 """
76 Dummy method which can be used to check the server is still alive
77 """
78 return True
79
80class BitBakeXMLRPCServer(SimpleXMLRPCServer):
81 # remove this when you're done with debugging
82 # allow_reuse_address = True
83
84 def __init__(self, cooker, interface = ("localhost", 0)):
85 """
86 Constructor
87 """
88 SimpleXMLRPCServer.__init__(self, interface,
89 requestHandler=SimpleXMLRPCRequestHandler,
90 logRequests=False, allow_none=True)
91 self._idlefuns = {}
92 self.host, self.port = self.socket.getsockname()
93 #self.register_introspection_functions()
94 commands = BitBakeServerCommands(self, cooker)
95 self.autoregister_all_functions(commands, "")
96
97 def autoregister_all_functions(self, context, prefix):
98 """
99 Convenience method for registering all functions in the scope
100 of this class that start with a common prefix
101 """
102 methodlist = inspect.getmembers(context, inspect.ismethod)
103 for name, method in methodlist:
104 if name.startswith(prefix):
105 self.register_function(method, name[len(prefix):])
106
107 def register_idle_function(self, function, data):
108 """Register a function to be called while the server is idle"""
109 assert callable(function)
110 self._idlefuns[function] = data
111
112 def serve_forever(self):
113 """
114 Serve Requests. Overloaded to honor a quit command
115 """
116 self.quit = False
117 while not self.quit:
118 self.handle_request()
119
120 # Tell idle functions we're exiting
121 for function, data in self._idlefuns.items():
122 try:
123 retval = function(self, data, True)
124 except:
125 pass
126
127 self.server_close()
128 return
129
130 def get_request(self):
131 """
132 Get next request. Behaves like the parent class unless a waitpid callback
133 has been set. In that case, we regularly check waitpid when the server is idle
134 """
135 while True:
136 # wait 500 ms for an xmlrpc request
137 if DEBUG:
138 print "DEBUG: select'ing 500ms waiting for an xmlrpc request..."
139 ifds, ofds, xfds = select.select([self.socket.fileno()], [], [], 0.5)
140 if ifds:
141 return self.socket.accept()
142 # call idle functions only if we're not shutting down atm to prevent a recursion
143 if not self.quit:
144 if DEBUG:
145 print "DEBUG: server is idle -- calling idle functions..."
146 for function, data in self._idlefuns.items():
147 try:
148 retval = function(self, data, False)
149 if not retval:
150 del self._idlefuns[function]
151 except SystemExit:
152 raise
153 except:
154 import traceback
155 traceback.print_exc()
156 pass
157