summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/server/xmlrpc.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/server/xmlrpc.py')
-rw-r--r--bitbake/lib/bb/server/xmlrpc.py187
1 files changed, 187 insertions, 0 deletions
diff --git a/bitbake/lib/bb/server/xmlrpc.py b/bitbake/lib/bb/server/xmlrpc.py
new file mode 100644
index 0000000000..3364918c77
--- /dev/null
+++ b/bitbake/lib/bb/server/xmlrpc.py
@@ -0,0 +1,187 @@
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, sys
36from bb import daemonize
37from bb.ui import uievent
38
39DEBUG = False
40
41from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
42import inspect, select
43
44if sys.hexversion < 0x020600F0:
45 print "Sorry, python 2.6 or later is required for bitbake's XMLRPC mode"
46 sys.exit(1)
47
48class BitBakeServerCommands():
49 def __init__(self, server, cooker):
50 self.cooker = cooker
51 self.server = server
52
53 def registerEventHandler(self, host, port):
54 """
55 Register a remote UI Event Handler
56 """
57 s = xmlrpclib.Server("http://%s:%d" % (host, port), allow_none=True)
58 return bb.event.register_UIHhandler(s)
59
60 def unregisterEventHandler(self, handlerNum):
61 """
62 Unregister a remote UI Event Handler
63 """
64 return bb.event.unregister_UIHhandler(handlerNum)
65
66 def runCommand(self, command):
67 """
68 Run a cooker command on the server
69 """
70 return self.cooker.command.runCommand(command)
71
72 def terminateServer(self):
73 """
74 Trigger the server to quit
75 """
76 self.server.quit = True
77 print "Server (cooker) exitting"
78 return
79
80 def ping(self):
81 """
82 Dummy method which can be used to check the server is still alive
83 """
84 return True
85
86class BitBakeServer(SimpleXMLRPCServer):
87 # remove this when you're done with debugging
88 # allow_reuse_address = True
89
90 def __init__(self, cooker, interface = ("localhost", 0)):
91 """
92 Constructor
93 """
94 SimpleXMLRPCServer.__init__(self, interface,
95 requestHandler=SimpleXMLRPCRequestHandler,
96 logRequests=False, allow_none=True)
97 self._idlefuns = {}
98 self.host, self.port = self.socket.getsockname()
99 #self.register_introspection_functions()
100 commands = BitBakeServerCommands(self, cooker)
101 self.autoregister_all_functions(commands, "")
102
103 def autoregister_all_functions(self, context, prefix):
104 """
105 Convenience method for registering all functions in the scope
106 of this class that start with a common prefix
107 """
108 methodlist = inspect.getmembers(context, inspect.ismethod)
109 for name, method in methodlist:
110 if name.startswith(prefix):
111 self.register_function(method, name[len(prefix):])
112
113 def register_idle_function(self, function, data):
114 """Register a function to be called while the server is idle"""
115 assert callable(function)
116 self._idlefuns[function] = data
117
118 def serve_forever(self):
119 """
120 Serve Requests. Overloaded to honor a quit command
121 """
122 self.quit = False
123 self.timeout = 0 # Run Idle calls for our first callback
124 while not self.quit:
125 #print "Idle queue length %s" % len(self._idlefuns)
126 self.handle_request()
127 #print "Idle timeout, running idle functions"
128 nextsleep = None
129 for function, data in self._idlefuns.items():
130 try:
131 retval = function(self, data, False)
132 if retval is False:
133 del self._idlefuns[function]
134 elif retval is True:
135 nextsleep = 0
136 elif nextsleep is 0:
137 continue
138 elif nextsleep is None:
139 nextsleep = retval
140 elif retval < nextsleep:
141 nextsleep = retval
142 except SystemExit:
143 raise
144 except:
145 import traceback
146 traceback.print_exc()
147 pass
148 if nextsleep is None and len(self._idlefuns) > 0:
149 nextsleep = 0
150 self.timeout = nextsleep
151 # Tell idle functions we're exiting
152 for function, data in self._idlefuns.items():
153 try:
154 retval = function(self, data, True)
155 except:
156 pass
157
158 self.server_close()
159 return
160
161class BitbakeServerInfo():
162 def __init__(self, server):
163 self.host = server.host
164 self.port = server.port
165
166class BitBakeServerFork():
167 def __init__(self, serverinfo, command, logfile):
168 daemonize.createDaemon(command, logfile)
169
170class BitBakeServerConnection():
171 def __init__(self, serverinfo):
172 self.connection = xmlrpclib.Server("http://%s:%s" % (serverinfo.host, serverinfo.port), allow_none=True)
173 self.events = uievent.BBUIEventQueue(self.connection)
174
175 def terminate(self):
176 # Don't wait for server indefinitely
177 import socket
178 socket.setdefaulttimeout(2)
179 try:
180 self.events.system_quit()
181 except:
182 pass
183 try:
184 self.connection.terminateServer()
185 except:
186 pass
187