ia64/xen-unstable

view tools/python/xen/xm/xenapi_create.py @ 19758:0573bbe19499

xend: pass-through: sxp.merge() cant deal with values being a list

sxp.merge() can't deal with values being a list so instead
of storing pci options as:

[ 'opts', [ 'key1' 'value1'], [ 'key2', 'value2'], ...]

store them as:

[ 'opts', [ 'key1' 'value1'], ['opts', [ 'key2', 'value2']], ...

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 16 11:37:41 2009 +0100 (2009-06-16)
parents 2c172f9db417
children
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.pci import pci_opts_list_from_sxp
30 from xen.util.path import SHAREDIR
31 import xen.util.xsm.xsm as security
33 import sys
34 import os
35 from os.path import join
36 import traceback
37 import re
39 def log(_, msg):
40 #print "> " + msg
41 pass
43 DEBUG = 0
45 def get_name_label(node):
46 name_node = node.getElementsByTagName("name")[0]
47 label_node = name_node.getElementsByTagName("label")[0]
48 return " ".join([child.nodeValue for child in label_node.childNodes])
50 def get_name_description(node):
51 name_node = node.getElementsByTagName("name")[0]
52 description_node = name_node.getElementsByTagName("description")[0]
53 return " ".join([child.nodeValue for child in description_node.childNodes])
55 def get_text_in_child_node(node, child):
56 tag_node = node.getElementsByTagName(child)[0]
57 return " ".join([child.nodeValue for child in tag_node.childNodes])
59 def get_child_node_attribute(node, child, attribute):
60 tag_node = node.getElementsByTagName(child)[0]
61 return tag_node.attributes[attribute].value
63 def get_child_nodes_as_dict(node, child_name,
64 key_attribute_name,
65 value_attribute_name):
66 return dict([(child.attributes[key_attribute_name].value,
67 child.attributes[value_attribute_name].value)
68 for child in node.getElementsByTagName(child_name)])
70 def try_quietly(fn, *args):
71 try:
72 return fn(*args)
73 except:
74 return None
76 class xenapi_create:
78 def __init__(self):
79 self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
81 self.dtd = join(SHAREDIR, "create.dtd")
83 def create(self, filename=None, document=None, skipdtd=False):
84 """
85 Create a domain from an XML file or DOM tree
86 """
87 if skipdtd:
88 print "Skipping DTD checks. Dangerous!"
90 if filename is not None:
91 if not skipdtd:
92 self.check_dtd(filename)
93 document = parse(filename)
94 elif document is not None:
95 if not skipdtd:
96 self.check_dom_against_dtd(document)
98 self.check_doc(document)
100 vdis = document.getElementsByTagName("vdi")
101 vdi_refs_dict = self.create_vdis(vdis)
103 networks = document.getElementsByTagName("network")
104 network_refs_dict = self.create_networks(networks)
106 try:
107 vms = document.getElementsByTagName("vm")
108 return self.create_vms(vms, vdi_refs_dict, network_refs_dict)
109 except Exception, exn:
110 try_quietly(self.cleanup_vdis(vdi_refs_dict))
111 raise exn
113 # Methods to check xml file
114 # try to use dtd to check where possible
115 def check_dtd(self, file):
116 """
117 Check file against DTD.
118 Use this if possible as it gives nice
119 error messages
120 """
121 dtd = xmldtd.load_dtd(self.dtd)
122 parser = xmlproc.XMLProcessor()
123 parser.set_application(xmlval.ValidatingApp(dtd, parser))
124 parser.dtd = dtd
125 parser.ent = dtd
126 parser.parse_resource(file)
128 def check_dom_against_dtd(self, dom):
129 """
130 Check DOM again DTD.
131 Doesn't give as nice error messages.
132 (no location info)
133 """
134 dtd = xmldtd.load_dtd(self.dtd)
135 app = xmlval.ValidatingApp(dtd, self)
136 app.set_locator(self)
137 self.dom2sax(dom, app)
139 # Get errors back from ValidatingApp
140 def report_error(self, number, args=None):
141 self.errors = xmlproc.errors.english
142 try:
143 msg = self.errors[number]
144 if args != None:
145 msg = msg % args
146 except KeyError:
147 msg = self.errors[4002] % number # Unknown err msg :-)
148 print msg
149 sys.exit(-1)
151 # Here for compatibility with ValidatingApp
152 def get_line(self):
153 return -1
155 def get_column(self):
156 return -1
158 def dom2sax(self, dom, app):
159 """
160 Take a dom tree and tarverse it,
161 issuing SAX calls to app.
162 """
163 for child in dom.childNodes:
164 if child.nodeType == child.TEXT_NODE:
165 data = child.nodeValue
166 app.handle_data(data, 0, len(data))
167 else:
168 app.handle_start_tag(
169 child.nodeName,
170 self.attrs_to_dict(child.attributes))
171 self.dom2sax(child, app)
172 app.handle_end_tag(child.nodeName)
174 def attrs_to_dict(self, attrs):
175 return dict(attrs.items())
177 #
178 # Checks which cannot be done with dtd
179 #
180 def check_doc(self, doc):
181 vms = doc.getElementsByTagName("vm")
182 self.check_vms(vms)
184 def check_vms(self, vms):
185 map(self.check_vm, vms)
187 def check_vm(self, vm):
188 vifs = vm.getElementsByTagName("vif")
189 self.check_vifs(vifs)
191 def check_vifs(self, vifs):
192 map(self.check_vif, vifs)
194 def check_vif(self, vif):
195 pass
197 # Cleanup methods here
198 def cleanup_vdis(self, vdi_refs_dict):
199 map(self.cleanup_vdi, vdi_refs_dict.values())
201 def cleanup_vdi(self, vdi_ref):
202 server.xenapi.VDI.destroy(vdi_ref)
204 def cleanup_vms(self, vm_refs):
205 map(self.cleanup_vm, vm_refs)
207 def cleanup_vm(self, vm_ref):
208 server.xenapi.VM.destroy(vm_ref)
210 # Create methods here
211 def create_vdis(self, vdis):
212 log(DEBUG, "create_vdis")
213 return dict(map(self.create_vdi, vdis))
215 def create_vdi(self, vdi):
216 log(DEBUG, "create_vdi")
218 vdi_record = {
219 "name_label": get_name_label(vdi),
220 "name_description": get_name_description(vdi),
221 "SR": self.DEFAULT_STORAGE_REPOSITORY,
222 "virtual_size": vdi.attributes["size"].value,
223 "type": vdi.attributes["type"].value,
224 "sharable": vdi.attributes["sharable"].value == "True",
225 "read_only": vdi.attributes["read_only"].value == "True",
226 "other_config": {"location":
227 vdi.attributes["src"].value}
228 }
230 key = vdi.attributes["name"].value
231 value = server.xenapi.VDI.create(vdi_record)
233 return (key, value)
235 def create_networks(self, networks):
236 log(DEBUG, "create_networks")
237 return dict(map(self.create_network, networks))
239 def create_network(self, network):
240 log(DEBUG, "create_network")
242 network_record = {
243 "name_label": get_name_label(network),
244 "name_description": get_name_description(network),
245 "other_config":
246 get_child_nodes_as_dict(network, "other_config",
247 "key", "value"),
248 "default_netmask": network.attributes["default_netmask"].value,
249 "default_gateway": network.attributes["default_gateway"].value
250 }
252 key = network.attributes["name"].value
253 value = server.xenapi.network.create(network_record)
255 return (key, value)
257 def create_vms(self, vms, vdis, networks):
258 log(DEBUG, "create_vms")
259 return map(lambda vm: self.create_vm(vm, vdis, networks), vms)
261 def create_vm(self, vm, vdis, networks):
262 log(DEBUG, "create_vm")
264 vm_record = {
265 "name_label":
266 get_name_label(vm),
267 "name_description":
268 get_name_description(vm),
269 "user_version":
270 get_text_in_child_node(vm, "version"),
271 "is_a_template":
272 vm.attributes["is_a_template"].value == 'true',
273 "auto_power_on":
274 vm.attributes["auto_power_on"].value == 'true',
275 "s3_integrity":
276 vm.attributes["s3_integrity"].value,
277 "superpages":
278 vm.attributes["superpages"].value,
279 "memory_static_max":
280 get_child_node_attribute(vm, "memory", "static_max"),
281 "memory_static_min":
282 get_child_node_attribute(vm, "memory", "static_min"),
283 "memory_dynamic_max":
284 get_child_node_attribute(vm, "memory", "dynamic_max"),
285 "memory_dynamic_min":
286 get_child_node_attribute(vm, "memory", "dynamic_min"),
287 "VCPUs_params":
288 get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
289 "VCPUs_max":
290 vm.attributes["vcpus_max"].value,
291 "VCPUs_at_startup":
292 vm.attributes["vcpus_at_startup"].value,
293 "actions_after_shutdown":
294 vm.attributes["actions_after_shutdown"].value,
295 "actions_after_reboot":
296 vm.attributes["actions_after_reboot"].value,
297 "actions_after_crash":
298 vm.attributes["actions_after_crash"].value,
299 "platform":
300 get_child_nodes_as_dict(vm, "platform", "key", "value"),
301 "other_config":
302 get_child_nodes_as_dict(vm, "other_config", "key", "value"),
303 "PV_bootloader":
304 "",
305 "PV_kernel":
306 "",
307 "PV_ramdisk":
308 "",
309 "PV_args":
310 "",
311 "PV_bootloader_args":
312 "",
313 "HVM_boot_policy":
314 "",
315 "HVM_boot_params":
316 {},
317 "PCI_bus":
318 ""
319 }
321 if vm.attributes.has_key("security_label"):
322 vm_record.update({
323 "security_label":
324 vm.attributes["security_label"].value
325 })
327 if len(vm.getElementsByTagName("pv")) > 0:
328 vm_record.update({
329 "PV_bootloader":
330 get_child_node_attribute(vm, "pv", "bootloader"),
331 "PV_kernel":
332 get_child_node_attribute(vm, "pv", "kernel"),
333 "PV_ramdisk":
334 get_child_node_attribute(vm, "pv", "ramdisk"),
335 "PV_args":
336 get_child_node_attribute(vm, "pv", "args"),
337 "PV_bootloader_args":
338 get_child_node_attribute(vm, "pv", "bootloader_args")
339 })
340 else:
341 hvm = vm.getElementsByTagName("hvm")[0]
342 vm_record.update({
343 "HVM_boot_policy":
344 get_child_node_attribute(vm, "hvm", "boot_policy"),
345 "HVM_boot_params":
346 get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
347 })
348 try:
349 vm_ref = server.xenapi.VM.create(vm_record)
350 except:
351 traceback.print_exc()
352 sys.exit(-1)
354 try:
355 # Now create vbds
357 vbds = vm.getElementsByTagName("vbd")
359 self.create_vbds(vm_ref, vbds, vdis)
361 # Now create vifs
363 vifs = vm.getElementsByTagName("vif")
365 self.create_vifs(vm_ref, vifs, networks)
367 # Now create vtpms
369 vtpms = vm.getElementsByTagName("vtpm")
371 self.create_vtpms(vm_ref, vtpms)
373 # Now create consoles
375 consoles = vm.getElementsByTagName("console")
377 self.create_consoles(vm_ref, consoles)
379 # Now create pcis
381 pcis = vm.getElementsByTagName("pci")
383 self.create_pcis(vm_ref, pcis)
385 # Now create scsis
387 scsis = vm.getElementsByTagName("vscsi")
389 self.create_scsis(vm_ref, scsis)
391 return vm_ref
392 except:
393 server.xenapi.VM.destroy(vm_ref)
394 raise
396 def create_vbds(self, vm_ref, vbds, vdis):
397 log(DEBUG, "create_vbds")
398 return map(lambda vbd: self.create_vbd(vm_ref, vbd, vdis), vbds)
400 def create_vbd(self, vm_ref, vbd, vdis):
401 log(DEBUG, "create_vbd")
403 vbd_record = {
404 "VM":
405 vm_ref,
406 "VDI":
407 vdis[vbd.attributes["vdi"].value],
408 "device":
409 vbd.attributes["device"].value,
410 "bootable":
411 vbd.attributes["bootable"].value == "1",
412 "mode":
413 vbd.attributes["mode"].value,
414 "type":
415 vbd.attributes["type"].value,
416 "qos_algorithm_type":
417 vbd.attributes["qos_algorithm_type"].value,
418 "qos_algorithm_params":
419 get_child_nodes_as_dict(vbd,
420 "qos_algorithm_param", "key", "value")
421 }
423 return server.xenapi.VBD.create(vbd_record)
425 def create_vifs(self, vm_ref, vifs, networks):
426 log(DEBUG, "create_vifs")
427 return map(lambda vif: self.create_vif(vm_ref, vif, networks), vifs)
429 def create_vif(self, vm_ref, vif, networks):
430 log(DEBUG, "create_vif")
432 if 'network' in vif.attributes.keys():
433 network_name = vif.attributes['network'].value
435 if network_name in networks.keys():
436 network_uuid = networks[network_name]
437 else:
438 networks = dict([(record['name_label'], ref)
439 for ref, record in
440 server.xenapi.network.get_all_records().items()])
441 if network_name in networks.keys():
442 network_uuid = networks[network_name]
443 else:
444 raise OptionError("Network %s doesn't exist"
445 % vif.attributes["network"].value)
446 else:
447 network_uuid = self._get_network_ref()
449 vif_record = {
450 "device":
451 vif.attributes["device"].value,
452 "network":
453 network_uuid,
454 "VM":
455 vm_ref,
456 "MAC":
457 vif.attributes["mac"].value,
458 "MTU":
459 vif.attributes["mtu"].value,
460 "qos_algorithm_type":
461 vif.attributes["qos_algorithm_type"].value,
462 "qos_algorithm_params":
463 get_child_nodes_as_dict(vif,
464 "qos_algorithm_param", "key", "value"),
465 "security_label":
466 vif.attributes["security_label"].value
467 }
469 return server.xenapi.VIF.create(vif_record)
471 _network_refs = []
473 def _get_network_ref(self):
474 try:
475 return self._network_refs.pop(0)
476 except IndexError:
477 self._network_refs = server.xenapi.network.get_all()
478 return self._network_refs.pop(0)
480 def create_vtpms(self, vm_ref, vtpms):
481 if len(vtpms) > 1:
482 vtpms = [ vtpms[0] ]
483 log(DEBUG, "create_vtpms")
484 return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms)
486 def create_vtpm(self, vm_ref, vtpm):
487 vtpm_record = {
488 "VM":
489 vm_ref,
490 "backend":
491 vtpm.attributes["backend"].value
492 }
493 return server.xenapi.VTPM.create(vtpm_record)
495 def create_consoles(self, vm_ref, consoles):
496 log(DEBUG, "create_consoles")
497 return map(lambda console: self.create_console(vm_ref, console),
498 consoles)
500 def create_console(self, vm_ref, console):
501 log(DEBUG, "create_consoles")
503 console_record = {
504 "VM":
505 vm_ref,
506 "protocol":
507 console.attributes["protocol"].value,
508 "other_config":
509 get_child_nodes_as_dict(console,
510 "other_config", "key", "value")
511 }
513 return server.xenapi.console.create(console_record)
515 def create_pcis(self, vm_ref, pcis):
516 log(DEBUG, "create_pcis")
517 return map(lambda pci: self.create_pci(vm_ref, pci), pcis)
519 def create_pci(self, vm_ref, pci):
520 log(DEBUG, "create_pci")
522 domain = int(pci.attributes["domain"].value, 16)
523 bus = int(pci.attributes["bus"].value, 16)
524 slot = int(pci.attributes["slot"].value, 16)
525 func = int(pci.attributes["func"].value, 16)
526 name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
528 target_ref = None
529 for ppci_ref in server.xenapi.PPCI.get_all():
530 if name == server.xenapi.PPCI.get_name(ppci_ref):
531 target_ref = ppci_ref
532 break
533 if target_ref is None:
534 log(DEBUG, "create_pci: pci device not found")
535 return None
537 dpci_record = {
538 "VM":
539 vm_ref,
540 "PPCI":
541 target_ref,
542 "hotplug_slot":
543 int(pci.attributes["vslot"].value, 16),
544 "options":
545 get_child_nodes_as_dict(pci,
546 "pci_opt", "key", "value")
547 }
549 return server.xenapi.DPCI.create(dpci_record)
551 def create_scsis(self, vm_ref, scsis):
552 log(DEBUG, "create_scsis")
553 return map(lambda scsi: self.create_scsi(vm_ref, scsi), scsis)
555 def create_scsi(self, vm_ref, scsi):
556 log(DEBUG, "create_scsi")
558 target_ref = None
559 for pscsi_ref in server.xenapi.PSCSI.get_all():
560 if scsi.attributes["p-dev"].value == server.xenapi.PSCSI.get_physical_HCTL(pscsi_ref):
561 target_ref = pscsi_ref
562 break
563 if target_ref is None:
564 log(DEBUG, "create_scsi: scsi device not found")
565 return None
567 dscsi_record = {
568 "VM":
569 vm_ref,
570 "PSCSI":
571 target_ref,
572 "virtual_HCTL":
573 scsi.attributes["v-dev"].value
574 }
576 return server.xenapi.DSCSI.create(dscsi_record)
578 def get_child_by_name(exp, childname, default = None):
579 try:
580 return [child for child in sxp.children(exp)
581 if child[0] == childname][0][1]
582 except:
583 return default
585 # Convert old sxp into new xml
587 class sxp2xml:
589 def convert_sxp_to_xml(self, config, transient=False):
591 devices = [child for child in sxp.children(config)
592 if len(child) > 0 and child[0] == "device"]
594 vbds_sxp = map(lambda x: x[1], [device for device in devices
595 if device[1][0] in ("vbd", "tap")])
597 vifs_sxp = map(lambda x: x[1], [device for device in devices
598 if device[1][0] == "vif"])
600 vtpms_sxp = map(lambda x: x[1], [device for device in devices
601 if device[1][0] == "vtpm"])
603 vfbs_sxp = map(lambda x: x[1], [device for device in devices
604 if device[1][0] == "vfb"])
606 pcis_sxp = map(lambda x: x[1], [device for device in devices
607 if device[1][0] == "pci"])
609 scsis_sxp = map(lambda x: x[1], [device for device in devices
610 if device[1][0] == "vscsi"])
612 # Create XML Document
614 impl = getDOMImplementation()
616 document = impl.createDocument(None, "xm", None)
618 # Lets make the VM tag..
620 vm = document.createElement("vm")
622 # Some string compatibility
624 actions_after_shutdown \
625 = get_child_by_name(config, "on_poweroff", "destroy")
626 actions_after_reboot \
627 = get_child_by_name(config, "on_reboot", "restart")
628 actions_after_crash \
629 = get_child_by_name(config, "on_crash", "restart")
631 def conv_chk(val, vals):
632 val.replace("-", "_")
633 if val not in vals:
634 raise "Invalid value: " + val
635 else:
636 return val
638 actions_after_shutdown = conv_chk(actions_after_shutdown,\
639 XEN_API_ON_NORMAL_EXIT)
640 actions_after_reboot = conv_chk(actions_after_reboot, \
641 XEN_API_ON_NORMAL_EXIT)
642 actions_after_crash = conv_chk(actions_after_crash, \
643 XEN_API_ON_CRASH_BEHAVIOUR)
644 # Flesh out tag attributes
646 vm.attributes["is_a_template"] = "false"
647 vm.attributes["auto_power_on"] = "false"
648 vm.attributes["actions_after_shutdown"] \
649 = actions_after_shutdown
650 vm.attributes["actions_after_reboot"] \
651 = actions_after_reboot
652 vm.attributes["actions_after_crash"] \
653 = actions_after_crash
654 vm.attributes["PCI_bus"] = ""
656 vm.attributes["vcpus_max"] \
657 = str(get_child_by_name(config, "vcpus", 1))
658 vm.attributes["vcpus_at_startup"] \
659 = str(get_child_by_name(config, "vcpus", 1))
660 vm.attributes["s3_integrity"] \
661 = str(get_child_by_name(config, "s3_integrity", 0))
662 vm.attributes["superpages"] \
663 = str(get_child_by_name(config, "superpages", 0))
665 sec_data = get_child_by_name(config, "security")
666 if sec_data:
667 try :
668 vm.attributes['security_label'] = \
669 security.set_security_label(sec_data[0][1][1],sec_data[0][2][1])
670 except Exception, e:
671 raise "Invalid security data format: %s" % str(sec_data)
673 # Make the name tag
675 vm.appendChild(self.make_name_tag(
676 get_child_by_name(config, "name"), document))
678 # Make version tag
680 version = document.createElement("version")
681 version.appendChild(document.createTextNode("0"))
682 vm.appendChild(version)
684 # Make pv or hvm tag
686 image = get_child_by_name(config, "image")
688 if image[0] == "linux":
689 pv = document.createElement("pv")
690 pv.attributes["kernel"] \
691 = get_child_by_name(image, "kernel", "")
692 pv.attributes["bootloader"] \
693 = get_child_by_name(config, "bootloader", "")
694 pv.attributes["ramdisk"] \
695 = get_child_by_name(image, "ramdisk", "")
696 pv.attributes["args"] \
697 = "root=" + get_child_by_name(image, "root", "") \
698 + " " + get_child_by_name(image, "args", "")
699 pv.attributes["bootloader_args"] \
700 = get_child_by_name(config, "bootloader_args","")
702 vm.appendChild(pv)
703 elif image[0] == "hvm":
704 hvm = document.createElement("hvm")
705 hvm.attributes["boot_policy"] = "BIOS order"
707 boot_order = document.createElement("boot_param")
708 boot_order.attributes["key"] = "order"
709 boot_order.attributes["value"] \
710 = get_child_by_name(image, "boot", "abcd")
711 hvm.appendChild
713 vm.appendChild(hvm)
715 # Make memory tag
717 memory = document.createElement("memory")
719 memory_str = str(int(
720 get_child_by_name(config, "memory"))*1024*1024)
722 memory.attributes["static_min"] = str(0)
723 memory.attributes["static_max"] = memory_str
724 memory.attributes["dynamic_min"] = memory_str
725 memory.attributes["dynamic_max"] = memory_str
727 if get_child_by_name(config, "maxmem"):
728 memory.attributes["static_max"] = \
729 str(int(get_child_by_name(config, "maxmem")*1024*1024))
731 vm.appendChild(memory)
733 # And now the vbds
735 vbds = map(lambda vbd: self.extract_vbd(vbd, document), vbds_sxp)
737 map(vm.appendChild, vbds)
739 # And now the vifs
741 vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
743 map(vm.appendChild, vifs)
745 # And now the vTPMs
747 vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp)
749 map(vm.appendChild, vtpms)
751 # And now the pcis
753 pcis = self.extract_pcis(pcis_sxp, document)
755 map(vm.appendChild, pcis)
757 # And now the scsis
759 scsis = self.extract_scsis(scsis_sxp, document)
761 map(vm.appendChild, scsis)
763 # Last but not least the consoles...
765 consoles = self.extract_consoles(image, document)
767 map(vm.appendChild, consoles)
769 vfbs = map(lambda vfb: self.extract_vfb(vfb, document), vfbs_sxp)
771 map(vm.appendChild, vfbs)
773 # Platform variables...
775 platform = self.extract_platform(image, document)
777 map(vm.appendChild, platform)
779 # transient?
781 if transient:
782 other_config = document.createElement("other_config")
783 other_config.attributes["key"] = "transient"
784 other_config.attributes["value"] = "True"
785 vm.appendChild(other_config)
787 # Add it to doc_root
789 document.documentElement.appendChild(vm)
791 # We want to pull out vdis
793 vdis = map(lambda vdb: self.extract_vdi(vdb, document), vbds_sxp)
795 map(document.documentElement.appendChild, vdis)
797 return document
799 def make_name_tag(self, label_text, document):
800 name = document.createElement("name")
802 label = document.createElement("label")
803 label.appendChild(document.createTextNode(str(label_text)))
804 name.appendChild(label)
806 description = document.createElement("description")
807 description.appendChild(document.createTextNode(" "))
808 name.appendChild(description)
810 return name
812 def extract_vbd(self, vbd_sxp, document):
813 src = get_child_by_name(vbd_sxp, "uname")
814 mode = get_child_by_name(vbd_sxp, "mode")
815 name = str(src.__hash__())
817 vbd = document.createElement("vbd")
819 vbd.attributes["name"] = "vdb" + name
820 vbd.attributes["vdi"] = "vdi" + name
821 vbd.attributes["mode"] \
822 = re.search("^w!{0,1}$", mode) and "RW" or "RO"
823 vbd.attributes["device"] \
824 = re.sub(":cdrom$", "", get_child_by_name(vbd_sxp, "dev"))
825 vbd.attributes["bootable"] = "1"
826 vbd.attributes["type"] \
827 = re.search(":cdrom$", get_child_by_name(vbd_sxp, "dev")) \
828 and "CD" or "disk"
829 vbd.attributes["qos_algorithm_type"] = ""
831 return vbd
833 def extract_vdi(self, vbd_sxp, document):
834 src = get_child_by_name(vbd_sxp, "uname")
835 mode = get_child_by_name(vbd_sxp, "mode")
836 name = "vdi" + str(src.__hash__())
838 vdi = document.createElement("vdi")
840 vdi.attributes["src"] = src
841 vdi.attributes["read_only"] \
842 = re.search("^w!{0,1}$", mode) and "False" or "True"
843 vdi.attributes["size"] = '-1'
844 vdi.attributes["type"] = "system"
845 vdi.attributes["sharable"] \
846 = re.search("^w!$", mode) and "True" or "False"
847 vdi.attributes["name"] = name
849 vdi.appendChild(self.make_name_tag(name, document))
851 return vdi
853 def extract_vif(self, vif_sxp, document):
855 vif = document.createElement("vif")
857 dev = get_child_by_name(vif_sxp, "vifname", None)
859 if dev is None:
860 dev = self.getFreshEthDevice()
862 vif.attributes["name"] \
863 = "vif" + str(dev.__hash__())
864 vif.attributes["mac"] \
865 = get_child_by_name(vif_sxp, "mac", "")
866 vif.attributes["mtu"] \
867 = get_child_by_name(vif_sxp, "mtu", "")
868 vif.attributes["device"] = dev
869 vif.attributes["qos_algorithm_type"] = ""
871 policy = get_child_by_name(vif_sxp, "policy")
872 label = get_child_by_name(vif_sxp, "label")
874 vif.attributes["security_label"] = security.set_security_label(policy, label)
876 if get_child_by_name(vif_sxp, "bridge") is not None:
877 vif.attributes["network"] \
878 = get_child_by_name(vif_sxp, "bridge")
880 return vif
882 def extract_vtpm(self, vtpm_sxp, document):
884 vtpm = document.createElement("vtpm")
886 vtpm.attributes["backend"] \
887 = get_child_by_name(vtpm_sxp, "backend", "0")
889 return vtpm
891 def extract_vfb(self, vfb_sxp, document):
893 vfb = document.createElement("console")
894 vfb.attributes["protocol"] = "rfb"
896 if get_child_by_name(vfb_sxp, "type", "") == "vnc":
897 vfb.appendChild(self.mk_other_config(
898 "type", "vnc",
899 document))
900 vfb.appendChild(self.mk_other_config(
901 "vncunused", get_child_by_name(vfb_sxp, "vncunused", "1"),
902 document))
903 vfb.appendChild(self.mk_other_config(
904 "vnclisten",
905 get_child_by_name(vfb_sxp, "vnclisten", "127.0.0.1"),
906 document))
907 vfb.appendChild(self.mk_other_config(
908 "vncdisplay", get_child_by_name(vfb_sxp, "vncdisplay", "0"),
909 document))
910 vfb.appendChild(self.mk_other_config(
911 "vncpasswd", get_child_by_name(vfb_sxp, "vncpasswd", ""),
912 document))
914 if get_child_by_name(vfb_sxp, "type", "") == "sdl":
915 vfb.appendChild(self.mk_other_config(
916 "type", "sdl",
917 document))
918 vfb.appendChild(self.mk_other_config(
919 "display", get_child_by_name(vfb_sxp, "display", ""),
920 document))
921 vfb.appendChild(self.mk_other_config(
922 "xauthority",
923 get_child_by_name(vfb_sxp, "xauthority", ""),
924 document))
925 vfb.appendChild(self.mk_other_config(
926 "opengl", get_child_by_name(vfb_sxp, "opengl", "1"),
927 document))
929 return vfb
931 def extract_pcis(self, pcis_sxp, document):
933 pcis = []
935 for pci_sxp in pcis_sxp:
936 for dev_sxp in sxp.children(pci_sxp, "dev"):
937 pci = document.createElement("pci")
939 pci.attributes["domain"] \
940 = get_child_by_name(dev_sxp, "domain", "0")
941 pci.attributes["bus"] \
942 = get_child_by_name(dev_sxp, "bus", "0")
943 pci.attributes["slot"] \
944 = get_child_by_name(dev_sxp, "slot", "0")
945 pci.attributes["func"] \
946 = get_child_by_name(dev_sxp, "func", "0")
947 pci.attributes["vslot"] \
948 = get_child_by_name(dev_sxp, "vslot", "0")
949 for opt in pci_opts_list_from_sxp(dev_sxp):
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