ia64/xen-unstable

view tools/python/xen/xend/server/SrvDomain.py @ 17757:6f48c4ee8ae2

xend: Add node parameter to do_migrate() for HTTP interface
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 29 13:38:31 2008 +0100 (2008-05-29)
parents 9df61d6601ba
children 3c1a88dc6fbe
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) 2005 Xensource Ltd
17 #============================================================================
19 from xen.web import http
21 from xen.xend import sxp
22 from xen.xend import XendDomain
23 from xen.xend.Args import FormFn
24 from xen.xend.XendLogging import log
26 from xen.web.SrvDir import SrvDir
28 class SrvDomain(SrvDir):
29 """Service managing a single domain.
30 """
32 def __init__(self, dom):
33 SrvDir.__init__(self)
34 self.dom = dom
35 self.xd = XendDomain.instance()
37 def op_configure(self, _, req):
38 """Configure an existing domain.
39 Configure is unusual in that it requires a domain id,
40 not a domain name.
41 """
42 fn = FormFn(self.xd.domain_configure,
43 [['dom', 'int'],
44 ['config', 'sxpr']])
45 return fn(req.args, {'dom': self.dom.domid})
47 def op_unpause(self, _1, _2):
48 val = self.xd.domain_unpause(self.dom.domid)
49 return val
51 def op_pause(self, _1, _2):
52 val = self.xd.domain_pause(self.dom.domid)
53 return val
55 def acceptCommand(self, req):
56 req.setResponseCode(http.ACCEPTED)
57 req.setHeader("Location", "%s/.." % req.prePathURL())
59 def op_rename(self, _, req):
60 self.acceptCommand(req)
61 return self.dom.setName(req.args['name'][0])
63 def op_shutdown(self, _, req):
64 self.acceptCommand(req)
65 return self.dom.shutdown(req.args['reason'][0])
67 def op_delete(self, _, req):
68 self.acceptCommand(req)
69 return self.xd.domain_delete(self.dom.getName())
71 def op_start(self, _, req):
72 self.acceptCommand(req)
73 paused = False
74 if 'paused' in req.args and req.args['paused'] == [1]:
75 paused = True
76 log.debug("Starting domain " + self.dom.getName() + " " + str(paused))
77 return self.xd.domain_start(self.dom.getName(), paused)
79 def op_sysrq(self, _, req):
80 self.acceptCommand(req)
81 return self.dom.send_sysrq(int(req.args['key'][0]))
83 def op_wait_for_devices(self, _, req):
84 self.acceptCommand(req)
85 return self.dom.waitForDevices()
87 def op_destroy(self, _, req):
88 self.acceptCommand(req)
89 return self.xd.domain_destroy(self.dom.domid)
91 def op_save(self, op, req):
92 self.acceptCommand(req)
93 return req.threadRequest(self.do_save, op, req)
95 def do_save(self, _, req):
96 return self.xd.domain_save(self.dom.domid, req.args['file'][0])
98 def op_dump(self, op, req):
99 self.acceptCommand(req)
100 return req.threadRequest(self.do_dump, op, req)
102 def do_dump(self, _, req):
103 fn = FormFn(self.xd.domain_dump,
104 [['dom', 'int'],
105 ['file', 'str'],
106 ['live', 'int'],
107 ['crash', 'int']])
108 return fn(req.args, {'dom': self.dom.domid})
110 def op_migrate(self, op, req):
111 return req.threadRequest(self.do_migrate, op, req)
113 def do_migrate(self, _, req):
114 fn = FormFn(self.xd.domain_migrate,
115 [['dom', 'int'],
116 ['destination', 'str'],
117 ['live', 'int'],
118 ['port', 'int'],
119 ['node', 'int'],
120 ['ssl', 'int']])
121 return fn(req.args, {'dom': self.dom.domid})
123 def op_pincpu(self, _, req):
124 fn = FormFn(self.xd.domain_pincpu,
125 [['dom', 'str'],
126 ['vcpu', 'str'],
127 ['cpumap', 'str']])
128 val = fn(req.args, {'dom': self.dom.getName()})
129 return val
131 def op_cpu_sedf_get(self, _, req):
132 fn = FormFn(self.xd.domain_cpu_sedf_get,
133 [['dom', 'int']])
134 val = fn(req.args, {'dom': self.dom.domid})
135 return val
138 def op_cpu_sedf_set(self, _, req):
139 fn = FormFn(self.xd.domain_cpu_sedf_set,
140 [['dom', 'int'],
141 ['period', 'int'],
142 ['slice', 'int'],
143 ['latency', 'int'],
144 ['extratime', 'int'],
145 ['weight', 'int']])
146 val = fn(req.args, {'dom': self.dom.domid})
147 return val
149 def op_domain_sched_credit_get(self, _, req):
150 fn = FormFn(self.xd.domain_sched_credit_get,
151 [['dom', 'str']])
152 val = fn(req.args, {'dom': self.dom.getName()})
153 return val
156 def op_domain_sched_credit_set(self, _, req):
157 fn = FormFn(self.xd.domain_sched_credit_set,
158 [['dom', 'str'],
159 ['weight', 'int'],
160 ['cap', 'int']])
161 val = fn(req.args, {'dom': self.dom.getName()})
162 return val
164 def op_maxmem_set(self, _, req):
165 return self.call(self.dom.setMemoryMaximum,
166 [['memory', 'int']],
167 req)
169 def call(self, fn, args, req):
170 return FormFn(fn, args)(req.args)
173 def op_mem_target_set(self, _, req):
174 return self.call(self.dom.setMemoryTarget,
175 [['target', 'int']],
176 req)
178 def op_devices(self, _, req):
179 return self.call(self.dom.getDeviceSxprs,
180 [['type', 'str']],
181 req)
183 def op_device_create(self, _, req):
184 return self.call(self.dom.device_create,
185 [['config', 'sxpr']],
186 req)
188 def op_device_destroy(self, _, req):
189 return self.call(self.dom.destroyDevice,
190 [['type', 'str'],
191 ['dev', 'str'],
192 ['force', 'int'],
193 ['rm_cfg', 'int']],
194 req)
196 def op_device_configure(self, _, req):
197 return self.call(self.dom.device_configure,
198 [['config', 'sxpr'],
199 ['dev', 'str']],
200 req)
203 def op_vif_limit_set(self, _, req):
204 fn = FormFn(self.xd.domain_vif_limit_set,
205 [['dom', 'int'],
206 ['vif', 'int'],
207 ['credit', 'int'],
208 ['period', 'int']])
209 val = fn(req.args, {'dom': self.dom.domid})
210 return val
212 def op_set_vcpus(self, _, req):
213 return self.call(self.dom.setVCpuCount,
214 [['vcpus', 'int']],
215 req)
218 def op_vcpuinfo(self, _1, req):
219 return self.call(self.dom.getVCPUInfo, [], req)
222 def op_reset(self, _, req):
223 self.acceptCommand(req)
224 return self.xd.domain_reset(self.dom.getName())
227 def render_POST(self, req):
228 return self.perform(req)
230 def render_GET(self, req):
231 op = req.args.get('op')
233 if op and op[0] in ['vcpuinfo']:
234 return self.perform(req)
236 #
237 # XXX SMH: below may be useful once again if we ever try to get
238 # the raw 'web' interface to xend working once more. But for now
239 # is useless and out of date (i.e. no ops called 'v???' anymore).
240 #
241 # if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']:
242 # return self.perform(req)
243 if self.use_sxp(req):
244 req.setHeader("Content-Type", sxp.mime_type)
245 sxp.show(self.dom.sxpr(), out=req)
246 else:
247 req.write('<html><head></head><body>')
248 self.print_path(req)
249 #self.ls()
250 req.write('<p>%s</p>' % self.dom)
251 self.form(req)
252 req.write('</body></html>')
253 return ''
255 def form(self, req):
256 url = req.prePathURL()
257 req.write('<form method="post" action="%s">' % url)
258 req.write('<input type="submit" name="op" value="unpause">')
259 req.write('<input type="submit" name="op" value="pause">')
260 req.write('</form>')
262 req.write('<form method="post" action="%s">' % url)
263 req.write('<input type="submit" name="op" value="destroy">')
264 req.write('</form>')
266 req.write('<form method="post" action="%s">' % url)
267 req.write('<input type="submit" name="op" value="reset">')
268 req.write('</form>')
270 req.write('<form method="post" action="%s">' % url)
271 req.write('<input type="submit" name="op" value="shutdown">')
272 req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff')
273 req.write('<input type="radio" name="reason" value="halt">Halt')
274 req.write('<input type="radio" name="reason" value="reboot">Reboot')
275 req.write('</form>')
277 req.write('<form method="post" action="%s">' % url)
278 req.write('<br><input type="submit" name="op" value="save">')
279 req.write(' To file: <input type="text" name="file">')
280 req.write('</form>')
282 req.write('<form method="post" action="%s">' % url)
283 req.write('<br><input type="submit" name="op" value="migrate">')
284 req.write(' To host: <input type="text" name="destination">')
285 req.write('<input type="checkbox" name="live" value="1">Live')
286 req.write('</form>')