direct-io.hg

view tools/python/xen/xend/server/SrvDomain.py @ 12779:e98c84468b72

The new lifecycle patches in xen-unstable added 3 new operations which can
be performed on domains - new, start and delete. libvirt has had no-op
stub implementations of these APIs for a while & thus we'd enable their
use for Xen 3.0.4 builds. The new APIs are not currently exposed via the
existing SEXPR protocol, and since the new Xen-API protocol is unsupported
tech-preview for 3.0.4 we don't want to re-write against that just yet.

Thus the attached patch adds the 3 neccessary bindings for the SEXPR protocol
to allow the lifecycle functionality to be invoked. It also allows the 'state'
parameter to be specified when listing domains, so we can explicitly request
inactive domains if we know we're running against a 3.0.4 era XenD

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
author Ewan Mellor <ewan@xensource.com>
date Thu Dec 07 12:15:30 2006 +0000 (2006-12-07)
parents b80f00215bba
children bc3ff220d24d
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 ['resource', 'int'],
119 ['port', 'int']])
120 return fn(req.args, {'dom': self.dom.domid})
122 def op_pincpu(self, _, req):
123 fn = FormFn(self.xd.domain_pincpu,
124 [['dom', 'int'],
125 ['vcpu', 'str'],
126 ['cpumap', 'str']])
127 val = fn(req.args, {'dom': self.dom.domid})
128 return val
130 def op_cpu_sedf_get(self, _, req):
131 fn = FormFn(self.xd.domain_cpu_sedf_get,
132 [['dom', 'int']])
133 val = fn(req.args, {'dom': self.dom.domid})
134 return val
137 def op_cpu_sedf_set(self, _, req):
138 fn = FormFn(self.xd.domain_cpu_sedf_set,
139 [['dom', 'int'],
140 ['period', 'int'],
141 ['slice', 'int'],
142 ['latency', 'int'],
143 ['extratime', 'int'],
144 ['weight', 'int']])
145 val = fn(req.args, {'dom': self.dom.domid})
146 return val
148 def op_domain_sched_credit_get(self, _, req):
149 fn = FormFn(self.xd.domain_sched_credit_get,
150 [['dom', 'int']])
151 val = fn(req.args, {'dom': self.dom.domid})
152 return val
155 def op_domain_sched_credit_set(self, _, req):
156 fn = FormFn(self.xd.domain_sched_credit_set,
157 [['dom', 'int'],
158 ['weight', 'int']])
159 val = fn(req.args, {'dom': self.dom.domid})
160 return val
162 def op_maxmem_set(self, _, req):
163 fn = FormFn(self.xd.domain_maxmem_set,
164 [['dom', 'int'],
165 ['memory', 'int']])
166 val = fn(req.args, {'dom': self.dom.domid})
167 return val
170 def call(self, fn, args, req):
171 return FormFn(fn, args)(req.args)
174 def op_mem_target_set(self, _, req):
175 return self.call(self.dom.setMemoryTarget,
176 [['target', 'int']],
177 req)
179 def op_devices(self, _, req):
180 return self.call(self.dom.getDeviceSxprs,
181 [['type', 'str']],
182 req)
184 def op_device_create(self, _, req):
185 return self.call(self.dom.device_create,
186 [['config', 'sxpr']],
187 req)
189 def op_device_destroy(self, _, req):
190 return self.call(self.dom.destroyDevice,
191 [['type', 'str'],
192 ['dev', 'str']],
193 req)
195 def op_device_configure(self, _, req):
196 return self.call(self.dom.device_configure,
197 [['config', 'sxpr'],
198 ['dev', 'str']],
199 req)
202 def op_vif_limit_set(self, _, req):
203 fn = FormFn(self.xd.domain_vif_limit_set,
204 [['dom', 'int'],
205 ['vif', 'int'],
206 ['credit', 'int'],
207 ['period', 'int']])
208 val = fn(req.args, {'dom': self.dom.domid})
209 return val
211 def op_set_vcpus(self, _, req):
212 return self.call(self.dom.setVCpuCount,
213 [['vcpus', 'int']],
214 req)
217 def op_vcpuinfo(self, _1, req):
218 return self.call(self.dom.getVCPUInfo, [], req)
221 def render_POST(self, req):
222 return self.perform(req)
224 def render_GET(self, req):
225 op = req.args.get('op')
227 if op and op[0] in ['vcpuinfo']:
228 return self.perform(req)
230 #
231 # XXX SMH: below may be useful once again if we ever try to get
232 # the raw 'web' interface to xend working once more. But for now
233 # is useless and out of date (i.e. no ops called 'v???' anymore).
234 #
235 # if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']:
236 # return self.perform(req)
237 if self.use_sxp(req):
238 req.setHeader("Content-Type", sxp.mime_type)
239 sxp.show(self.dom.sxpr(), out=req)
240 else:
241 req.write('<html><head></head><body>')
242 self.print_path(req)
243 #self.ls()
244 req.write('<p>%s</p>' % self.dom)
245 self.form(req)
246 req.write('</body></html>')
247 return ''
249 def form(self, req):
250 url = req.prePathURL()
251 req.write('<form method="post" action="%s">' % url)
252 req.write('<input type="submit" name="op" value="unpause">')
253 req.write('<input type="submit" name="op" value="pause">')
254 req.write('</form>')
256 req.write('<form method="post" action="%s">' % url)
257 req.write('<input type="submit" name="op" value="destroy">')
258 req.write('</form>')
260 req.write('<form method="post" action="%s">' % url)
261 req.write('<input type="submit" name="op" value="shutdown">')
262 req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff')
263 req.write('<input type="radio" name="reason" value="halt">Halt')
264 req.write('<input type="radio" name="reason" value="reboot">Reboot')
265 req.write('</form>')
267 req.write('<form method="post" action="%s">' % url)
268 req.write('<br><input type="submit" name="op" value="save">')
269 req.write(' To file: <input type="text" name="file">')
270 req.write('</form>')
272 req.write('<form method="post" action="%s">' % url)
273 req.write('<br><input type="submit" name="op" value="migrate">')
274 req.write(' To host: <input type="text" name="destination">')
275 req.write('<input type="checkbox" name="live" value="1">Live')
276 req.write('</form>')