debuggers.hg

view tools/python/xen/xend/server/SrvDomain.py @ 4672:d781b9d08e80

bitkeeper revision 1.1327.2.4 (426918a34Af7gihN8mTkq-P3KrAZXg)

Remove twisted from save/migrate handling.
This needs to use threads, so add thread support for
http server requests.

Signed-off-by: Mike Wray <mike.wray@hp.com>
author mjw@wray-m-3.hpl.hp.com
date Fri Apr 22 15:30:43 2005 +0000 (2005-04-22)
parents a838a908e38e
children 369e382b2f81
line source
1 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
3 from xen.web import http
5 from xen.xend import sxp
6 from xen.xend import XendDomain
7 from xen.xend import XendConsole
8 from xen.xend import PrettyPrint
9 from xen.xend.Args import FormFn
11 from SrvDir import SrvDir
13 class SrvDomain(SrvDir):
14 """Service managing a single domain.
15 """
17 def __init__(self, dom):
18 SrvDir.__init__(self)
19 self.dom = dom
20 self.xd = XendDomain.instance()
21 self.xconsole = XendConsole.instance()
23 def op_configure(self, op, req):
24 """Configure an existing domain.
25 Configure is unusual in that it requires a domain id,
26 not a domain name.
27 """
28 fn = FormFn(self.xd.domain_configure,
29 [['dom', 'int'],
30 ['config', 'sxpr']])
31 return fn(req.args, {'dom': self.dom.dom})
33 def op_unpause(self, op, req):
34 val = self.xd.domain_unpause(self.dom.name)
35 return val
37 def op_pause(self, op, req):
38 # Pause doesn't need a thread, but request one for testing.
39 return req.threadRequest(self.do_pause, op, req)
41 def do_pause(self, op, req):
42 val = self.xd.domain_pause(self.dom.name)
43 return val
45 def op_shutdown(self, op, req):
46 fn = FormFn(self.xd.domain_shutdown,
47 [['dom', 'str'],
48 ['reason', 'str'],
49 ['key', 'int']])
50 val = fn(req.args, {'dom': self.dom.id})
51 req.setResponseCode(http.ACCEPTED)
52 req.setHeader("Location", "%s/.." % req.prePathURL())
53 return val
55 def op_destroy(self, op, req):
56 fn = FormFn(self.xd.domain_destroy,
57 [['dom', 'str'],
58 ['reason', 'str']])
59 val = fn(req.args, {'dom': self.dom.id})
60 req.setHeader("Location", "%s/.." % req.prePathURL())
61 return val
63 def op_save(self, op, req):
64 return req.threadRequest(self.do_save, op, req)
66 def do_save(self, op, req):
67 fn = FormFn(self.xd.domain_save,
68 [['dom', 'str'],
69 ['file', 'str']])
70 val = fn(req.args, {'dom': self.dom.id})
71 return 0
73 def op_migrate(self, op, req):
74 return req.threadRequest(self.do_migrate, op, req)
76 def do_migrate(self, op, req):
77 fn = FormFn(self.xd.domain_migrate,
78 [['dom', 'str'],
79 ['destination', 'str'],
80 ['live', 'int'],
81 ['resource', 'int']])
82 info = fn(req.args, {'dom': self.dom.id})
83 #req.setResponseCode(http.ACCEPTED)
84 host = info.dst_host
85 port = info.dst_port
86 dom = info.dst_dom
87 url = "http://%s:%d/xend/domain/%d" % (host, port, dom)
88 req.setHeader("Location", url)
89 print 'do_migrate> url=', url
90 return url
92 def op_pincpu(self, op, req):
93 fn = FormFn(self.xd.domain_pincpu,
94 [['dom', 'str'],
95 ['cpu', 'int']])
96 val = fn(req.args, {'dom': self.dom.id})
97 return val
99 def op_cpu_bvt_set(self, op, req):
100 fn = FormFn(self.xd.domain_cpu_bvt_set,
101 [['dom', 'str'],
102 ['mcuadv', 'int'],
103 ['warpback', 'int'],
104 ['warpvalue', 'int'],
105 ['warpl', 'long'],
106 ['warpu', 'long']])
107 val = fn(req.args, {'dom': self.dom.id})
108 return val
110 def op_maxmem_set(self, op, req):
111 fn = FormFn(self.xd.domain_maxmem_set,
112 [['dom', 'str'],
113 ['memory', 'int']])
114 val = fn(req.args, {'dom': self.dom.id})
115 return val
117 def op_device_create(self, op, req):
118 fn = FormFn(self.xd.domain_device_create,
119 [['dom', 'str'],
120 ['config', 'sxpr']])
121 val = fn(req.args, {'dom': self.dom.id})
122 return val
124 def op_device_refresh(self, op, req):
125 fn = FormFn(self.xd.domain_device_refresh,
126 [['dom', 'str'],
127 ['type', 'str'],
128 ['idx', 'str']])
129 val = fn(req.args, {'dom': self.dom.id})
130 return val
132 def op_device_destroy(self, op, req):
133 fn = FormFn(self.xd.domain_device_destroy,
134 [['dom', 'str'],
135 ['type', 'str'],
136 ['idx', 'str']])
137 val = fn(req.args, {'dom': self.dom.id})
138 return val
140 def op_device_configure(self, op, req):
141 fn = FormFn(self.xd.domain_device_configure,
142 [['dom', 'str'],
143 ['config', 'sxpr'],
144 ['idx', 'str']])
145 val = fn(req.args, {'dom': self.dom.id})
146 return val
148 def op_vif_credit_limit(self, op, req):
149 fn = FormFn(self.xd.domain_vif_credit_limit,
150 [['dom', 'str'],
151 ['vif', 'int'],
152 ['credit', 'int'],
153 ['period', 'int']])
154 val = fn(req.args, {'dom': self.dom.id})
155 return val
157 def op_vifs(self, op, req):
158 devs = self.xd.domain_vif_ls(self.dom.id)
159 return [ dev.sxpr() for dev in devs ]
161 def op_vif(self, op, req):
162 fn = FormFn(self.xd.domain_vif_get,
163 [['dom', 'str'],
164 ['vif', 'str']])
165 val = fn(req.args, {'dom': self.dom.id})
166 return val
168 def op_vbds(self, op, req):
169 devs = self.xd.domain_vbd_ls(self.dom.id)
170 return [ dev.sxpr() for dev in devs ]
172 def op_vbd(self, op, req):
173 fn = FormFn(self.xd.domain_vbd_get,
174 [['dom', 'str'],
175 ['vbd', 'str']])
176 val = fn(req.args, {'dom': self.dom.id})
177 return val
179 def op_mem_target_set(self, op, req):
180 fn = FormFn(self.xd.domain_mem_target_set,
181 [['dom', 'str'],
182 ['target', 'int']])
183 val = fn(req.args, {'dom': self.dom.id})
184 return val
186 def render_POST(self, req):
187 return self.perform(req)
189 def render_GET(self, req):
190 op = req.args.get('op')
191 if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']:
192 return self.perform(req)
193 if self.use_sxp(req):
194 req.setHeader("Content-Type", sxp.mime_type)
195 sxp.show(self.dom.sxpr(), out=req)
196 else:
197 req.write('<html><head></head><body>')
198 self.print_path(req)
199 #self.ls()
200 req.write('<p>%s</p>' % self.dom)
201 if self.dom.console:
202 cinfo = self.dom.console
203 cid = str(cinfo.console_port)
204 #todo: Local xref: need to know server prefix.
205 req.write('<p><a href="/xend/console/%s">Console %s</a></p>'
206 % (cid, cid))
207 req.write('<p><a href="%s">Connect to console</a></p>'
208 % cinfo.uri())
209 if self.dom.config:
210 req.write("<code><pre>")
211 PrettyPrint.prettyprint(self.dom.config, out=req)
212 req.write("</pre></code>")
213 self.form(req)
214 req.write('</body></html>')
215 return ''
217 def form(self, req):
218 url = req.prePathURL()
219 req.write('<form method="post" action="%s">' % url)
220 req.write('<input type="submit" name="op" value="unpause">')
221 req.write('<input type="submit" name="op" value="pause">')
222 req.write('</form>')
224 req.write('<form method="post" action="%s">' % url)
225 req.write('<input type="submit" name="op" value="destroy">')
226 req.write('<input type="radio" name="reason" value="halt" checked>Halt')
227 req.write('<input type="radio" name="reason" value="reboot">Reboot')
228 req.write('</form>')
230 req.write('<form method="post" action="%s">' % url)
231 req.write('<input type="submit" name="op" value="shutdown">')
232 req.write('<input type="radio" name="reason" value="poweroff" checked>Poweroff')
233 req.write('<input type="radio" name="reason" value="halt">Halt')
234 req.write('<input type="radio" name="reason" value="reboot">Reboot')
235 req.write('</form>')
237 req.write('<form method="post" action="%s">' % url)
238 req.write('<br><input type="submit" name="op" value="save">')
239 req.write(' To file: <input type="text" name="file">')
240 req.write('</form>')
242 req.write('<form method="post" action="%s">' % url)
243 req.write('<br><input type="submit" name="op" value="migrate">')
244 req.write(' To host: <input type="text" name="destination">')
245 req.write('<input type="checkbox" name="live" value="1">Live')
246 req.write('</form>')