ia64/xen-unstable

view tools/python/xen/xm/xenapi_create.py @ 19721:2c172f9db417

xm: xen-api, pass-through: create: Use vslot for hotplug_slot

Using func for hotplug_slot is not correct, although func is often
zero, previously zero meant please pick a vslot and asking xend to
pick a vslot was the only method available.

This resolves the following error when using Xen API:
$ xm create hvm.conf
...
Internal error: Timed out waiting for device model action.

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:41:50 2009 +0100 (2009-06-04)
parents a3125a83e40b
children 0573bbe19499
line source
1 #!/usr/bin/python
2 #============================================================================
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of version 2.1 of the GNU Lesser General Public
5 # License as published by the Free Software Foundation.
6 #
7 # This library is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 # Lesser General Public License for more details.
11 #
12 # You should have received a copy of the GNU Lesser General Public
13 # License along with this library; if not, write to the Free Software
14 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 #============================================================================
16 # Copyright (C) 2007 Tom Wilkie <tom.wilkie@gmail.com>
17 #============================================================================
18 """Domain creation using new XenAPI
19 """
21 from xen.xm.main import server, get_default_SR
22 from xml.dom.minidom import parse, getDOMImplementation
23 from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
24 from xen.xend import sxp
25 from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
26 XEN_API_ON_CRASH_BEHAVIOUR
27 from xen.xm.opts import OptionError
28 from xen.util import xsconstants
29 from xen.util.path import SHAREDIR
30 import xen.util.xsm.xsm as security
32 import sys
33 import os
34 from os.path import join
35 import traceback
36 import re
38 def log(_, msg):
39 #print "> " + msg
40 pass
42 DEBUG = 0
44 def get_name_label(node):
45 name_node = node.getElementsByTagName("name")[0]
46 label_node = name_node.getElementsByTagName("label")[0]
47 return " ".join([child.nodeValue for child in label_node.childNodes])
49 def get_name_description(node):
50 name_node = node.getElementsByTagName("name")[0]
51 description_node = name_node.getElementsByTagName("description")[0]
52 return " ".join([child.nodeValue for child in description_node.childNodes])
54 def get_text_in_child_node(node, child):
55 tag_node = node.getElementsByTagName(child)[0]
56 return " ".join([child.nodeValue for child in tag_node.childNodes])
58 def get_child_node_attribute(node, child, attribute):
59 tag_node = node.getElementsByTagName(child)[0]
60 return tag_node.attributes[attribute].value
62 def get_child_nodes_as_dict(node, child_name,
63 key_attribute_name,
64 value_attribute_name):
65 return dict([(child.attributes[key_attribute_name].value,
66 child.attributes[value_attribute_name].value)
67 for child in node.getElementsByTagName(child_name)])
69 def try_quietly(fn, *args):
70 try:
71 return fn(*args)
72 except:
73 return None
75 class xenapi_create:
77 def __init__(self):
78 self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
80 self.dtd = join(SHAREDIR, "create.dtd")
82 def create(self, filename=None, document=None, skipdtd=False):
83 """
84 Create a domain from an XML file or DOM tree
85 """
86 if skipdtd:
87 print "Skipping DTD checks. Dangerous!"
89 if filename is not None:
90 if not skipdtd:
91 self.check_dtd(filename)
92 document = parse(filename)
93 elif document is not None:
94 if not skipdtd:
95 self.check_dom_against_dtd(document)
97 self.check_doc(document)
99 vdis = document.getElementsByTagName("vdi")
100 vdi_refs_dict = self.create_vdis(vdis)
102 networks = document.getElementsByTagName("network")
103 network_refs_dict = self.create_networks(networks)
105 try:
106 vms = document.getElementsByTagName("vm")
107 return self.create_vms(vms, vdi_refs_dict, network_refs_dict)
108 except Exception, exn:
109 try_quietly(self.cleanup_vdis(vdi_refs_dict))
110 raise exn
112 # Methods to check xml file
113 # try to use dtd to check where possible
114 def check_dtd(self, file):
115 """
116 Check file against DTD.
117 Use this if possible as it gives nice
118 error messages
119 """
120 dtd = xmldtd.load_dtd(self.dtd)
121 parser = xmlproc.XMLProcessor()
122 parser.set_application(xmlval.ValidatingApp(dtd, parser))
123 parser.dtd = dtd
124 parser.ent = dtd
125 parser.parse_resource(file)
127 def check_dom_against_dtd(self, dom):
128 """
129 Check DOM again DTD.
130 Doesn't give as nice error messages.
131 (no location info)
132 """
133 dtd = xmldtd.load_dtd(self.dtd)
134 app = xmlval.ValidatingApp(dtd, self)
135 app.set_locator(self)
136 self.dom2sax(dom, app)
138 # Get errors back from ValidatingApp
139 def report_error(self, number, args=None):
140 self.errors = xmlproc.errors.english
141 try:
142 msg = self.errors[number]
143 if args != None:
144 msg = msg % args
145 except KeyError:
146 msg = self.errors[4002] % number # Unknown err msg :-)
147 print msg
148 sys.exit(-1)
150 # Here for compatibility with ValidatingApp
151 def get_line(self):
152 return -1
154 def get_column(self):
155 return -1
157 def dom2sax(self, dom, app):
158 """
159 Take a dom tree and tarverse it,
160 issuing SAX calls to app.
161 """
162 for child in dom.childNodes:
163 if child.nodeType == child.TEXT_NODE:
164 data = child.nodeValue
165 app.handle_data(data, 0, len(data))
166 else:
167 app.handle_start_tag(
168 child.nodeName,
169 self.attrs_to_dict(child.attributes))
170 self.dom2sax(child, app)
171 app.handle_end_tag(child.nodeName)
173 def attrs_to_dict(self, attrs):
174 return dict(attrs.items())
176 #
177 # Checks which cannot be done with dtd
178 #
179 def check_doc(self, doc):
180 vms = doc.getElementsByTagName("vm")
181 self.check_vms(vms)
183 def check_vms(self, vms):
184 map(self.check_vm, vms)
186 def check_vm(self, vm):
187 vifs = vm.getElementsByTagName("vif")
188 self.check_vifs(vifs)
190 def check_vifs(self, vifs):
191 map(self.check_vif, vifs)
193 def check_vif(self, vif):
194 pass
196 # Cleanup methods here
197 def cleanup_vdis(self, vdi_refs_dict):
198 map(self.cleanup_vdi, vdi_refs_dict.values())
200 def cleanup_vdi(self, vdi_ref):
201 server.xenapi.VDI.destroy(vdi_ref)
203 def cleanup_vms(self, vm_refs):
204 map(self.cleanup_vm, vm_refs)
206 def cleanup_vm(self, vm_ref):
207 server.xenapi.VM.destroy(vm_ref)
209 # Create methods here
210 def create_vdis(self, vdis):
211 log(DEBUG, "create_vdis")
212 return dict(map(self.create_vdi, vdis))
214 def create_vdi(self, vdi):
215 log(DEBUG, "create_vdi")
217 vdi_record = {
218 "name_label": get_name_label(vdi),
219 "name_description": get_name_description(vdi),
220 "SR": self.DEFAULT_STORAGE_REPOSITORY,
221 "virtual_size": vdi.attributes["size"].value,
222 "type": vdi.attributes["type"].value,
223 "sharable": vdi.attributes["sharable"].value == "True",
224 "read_only": vdi.attributes["read_only"].value == "True",
225 "other_config": {"location":
226 vdi.attributes["src"].value}
227 }
229 key = vdi.attributes["name"].value
230 value = server.xenapi.VDI.create(vdi_record)
232 return (key, value)
234 def create_networks(self, networks):
235 log(DEBUG, "create_networks")
236 return dict(map(self.create_network, networks))
238 def create_network(self, network):
239 log(DEBUG, "create_network")
241 network_record = {
242 "name_label": get_name_label(network),
243 "name_description": get_name_description(network),
244 "other_config":
245 get_child_nodes_as_dict(network, "other_config",
246 "key", "value"),
247 "default_netmask": network.attributes["default_netmask"].value,
248 "default_gateway": network.attributes["default_gateway"].value
249 }
251 key = network.attributes["name"].value
252 value = server.xenapi.network.create(network_record)
254 return (key, value)
256 def create_vms(self, vms, vdis, networks):
257 log(DEBUG, "create_vms")
258 return map(lambda vm: self.create_vm(vm, vdis, networks), vms)
260 def create_vm(self, vm, vdis, networks):
261 log(DEBUG, "create_vm")
263 vm_record = {
264 "name_label":
265 get_name_label(vm),
266 "name_description":
267 get_name_description(vm),
268 "user_version":
269 get_text_in_child_node(vm, "version"),
270 "is_a_template":
271 vm.attributes["is_a_template"].value == 'true',
272 "auto_power_on":
273 vm.attributes["auto_power_on"].value == 'true',
274 "s3_integrity":
275 vm.attributes["s3_integrity"].value,
276 "superpages":
277 vm.attributes["superpages"].value,
278 "memory_static_max":
279 get_child_node_attribute(vm, "memory", "static_max"),
280 "memory_static_min":
281 get_child_node_attribute(vm, "memory", "static_min"),
282 "memory_dynamic_max":
283 get_child_node_attribute(vm, "memory", "dynamic_max"),
284 "memory_dynamic_min":
285 get_child_node_attribute(vm, "memory", "dynamic_min"),
286 "VCPUs_params":
287 get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
288 "VCPUs_max":
289 vm.attributes["vcpus_max"].value,
290 "VCPUs_at_startup":
291 vm.attributes["vcpus_at_startup"].value,
292 "actions_after_shutdown":
293 vm.attributes["actions_after_shutdown"].value,
294 "actions_after_reboot":
295 vm.attributes["actions_after_reboot"].value,
296 "actions_after_crash":
297 vm.attributes["actions_after_crash"].value,
298 "platform":
299 get_child_nodes_as_dict(vm, "platform", "key", "value"),
300 "other_config":
301 get_child_nodes_as_dict(vm, "other_config", "key", "value"),
302 "PV_bootloader":
303 "",
304 "PV_kernel":
305 "",
306 "PV_ramdisk":
307 "",
308 "PV_args":
309 "",
310 "PV_bootloader_args":
311 "",
312 "HVM_boot_policy":
313 "",
314 "HVM_boot_params":
315 {},
316 "PCI_bus":
317 ""
318 }
320 if vm.attributes.has_key("security_label"):
321 vm_record.update({
322 "security_label":
323 vm.attributes["security_label"].value
324 })
326 if len(vm.getElementsByTagName("pv")) > 0:
327 vm_record.update({
328 "PV_bootloader":
329 get_child_node_attribute(vm, "pv", "bootloader"),
330 "PV_kernel":
331 get_child_node_attribute(vm, "pv", "kernel"),
332 "PV_ramdisk":
333 get_child_node_attribute(vm, "pv", "ramdisk"),
334 "PV_args":
335 get_child_node_attribute(vm, "pv", "args"),
336 "PV_bootloader_args":
337 get_child_node_attribute(vm, "pv", "bootloader_args")
338 })
339 else:
340 hvm = vm.getElementsByTagName("hvm")[0]
341 vm_record.update({
342 "HVM_boot_policy":
343 get_child_node_attribute(vm, "hvm", "boot_policy"),
344 "HVM_boot_params":
345 get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
346 })
347 try:
348 vm_ref = server.xenapi.VM.create(vm_record)
349 except:
350 traceback.print_exc()
351 sys.exit(-1)
353 try:
354 # Now create vbds
356 vbds = vm.getElementsByTagName("vbd")
358 self.create_vbds(vm_ref, vbds, vdis)
360 # Now create vifs
362 vifs = vm.getElementsByTagName("vif")
364 self.create_vifs(vm_ref, vifs, networks)
366 # Now create vtpms
368 vtpms = vm.getElementsByTagName("vtpm")
370 self.create_vtpms(vm_ref, vtpms)
372 # Now create consoles
374 consoles = vm.getElementsByTagName("console")
376 self.create_consoles(vm_ref, consoles)
378 # Now create pcis
380 pcis = vm.getElementsByTagName("pci")
382 self.create_pcis(vm_ref, pcis)
384 # Now create scsis
386 scsis = vm.getElementsByTagName("vscsi")
388 self.create_scsis(vm_ref, scsis)
390 return vm_ref
391 except:
392 server.xenapi.VM.destroy(vm_ref)
393 raise
395 def create_vbds(self, vm_ref, vbds, vdis):
396 log(DEBUG, "create_vbds")
397 return map(lambda vbd: self.create_vbd(vm_ref, vbd, vdis), vbds)
399 def create_vbd(self, vm_ref, vbd, vdis):
400 log(DEBUG, "create_vbd")
402 vbd_record = {
403 "VM":
404 vm_ref,
405 "VDI":
406 vdis[vbd.attributes["vdi"].value],
407 "device":
408 vbd.attributes["device"].value,
409 "bootable":
410 vbd.attributes["bootable"].value == "1",
411 "mode":
412 vbd.attributes["mode"].value,
413 "type":
414 vbd.attributes["type"].value,
415 "qos_algorithm_type":
416 vbd.attributes["qos_algorithm_type"].value,
417 "qos_algorithm_params":
418 get_child_nodes_as_dict(vbd,
419 "qos_algorithm_param", "key", "value")
420 }
422 return server.xenapi.VBD.create(vbd_record)
424 def create_vifs(self, vm_ref, vifs, networks):
425 log(DEBUG, "create_vifs")
426 return map(lambda vif: self.create_vif(vm_ref, vif, networks), vifs)
428 def create_vif(self, vm_ref, vif, networks):
429 log(DEBUG, "create_vif")
431 if 'network' in vif.attributes.keys():
432 network_name = vif.attributes['network'].value
434 if network_name in networks.keys():
435 network_uuid = networks[network_name]
436 else:
437 networks = dict([(record['name_label'], ref)
438 for ref, record in
439 server.xenapi.network.get_all_records().items()])
440 if network_name in networks.keys():
441 network_uuid = networks[network_name]
442 else:
443 raise OptionError("Network %s doesn't exist"
444 % vif.attributes["network"].value)
445 else:
446 network_uuid = self._get_network_ref()
448 vif_record = {
449 "device":
450 vif.attributes["device"].value,
451 "network":
452 network_uuid,
453 "VM":
454 vm_ref,
455 "MAC":
456 vif.attributes["mac"].value,
457 "MTU":
458 vif.attributes["mtu"].value,
459 "qos_algorithm_type":
460 vif.attributes["qos_algorithm_type"].value,
461 "qos_algorithm_params":
462 get_child_nodes_as_dict(vif,
463 "qos_algorithm_param", "key", "value"),
464 "security_label":
465 vif.attributes["security_label"].value
466 }
468 return server.xenapi.VIF.create(vif_record)
470 _network_refs = []
472 def _get_network_ref(self):
473 try:
474 return self._network_refs.pop(0)
475 except IndexError:
476 self._network_refs = server.xenapi.network.get_all()
477 return self._network_refs.pop(0)
479 def create_vtpms(self, vm_ref, vtpms):
480 if len(vtpms) > 1:
481 vtpms = [ vtpms[0] ]
482 log(DEBUG, "create_vtpms")
483 return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms)
485 def create_vtpm(self, vm_ref, vtpm):
486 vtpm_record = {
487 "VM":
488 vm_ref,
489 "backend":
490 vtpm.attributes["backend"].value
491 }
492 return server.xenapi.VTPM.create(vtpm_record)
494 def create_consoles(self, vm_ref, consoles):
495 log(DEBUG, "create_consoles")
496 return map(lambda console: self.create_console(vm_ref, console),
497 consoles)
499 def create_console(self, vm_ref, console):
500 log(DEBUG, "create_consoles")
502 console_record = {
503 "VM":
504 vm_ref,
505 "protocol":
506 console.attributes["protocol"].value,
507 "other_config":
508 get_child_nodes_as_dict(console,
509 "other_config", "key", "value")
510 }
512 return server.xenapi.console.create(console_record)
514 def create_pcis(self, vm_ref, pcis):
515 log(DEBUG, "create_pcis")
516 return map(lambda pci: self.create_pci(vm_ref, pci), pcis)
518 def create_pci(self, vm_ref, pci):
519 log(DEBUG, "create_pci")
521 domain = int(pci.attributes["domain"].value, 16)
522 bus = int(pci.attributes["bus"].value, 16)
523 slot = int(pci.attributes["slot"].value, 16)
524 func = int(pci.attributes["func"].value, 16)
525 name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
527 target_ref = None
528 for ppci_ref in server.xenapi.PPCI.get_all():
529 if name == server.xenapi.PPCI.get_name(ppci_ref):
530 target_ref = ppci_ref
531 break
532 if target_ref is None:
533 log(DEBUG, "create_pci: pci device not found")
534 return None
536 dpci_record = {
537 "VM":
538 vm_ref,
539 "PPCI":
540 target_ref,
541 "hotplug_slot":
542 int(pci.attributes["vslot"].value, 16),
543 "options":
544 get_child_nodes_as_dict(pci,
545 "pci_opt", "key", "value")
546 }
548 return server.xenapi.DPCI.create(dpci_record)
550 def create_scsis(self, vm_ref, scsis):
551 log(DEBUG, "create_scsis")
552 return map(lambda scsi: self.create_scsi(vm_ref, scsi), scsis)
554 def create_scsi(self, vm_ref, scsi):
555 log(DEBUG, "create_scsi")
557 target_ref = None
558 for pscsi_ref in server.xenapi.PSCSI.get_all():
559 if scsi.attributes["p-dev"].value == server.xenapi.PSCSI.get_physical_HCTL(pscsi_ref):
560 target_ref = pscsi_ref
561 break
562 if target_ref is None:
563 log(DEBUG, "create_scsi: scsi device not found")
564 return None
566 dscsi_record = {
567 "VM":
568 vm_ref,
569 "PSCSI":
570 target_ref,
571 "virtual_HCTL":
572 scsi.attributes["v-dev"].value
573 }
575 return server.xenapi.DSCSI.create(dscsi_record)
577 def get_child_by_name(exp, childname, default = None):
578 try:
579 return [child for child in sxp.children(exp)
580 if child[0] == childname][0][1]
581 except:
582 return default
584 # Convert old sxp into new xml
586 class sxp2xml:
588 def convert_sxp_to_xml(self, config, transient=False):
590 devices = [child for child in sxp.children(config)
591 if len(child) > 0 and child[0] == "device"]
593 vbds_sxp = map(lambda x: x[1], [device for device in devices
594 if device[1][0] in ("vbd", "tap")])
596 vifs_sxp = map(lambda x: x[1], [device for device in devices
597 if device[1][0] == "vif"])
599 vtpms_sxp = map(lambda x: x[1], [device for device in devices
600 if device[1][0] == "vtpm"])
602 vfbs_sxp = map(lambda x: x[1], [device for device in devices
603 if device[1][0] == "vfb"])
605 pcis_sxp = map(lambda x: x[1], [device for device in devices
606 if device[1][0] == "pci"])
608 scsis_sxp = map(lambda x: x[1], [device for device in devices
609 if device[1][0] == "vscsi"])
611 # Create XML Document
613 impl = getDOMImplementation()
615 document = impl.createDocument(None, "xm", None)
617 # Lets make the VM tag..
619 vm = document.createElement("vm")
621 # Some string compatibility
623 actions_after_shutdown \
624 = get_child_by_name(config, "on_poweroff", "destroy")
625 actions_after_reboot \
626 = get_child_by_name(config, "on_reboot", "restart")
627 actions_after_crash \
628 = get_child_by_name(config, "on_crash", "restart")
630 def conv_chk(val, vals):
631 val.replace("-", "_")
632 if val not in vals:
633 raise "Invalid value: " + val
634 else:
635 return val
637 actions_after_shutdown = conv_chk(actions_after_shutdown,\
638 XEN_API_ON_NORMAL_EXIT)
639 actions_after_reboot = conv_chk(actions_after_reboot, \
640 XEN_API_ON_NORMAL_EXIT)
641 actions_after_crash = conv_chk(actions_after_crash, \
642 XEN_API_ON_CRASH_BEHAVIOUR)
643 # Flesh out tag attributes
645 vm.attributes["is_a_template"] = "false"
646 vm.attributes["auto_power_on"] = "false"
647 vm.attributes["actions_after_shutdown"] \
648 = actions_after_shutdown
649 vm.attributes["actions_after_reboot"] \
650 = actions_after_reboot
651 vm.attributes["actions_after_crash"] \
652 = actions_after_crash
653 vm.attributes["PCI_bus"] = ""
655 vm.attributes["vcpus_max"] \
656 = str(get_child_by_name(config, "vcpus", 1))
657 vm.attributes["vcpus_at_startup"] \
658 = str(get_child_by_name(config, "vcpus", 1))
659 vm.attributes["s3_integrity"] \
660 = str(get_child_by_name(config, "s3_integrity", 0))
661 vm.attributes["superpages"] \
662 = str(get_child_by_name(config, "superpages", 0))
664 sec_data = get_child_by_name(config, "security")
665 if sec_data:
666 try :
667 vm.attributes['security_label'] = \
668 security.set_security_label(sec_data[0][1][1],sec_data[0][2][1])
669 except Exception, e:
670 raise "Invalid security data format: %s" % str(sec_data)
672 # Make the name tag
674 vm.appendChild(self.make_name_tag(
675 get_child_by_name(config, "name"), document))
677 # Make version tag
679 version = document.createElement("version")
680 version.appendChild(document.createTextNode("0"))
681 vm.appendChild(version)
683 # Make pv or hvm tag
685 image = get_child_by_name(config, "image")
687 if image[0] == "linux":
688 pv = document.createElement("pv")
689 pv.attributes["kernel"] \
690 = get_child_by_name(image, "kernel", "")
691 pv.attributes["bootloader"] \
692 = get_child_by_name(config, "bootloader", "")
693 pv.attributes["ramdisk"] \
694 = get_child_by_name(image, "ramdisk", "")
695 pv.attributes["args"] \
696 = "root=" + get_child_by_name(image, "root", "") \
697 + " " + get_child_by_name(image, "args", "")
698 pv.attributes["bootloader_args"] \
699 = get_child_by_name(config, "bootloader_args","")
701 vm.appendChild(pv)
702 elif image[0] == "hvm":
703 hvm = document.createElement("hvm")
704 hvm.attributes["boot_policy"] = "BIOS order"
706 boot_order = document.createElement("boot_param")
707 boot_order.attributes["key"] = "order"
708 boot_order.attributes["value"] \
709 = get_child_by_name(image, "boot", "abcd")
710 hvm.appendChild
712 vm.appendChild(hvm)
714 # Make memory tag
716 memory = document.createElement("memory")
718 memory_str = str(int(
719 get_child_by_name(config, "memory"))*1024*1024)
721 memory.attributes["static_min"] = str(0)
722 memory.attributes["static_max"] = memory_str
723 memory.attributes["dynamic_min"] = memory_str
724 memory.attributes["dynamic_max"] = memory_str
726 if get_child_by_name(config, "maxmem"):
727 memory.attributes["static_max"] = \
728 str(int(get_child_by_name(config, "maxmem")*1024*1024))
730 vm.appendChild(memory)
732 # And now the vbds
734 vbds = map(lambda vbd: self.extract_vbd(vbd, document), vbds_sxp)
736 map(vm.appendChild, vbds)
738 # And now the vifs
740 vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
742 map(vm.appendChild, vifs)
744 # And now the vTPMs
746 vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp)
748 map(vm.appendChild, vtpms)
750 # And now the pcis
752 pcis = self.extract_pcis(pcis_sxp, document)
754 map(vm.appendChild, pcis)
756 # And now the scsis
758 scsis = self.extract_scsis(scsis_sxp, document)
760 map(vm.appendChild, scsis)
762 # Last but not least the consoles...
764 consoles = self.extract_consoles(image, document)
766 map(vm.appendChild, consoles)
768 vfbs = map(lambda vfb: self.extract_vfb(vfb, document), vfbs_sxp)
770 map(vm.appendChild, vfbs)
772 # Platform variables...
774 platform = self.extract_platform(image, document)
776 map(vm.appendChild, platform)
778 # transient?
780 if transient:
781 other_config = document.createElement("other_config")
782 other_config.attributes["key"] = "transient"
783 other_config.attributes["value"] = "True"
784 vm.appendChild(other_config)
786 # Add it to doc_root
788 document.documentElement.appendChild(vm)
790 # We want to pull out vdis
792 vdis = map(lambda vdb: self.extract_vdi(vdb, document), vbds_sxp)
794 map(document.documentElement.appendChild, vdis)
796 return document
798 def make_name_tag(self, label_text, document):
799 name = document.createElement("name")
801 label = document.createElement("label")
802 label.appendChild(document.createTextNode(str(label_text)))
803 name.appendChild(label)
805 description = document.createElement("description")
806 description.appendChild(document.createTextNode(" "))
807 name.appendChild(description)
809 return name
811 def extract_vbd(self, vbd_sxp, document):
812 src = get_child_by_name(vbd_sxp, "uname")
813 mode = get_child_by_name(vbd_sxp, "mode")
814 name = str(src.__hash__())
816 vbd = document.createElement("vbd")
818 vbd.attributes["name"] = "vdb" + name
819 vbd.attributes["vdi"] = "vdi" + name
820 vbd.attributes["mode"] \
821 = re.search("^w!{0,1}$", mode) and "RW" or "RO"
822 vbd.attributes["device"] \
823 = re.sub(":cdrom$", "", get_child_by_name(vbd_sxp, "dev"))
824 vbd.attributes["bootable"] = "1"
825 vbd.attributes["type"] \
826 = re.search(":cdrom$", get_child_by_name(vbd_sxp, "dev")) \
827 and "CD" or "disk"
828 vbd.attributes["qos_algorithm_type"] = ""
830 return vbd
832 def extract_vdi(self, vbd_sxp, document):
833 src = get_child_by_name(vbd_sxp, "uname")
834 mode = get_child_by_name(vbd_sxp, "mode")
835 name = "vdi" + str(src.__hash__())
837 vdi = document.createElement("vdi")
839 vdi.attributes["src"] = src
840 vdi.attributes["read_only"] \
841 = re.search("^w!{0,1}$", mode) and "False" or "True"
842 vdi.attributes["size"] = '-1'
843 vdi.attributes["type"] = "system"
844 vdi.attributes["sharable"] \
845 = re.search("^w!$", mode) and "True" or "False"
846 vdi.attributes["name"] = name
848 vdi.appendChild(self.make_name_tag(name, document))
850 return vdi
852 def extract_vif(self, vif_sxp, document):
854 vif = document.createElement("vif")
856 dev = get_child_by_name(vif_sxp, "vifname", None)
858 if dev is None:
859 dev = self.getFreshEthDevice()
861 vif.attributes["name"] \
862 = "vif" + str(dev.__hash__())
863 vif.attributes["mac"] \
864 = get_child_by_name(vif_sxp, "mac", "")
865 vif.attributes["mtu"] \
866 = get_child_by_name(vif_sxp, "mtu", "")
867 vif.attributes["device"] = dev
868 vif.attributes["qos_algorithm_type"] = ""
870 policy = get_child_by_name(vif_sxp, "policy")
871 label = get_child_by_name(vif_sxp, "label")
873 vif.attributes["security_label"] = security.set_security_label(policy, label)
875 if get_child_by_name(vif_sxp, "bridge") is not None:
876 vif.attributes["network"] \
877 = get_child_by_name(vif_sxp, "bridge")
879 return vif
881 def extract_vtpm(self, vtpm_sxp, document):
883 vtpm = document.createElement("vtpm")
885 vtpm.attributes["backend"] \
886 = get_child_by_name(vtpm_sxp, "backend", "0")
888 return vtpm
890 def extract_vfb(self, vfb_sxp, document):
892 vfb = document.createElement("console")
893 vfb.attributes["protocol"] = "rfb"
895 if get_child_by_name(vfb_sxp, "type", "") == "vnc":
896 vfb.appendChild(self.mk_other_config(
897 "type", "vnc",
898 document))
899 vfb.appendChild(self.mk_other_config(
900 "vncunused", get_child_by_name(vfb_sxp, "vncunused", "1"),
901 document))
902 vfb.appendChild(self.mk_other_config(
903 "vnclisten",
904 get_child_by_name(vfb_sxp, "vnclisten", "127.0.0.1"),
905 document))
906 vfb.appendChild(self.mk_other_config(
907 "vncdisplay", get_child_by_name(vfb_sxp, "vncdisplay", "0"),
908 document))
909 vfb.appendChild(self.mk_other_config(
910 "vncpasswd", get_child_by_name(vfb_sxp, "vncpasswd", ""),
911 document))
913 if get_child_by_name(vfb_sxp, "type", "") == "sdl":
914 vfb.appendChild(self.mk_other_config(
915 "type", "sdl",
916 document))
917 vfb.appendChild(self.mk_other_config(
918 "display", get_child_by_name(vfb_sxp, "display", ""),
919 document))
920 vfb.appendChild(self.mk_other_config(
921 "xauthority",
922 get_child_by_name(vfb_sxp, "xauthority", ""),
923 document))
924 vfb.appendChild(self.mk_other_config(
925 "opengl", get_child_by_name(vfb_sxp, "opengl", "1"),
926 document))
928 return vfb
930 def extract_pcis(self, pcis_sxp, document):
932 pcis = []
934 for pci_sxp in pcis_sxp:
935 for dev_sxp in sxp.children(pci_sxp, "dev"):
936 pci = document.createElement("pci")
938 pci.attributes["domain"] \
939 = get_child_by_name(dev_sxp, "domain", "0")
940 pci.attributes["bus"] \
941 = get_child_by_name(dev_sxp, "bus", "0")
942 pci.attributes["slot"] \
943 = get_child_by_name(dev_sxp, "slot", "0")
944 pci.attributes["func"] \
945 = get_child_by_name(dev_sxp, "func", "0")
946 pci.attributes["vslot"] \
947 = get_child_by_name(dev_sxp, "vslot", "0")
948 for opt in get_child_by_name(dev_sxp, "opts", ""):
949 if len(opt) > 0:
950 pci_opt = document.createElement("pci_opt")
951 pci_opt.attributes["key"] = opt[0]
952 pci_opt.attributes["value"] = opt[1]
953 pci.appendChild(pci_opt)
955 pcis.append(pci)
957 return pcis
959 def extract_scsis(self, scsis_sxp, document):
961 scsis = []
963 for scsi_sxp in scsis_sxp:
964 for dev_sxp in sxp.children(scsi_sxp, "dev"):
965 scsi = document.createElement("vscsi")
967 scsi.attributes["p-dev"] \
968 = get_child_by_name(dev_sxp, "p-dev")
969 scsi.attributes["v-dev"] \
970 = get_child_by_name(dev_sxp, "v-dev")
972 scsis.append(scsi)
974 return scsis
976 def mk_other_config(self, key, value, document):
977 other_config = document.createElement("other_config")
978 other_config.attributes["key"] = key
979 other_config.attributes["value"] = value
980 return other_config
982 def extract_consoles(self, image, document):
983 consoles = []
985 if int(get_child_by_name(image, "nographic", "1")) == 1:
986 return consoles
988 if int(get_child_by_name(image, "vnc", "0")) == 1:
989 console = document.createElement("console")
990 console.attributes["protocol"] = "rfb"
991 console.appendChild(self.mk_other_config(
992 "type", "vnc",
993 document))
994 console.appendChild(self.mk_other_config(
995 "vncunused", str(get_child_by_name(image, "vncunused", "1")),
996 document))
997 console.appendChild(self.mk_other_config(
998 "vnclisten",
999 get_child_by_name(image, "vnclisten", "127.0.0.1"),
1000 document))
1001 console.appendChild(self.mk_other_config(
1002 "vncdisplay", str(get_child_by_name(image, "vncdisplay", "0")),
1003 document))
1004 console.appendChild(self.mk_other_config(
1005 "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
1006 document))
1007 consoles.append(console)
1008 if int(get_child_by_name(image, "sdl", "0")) == 1:
1009 console = document.createElement("console")
1010 console.attributes["protocol"] = "rfb"
1011 console.appendChild(self.mk_other_config(
1012 "type", "sdl",
1013 document))
1014 console.appendChild(self.mk_other_config(
1015 "display", get_child_by_name(image, "display", ""),
1016 document))
1017 console.appendChild(self.mk_other_config(
1018 "xauthority", get_child_by_name(image, "xauthority", ""),
1019 document))
1020 console.appendChild(self.mk_other_config(
1021 "opengl", str(get_child_by_name(image, "opengl", "1")),
1022 document))
1023 consoles.append(console)
1025 return consoles
1028 def extract_platform(self, image, document):
1030 platform_keys = [
1031 'acpi',
1032 'apic',
1033 'boot',
1034 'device_model',
1035 'loader',
1036 'fda',
1037 'fdb',
1038 'keymap',
1039 'isa',
1040 'localtime',
1041 'monitor',
1042 'pae',
1043 'rtc_timeoffset',
1044 'serial',
1045 'soundhw',
1046 'stdvga',
1047 'usb',
1048 'usbdevice',
1049 'hpet',
1050 'timer_mode',
1051 'vpt_align',
1052 'viridian',
1053 'vhpt',
1054 'guest_os_type',
1055 'hap',
1056 'pci_msitranslate',
1057 'pci_power_mgmt',
1058 'xen_platform_pci',
1061 platform_configs = []
1062 for key in platform_keys:
1063 value = get_child_by_name(image, key, None)
1064 if value is not None:
1065 platform = document.createElement("platform")
1066 platform.attributes["key"] = key
1067 platform.attributes["value"] = str(value)
1068 platform_configs.append(platform)
1070 return platform_configs
1072 _eths = -1
1074 def getFreshEthDevice(self):
1075 self._eths += 1
1076 return "eth%i" % self._eths