ia64/xen-unstable

view tools/python/xen/xend/server/SrvServer.py @ 13642:ba3ec84c9423

[XEND] Add missing ConsoleController.py

Signed-off-by: Alastair Tse <atse@xensource.com>
author Alastair Tse <atse@xensource.com>
date Fri Jan 26 02:44:35 2007 +0000 (2007-01-26)
parents ee1febe317f7
children ea68ae90fc10
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 # Copyright (C) 2006 XenSource Ltd.
17 #============================================================================
19 """Example xend HTTP
21 Can be accessed from a browser or from a program.
22 Do 'python SrvServer.py' to run the server.
23 Then point a web browser at http://localhost:8000/xend and follow the links.
24 Most are stubs, except /domain which has a list of domains and a 'create domain'
25 button.
27 You can also access the server from a program.
28 Do 'python XendClient.py' to run a few test operations.
30 The data served differs depending on the client (as defined by User-Agent
31 and Accept in the HTTP headers). If the client is a browser, data
32 is returned in HTML, with interactive forms. If the client is a program,
33 data is returned in SXP format, with no forms.
35 The server serves to the world by default. To restrict it to the local host
36 change 'interface' in main().
38 Mike Wray <mike.wray@hp.com>
39 """
40 # todo Support security settings etc. in the config file.
41 # todo Support command-line args.
43 import fcntl
44 import re
45 import time
46 import signal
47 from threading import Thread
49 from xen.web.httpserver import HttpServer, UnixHttpServer
51 from xen.xend import XendNode, XendOptions, XendAPI
52 from xen.xend import Vifctl
53 from xen.xend.XendLogging import log
54 from xen.xend.XendClient import XEN_API_SOCKET
55 from xen.web.SrvDir import SrvDir
57 from SrvRoot import SrvRoot
58 from XMLRPCServer import XMLRPCServer
60 xoptions = XendOptions.instance()
63 class XendServers:
65 def __init__(self, root):
66 self.servers = []
67 self.root = root
68 self.running = False
69 self.cleaningUp = False
70 self.reloadingConfig = False
72 def add(self, server):
73 self.servers.append(server)
75 def cleanup(self, signum = 0, frame = None):
76 log.debug("SrvServer.cleanup()")
77 self.cleaningUp = True
78 for server in self.servers:
79 try:
80 server.shutdown()
81 except:
82 pass
83 self.running = False
85 def reloadConfig(self, signum = 0, frame = None):
86 log.debug("SrvServer.reloadConfig()")
87 self.reloadingConfig = True
88 self.cleanup(signum, frame)
90 def start(self, status):
91 # Running the network script will spawn another process, which takes
92 # the status fd with it unless we set FD_CLOEXEC. Failing to do this
93 # causes the read in SrvDaemon to hang even when we have written here.
94 if status:
95 fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC)
97 Vifctl.network('start')
99 # Prepare to catch SIGTERM (received when 'xend stop' is executed)
100 # and call each server's cleanup if possible
101 signal.signal(signal.SIGTERM, self.cleanup)
102 signal.signal(signal.SIGHUP, self.reloadConfig)
104 while True:
105 XendNode.instance().refreshBridges()
107 threads = []
108 for server in self.servers:
109 if server.ready:
110 continue
112 thread = Thread(target=server.run,
113 name=server.__class__.__name__)
114 thread.setDaemon(True)
115 thread.start()
116 threads.append(thread)
118 # check for when all threads have initialized themselves and then
119 # close the status pipe
121 retryCount = 0
122 threads_left = True
123 while threads_left:
124 threads_left = False
126 for server in self.servers:
127 if not server.ready:
128 threads_left = True
129 break
131 if threads_left:
132 time.sleep(.5)
133 retryCount += 1
134 if retryCount > 60:
135 for server in self.servers:
136 if not server.ready:
137 log.error("Server " +
138 server.__class__.__name__ +
139 " did not initialise!")
140 break
142 if status:
143 status.write('0')
144 status.close()
145 status = None
147 # loop to keep main thread alive until it receives a SIGTERM
148 self.running = True
149 while self.running:
150 time.sleep(100000000)
152 if self.reloadingConfig:
153 log.info("Restarting all XML-RPC and Xen-API servers...")
154 self.cleaningUp = False
155 self.reloadingConfig = False
156 xoptions.set_config()
157 self.servers = []
158 _loadConfig(self, self.root, True)
159 else:
160 break
162 def _loadConfig(servers, root, reload):
163 if xoptions.get_xend_http_server():
164 servers.add(HttpServer(root,
165 xoptions.get_xend_address(),
166 xoptions.get_xend_port()))
167 if xoptions.get_xend_unix_server():
168 path = xoptions.get_xend_unix_path()
169 log.info('unix path=' + path)
170 servers.add(UnixHttpServer(root, path))
172 api_cfg = xoptions.get_xen_api_server()
173 if api_cfg:
174 try:
175 addrs = [(str(x[0]).split(':'),
176 len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
177 len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
178 or None)
179 for x in api_cfg]
180 for addrport, auth, allowed in addrs:
181 if auth not in [XendAPI.AUTH_PAM, XendAPI.AUTH_NONE]:
182 log.error('Xen-API server configuration %s is invalid, ' +
183 'as %s is not a valid authentication type.',
184 api_cfg, auth)
185 break
187 if len(addrport) == 1:
188 if addrport[0] == 'unix':
189 servers.add(XMLRPCServer(auth, True,
190 path = XEN_API_SOCKET,
191 hosts_allowed = allowed))
192 else:
193 servers.add(
194 XMLRPCServer(auth, True, True, '',
195 int(addrport[0]),
196 hosts_allowed = allowed))
197 else:
198 addr, port = addrport
199 servers.add(XMLRPCServer(auth, True, True, addr,
200 int(port),
201 hosts_allowed = allowed))
202 except (ValueError, TypeError), exn:
203 log.exception('Xen API Server init failed')
204 log.error('Xen-API server configuration %s is invalid.', api_cfg)
206 if xoptions.get_xend_tcp_xmlrpc_server():
207 addr = xoptions.get_xend_tcp_xmlrpc_server_address()
208 port = xoptions.get_xend_tcp_xmlrpc_server_port()
209 servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, use_tcp = True,
210 host = addr, port = port))
212 if xoptions.get_xend_unix_xmlrpc_server():
213 servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
216 def create():
217 root = SrvDir()
218 root.putChild('xend', SrvRoot())
219 servers = XendServers(root)
220 _loadConfig(servers, root, False)
221 return servers