ia64/xen-unstable

view tools/python/xen/xm/xenapi_create.py @ 19451:ef56cfbdd390

xenapi: Fix VDI:read_only, VDI:sharable and VBD:mode of XenAPI

I started a VM by using xm create, then I checked values of VDI
records and values of VBD records. When I gave the following disk
modes to a disk parameter, I got the following values from the records.

"r" "w" "w!"
VDI:read_only True True True <-- Always True!
VDI:sharable True True True <-- Always True!
VBD:mode RO RW RO
^^ <-- It should be RW.

This patch fixes the values of the records as follows.

"r" "w" "w!"
VDI:read_only True False False
VDI:sharable False False True
VBD:mode RO RW RW

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:31:08 2009 +0100 (2009-03-31)
parents 33270c9a3d2f
children 5c69f98c348e
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 import xen.util.xsm.xsm as security
31 import sys
32 import os
33 import traceback
34 import re
36 def log(_, msg):
37 #print "> " + msg
38 pass
40 DEBUG = 0
42 def get_name_label(node):
43 name_node = node.getElementsByTagName("name")[0]
44 label_node = name_node.getElementsByTagName("label")[0]
45 return " ".join([child.nodeValue for child in label_node.childNodes])
47 def get_name_description(node):
48 name_node = node.getElementsByTagName("name")[0]
49 description_node = name_node.getElementsByTagName("description")[0]
50 return " ".join([child.nodeValue for child in description_node.childNodes])
52 def get_text_in_child_node(node, child):
53 tag_node = node.getElementsByTagName(child)[0]
54 return " ".join([child.nodeValue for child in tag_node.childNodes])
56 def get_child_node_attribute(node, child, attribute):
57 tag_node = node.getElementsByTagName(child)[0]
58 return tag_node.attributes[attribute].value
60 def get_child_nodes_as_dict(node, child_name,
61 key_attribute_name,
62 value_attribute_name):
63 return dict([(child.attributes[key_attribute_name].value,
64 child.attributes[value_attribute_name].value)
65 for child in node.getElementsByTagName(child_name)])
67 def try_quietly(fn, *args):
68 try:
69 return fn(*args)
70 except:
71 return None
73 class xenapi_create:
75 def __init__(self):
76 self.DEFAULT_STORAGE_REPOSITORY = get_default_SR()
78 self.dtd = "/usr/share/xen/create.dtd"
80 def create(self, filename=None, document=None, skipdtd=False):
81 """
82 Create a domain from an XML file or DOM tree
83 """
84 if skipdtd:
85 print "Skipping DTD checks. Dangerous!"
87 if filename is not None:
88 if not skipdtd:
89 self.check_dtd(filename)
90 document = parse(filename)
91 elif document is not None:
92 if not skipdtd:
93 self.check_dom_against_dtd(document)
95 self.check_doc(document)
97 vdis = document.getElementsByTagName("vdi")
98 vdi_refs_dict = self.create_vdis(vdis)
100 networks = document.getElementsByTagName("network")
101 network_refs_dict = self.create_networks(networks)
103 try:
104 vms = document.getElementsByTagName("vm")
105 return self.create_vms(vms, vdi_refs_dict, network_refs_dict)
106 except Exception, exn:
107 try_quietly(self.cleanup_vdis(vdi_refs_dict))
108 raise exn
110 # Methods to check xml file
111 # try to use dtd to check where possible
112 def check_dtd(self, file):
113 """
114 Check file against DTD.
115 Use this if possible as it gives nice
116 error messages
117 """
118 dtd = xmldtd.load_dtd(self.dtd)
119 parser = xmlproc.XMLProcessor()
120 parser.set_application(xmlval.ValidatingApp(dtd, parser))
121 parser.dtd = dtd
122 parser.ent = dtd
123 parser.parse_resource(file)
125 def check_dom_against_dtd(self, dom):
126 """
127 Check DOM again DTD.
128 Doesn't give as nice error messages.
129 (no location info)
130 """
131 dtd = xmldtd.load_dtd(self.dtd)
132 app = xmlval.ValidatingApp(dtd, self)
133 app.set_locator(self)
134 self.dom2sax(dom, app)
136 # Get errors back from ValidatingApp
137 def report_error(self, number, args=None):
138 self.errors = xmlproc.errors.english
139 try:
140 msg = self.errors[number]
141 if args != None:
142 msg = msg % args
143 except KeyError:
144 msg = self.errors[4002] % number # Unknown err msg :-)
145 print msg
146 sys.exit(-1)
148 # Here for compatibility with ValidatingApp
149 def get_line(self):
150 return -1
152 def get_column(self):
153 return -1
155 def dom2sax(self, dom, app):
156 """
157 Take a dom tree and tarverse it,
158 issuing SAX calls to app.
159 """
160 for child in dom.childNodes:
161 if child.nodeType == child.TEXT_NODE:
162 data = child.nodeValue
163 app.handle_data(data, 0, len(data))
164 else:
165 app.handle_start_tag(
166 child.nodeName,
167 self.attrs_to_dict(child.attributes))
168 self.dom2sax(child, app)
169 app.handle_end_tag(child.nodeName)
171 def attrs_to_dict(self, attrs):
172 return dict(attrs.items())
174 #
175 # Checks which cannot be done with dtd
176 #
177 def check_doc(self, doc):
178 vms = doc.getElementsByTagName("vm")
179 self.check_vms(vms)
181 def check_vms(self, vms):
182 map(self.check_vm, vms)
184 def check_vm(self, vm):
185 vifs = vm.getElementsByTagName("vif")
186 self.check_vifs(vifs)
188 def check_vifs(self, vifs):
189 map(self.check_vif, vifs)
191 def check_vif(self, vif):
192 pass
194 # Cleanup methods here
195 def cleanup_vdis(self, vdi_refs_dict):
196 map(self.cleanup_vdi, vdi_refs_dict.values())
198 def cleanup_vdi(self, vdi_ref):
199 server.xenapi.VDI.destroy(vdi_ref)
201 def cleanup_vms(self, vm_refs):
202 map(self.cleanup_vm, vm_refs)
204 def cleanup_vm(self, vm_ref):
205 server.xenapi.VM.destroy(vm_ref)
207 # Create methods here
208 def create_vdis(self, vdis):
209 log(DEBUG, "create_vdis")
210 return dict(map(self.create_vdi, vdis))
212 def create_vdi(self, vdi):
213 log(DEBUG, "create_vdi")
215 vdi_record = {
216 "name_label": get_name_label(vdi),
217 "name_description": get_name_description(vdi),
218 "SR": self.DEFAULT_STORAGE_REPOSITORY,
219 "virtual_size": vdi.attributes["size"].value,
220 "type": vdi.attributes["type"].value,
221 "sharable": vdi.attributes["sharable"].value == "True",
222 "read_only": vdi.attributes["read_only"].value == "True",
223 "other_config": {"location":
224 vdi.attributes["src"].value}
225 }
227 key = vdi.attributes["name"].value
228 value = server.xenapi.VDI.create(vdi_record)
230 return (key, value)
232 def create_networks(self, networks):
233 log(DEBUG, "create_networks")
234 return dict(map(self.create_network, networks))
236 def create_network(self, network):
237 log(DEBUG, "create_network")
239 network_record = {
240 "name_label": get_name_label(network),
241 "name_description": get_name_description(network),
242 "other_config":
243 get_child_nodes_as_dict(network, "other_config",
244 "key", "value"),
245 "default_netmask": network.attributes["default_netmask"].value,
246 "default_gateway": network.attributes["default_gateway"].value
247 }
249 key = network.attributes["name"].value
250 value = server.xenapi.network.create(network_record)
252 return (key, value)
254 def create_vms(self, vms, vdis, networks):
255 log(DEBUG, "create_vms")
256 return map(lambda vm: self.create_vm(vm, vdis, networks), vms)
258 def create_vm(self, vm, vdis, networks):
259 log(DEBUG, "create_vm")
261 vm_record = {
262 "name_label":
263 get_name_label(vm),
264 "name_description":
265 get_name_description(vm),
266 "user_version":
267 get_text_in_child_node(vm, "version"),
268 "is_a_template":
269 vm.attributes["is_a_template"].value == 'true',
270 "auto_power_on":
271 vm.attributes["auto_power_on"].value == 'true',
272 "s3_integrity":
273 vm.attributes["s3_integrity"].value,
274 "memory_static_max":
275 get_child_node_attribute(vm, "memory", "static_max"),
276 "memory_static_min":
277 get_child_node_attribute(vm, "memory", "static_min"),
278 "memory_dynamic_max":
279 get_child_node_attribute(vm, "memory", "dynamic_max"),
280 "memory_dynamic_min":
281 get_child_node_attribute(vm, "memory", "dynamic_min"),
282 "VCPUs_params":
283 get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
284 "VCPUs_max":
285 vm.attributes["vcpus_max"].value,
286 "VCPUs_at_startup":
287 vm.attributes["vcpus_at_startup"].value,
288 "actions_after_shutdown":
289 vm.attributes["actions_after_shutdown"].value,
290 "actions_after_reboot":
291 vm.attributes["actions_after_reboot"].value,
292 "actions_after_crash":
293 vm.attributes["actions_after_crash"].value,
294 "platform":
295 get_child_nodes_as_dict(vm, "platform", "key", "value"),
296 "other_config":
297 get_child_nodes_as_dict(vm, "other_config", "key", "value"),
298 "PV_bootloader":
299 "",
300 "PV_kernel":
301 "",
302 "PV_ramdisk":
303 "",
304 "PV_args":
305 "",
306 "PV_bootloader_args":
307 "",
308 "HVM_boot_policy":
309 "",
310 "HVM_boot_params":
311 {},
312 "PCI_bus":
313 ""
314 }
316 if vm.attributes.has_key("security_label"):
317 vm_record.update({
318 "security_label":
319 vm.attributes["security_label"].value
320 })
322 if len(vm.getElementsByTagName("pv")) > 0:
323 vm_record.update({
324 "PV_bootloader":
325 get_child_node_attribute(vm, "pv", "bootloader"),
326 "PV_kernel":
327 get_child_node_attribute(vm, "pv", "kernel"),
328 "PV_ramdisk":
329 get_child_node_attribute(vm, "pv", "ramdisk"),
330 "PV_args":
331 get_child_node_attribute(vm, "pv", "args"),
332 "PV_bootloader_args":
333 get_child_node_attribute(vm, "pv", "bootloader_args")
334 })
335 else:
336 hvm = vm.getElementsByTagName("hvm")[0]
337 vm_record.update({
338 "HVM_boot_policy":
339 get_child_node_attribute(vm, "hvm", "boot_policy"),
340 "HVM_boot_params":
341 get_child_nodes_as_dict(hvm, "boot_param", "key", "value")
342 })
343 try:
344 vm_ref = server.xenapi.VM.create(vm_record)
345 except:
346 traceback.print_exc()
347 sys.exit(-1)
349 try:
350 # Now create vbds
352 vbds = vm.getElementsByTagName("vbd")
354 self.create_vbds(vm_ref, vbds, vdis)
356 # Now create vifs
358 vifs = vm.getElementsByTagName("vif")
360 self.create_vifs(vm_ref, vifs, networks)
362 # Now create vtpms
364 vtpms = vm.getElementsByTagName("vtpm")
366 self.create_vtpms(vm_ref, vtpms)
368 # Now create consoles
370 consoles = vm.getElementsByTagName("console")
372 self.create_consoles(vm_ref, consoles)
374 # Now create pcis
376 pcis = vm.getElementsByTagName("pci")
378 self.create_pcis(vm_ref, pcis)
380 # Now create scsis
382 scsis = vm.getElementsByTagName("vscsi")
384 self.create_scsis(vm_ref, scsis)
386 return vm_ref
387 except:
388 server.xenapi.VM.destroy(vm_ref)
389 raise
391 def create_vbds(self, vm_ref, vbds, vdis):
392 log(DEBUG, "create_vbds")
393 return map(lambda vbd: self.create_vbd(vm_ref, vbd, vdis), vbds)
395 def create_vbd(self, vm_ref, vbd, vdis):
396 log(DEBUG, "create_vbd")
398 vbd_record = {
399 "VM":
400 vm_ref,
401 "VDI":
402 vdis[vbd.attributes["vdi"].value],
403 "device":
404 vbd.attributes["device"].value,
405 "bootable":
406 vbd.attributes["bootable"].value == "1",
407 "mode":
408 vbd.attributes["mode"].value,
409 "type":
410 vbd.attributes["type"].value,
411 "qos_algorithm_type":
412 vbd.attributes["qos_algorithm_type"].value,
413 "qos_algorithm_params":
414 get_child_nodes_as_dict(vbd,
415 "qos_algorithm_param", "key", "value")
416 }
418 return server.xenapi.VBD.create(vbd_record)
420 def create_vifs(self, vm_ref, vifs, networks):
421 log(DEBUG, "create_vifs")
422 return map(lambda vif: self.create_vif(vm_ref, vif, networks), vifs)
424 def create_vif(self, vm_ref, vif, networks):
425 log(DEBUG, "create_vif")
427 if 'network' in vif.attributes.keys():
428 network_name = vif.attributes['network'].value
430 if network_name in networks.keys():
431 network_uuid = networks[network_name]
432 else:
433 networks = dict([(record['name_label'], ref)
434 for ref, record in
435 server.xenapi.network.get_all_records().items()])
436 if network_name in networks.keys():
437 network_uuid = networks[network_name]
438 else:
439 raise OptionError("Network %s doesn't exist"
440 % vif.attributes["network"].value)
441 else:
442 network_uuid = self._get_network_ref()
444 vif_record = {
445 "device":
446 vif.attributes["device"].value,
447 "network":
448 network_uuid,
449 "VM":
450 vm_ref,
451 "MAC":
452 vif.attributes["mac"].value,
453 "MTU":
454 vif.attributes["mtu"].value,
455 "qos_algorithm_type":
456 vif.attributes["qos_algorithm_type"].value,
457 "qos_algorithm_params":
458 get_child_nodes_as_dict(vif,
459 "qos_algorithm_param", "key", "value"),
460 "security_label":
461 vif.attributes["security_label"].value
462 }
464 return server.xenapi.VIF.create(vif_record)
466 _network_refs = []
468 def _get_network_ref(self):
469 try:
470 return self._network_refs.pop(0)
471 except IndexError:
472 self._network_refs = server.xenapi.network.get_all()
473 return self._network_refs.pop(0)
475 def create_vtpms(self, vm_ref, vtpms):
476 if len(vtpms) > 1:
477 vtpms = [ vtpms[0] ]
478 log(DEBUG, "create_vtpms")
479 return map(lambda vtpm: self.create_vtpm(vm_ref, vtpm), vtpms)
481 def create_vtpm(self, vm_ref, vtpm):
482 vtpm_record = {
483 "VM":
484 vm_ref,
485 "backend":
486 vtpm.attributes["backend"].value
487 }
488 return server.xenapi.VTPM.create(vtpm_record)
490 def create_consoles(self, vm_ref, consoles):
491 log(DEBUG, "create_consoles")
492 return map(lambda console: self.create_console(vm_ref, console),
493 consoles)
495 def create_console(self, vm_ref, console):
496 log(DEBUG, "create_consoles")
498 console_record = {
499 "VM":
500 vm_ref,
501 "protocol":
502 console.attributes["protocol"].value,
503 "other_config":
504 get_child_nodes_as_dict(console,
505 "other_config", "key", "value")
506 }
508 return server.xenapi.console.create(console_record)
510 def create_pcis(self, vm_ref, pcis):
511 log(DEBUG, "create_pcis")
512 return map(lambda pci: self.create_pci(vm_ref, pci), pcis)
514 def create_pci(self, vm_ref, pci):
515 log(DEBUG, "create_pci")
517 domain = int(pci.attributes["domain"].value, 16)
518 bus = int(pci.attributes["bus"].value, 16)
519 slot = int(pci.attributes["slot"].value, 16)
520 func = int(pci.attributes["func"].value, 16)
521 name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
523 target_ref = None
524 for ppci_ref in server.xenapi.PPCI.get_all():
525 if name == server.xenapi.PPCI.get_name(ppci_ref):
526 target_ref = ppci_ref
527 break
528 if target_ref is None:
529 log(DEBUG, "create_pci: pci device not found")
530 return None
532 dpci_record = {
533 "VM":
534 vm_ref,
535 "PPCI":
536 target_ref,
537 "hotplug_slot":
538 int(pci.attributes["func"].value, 16),
539 "options":
540 get_child_nodes_as_dict(pci,
541 "pci_opt", "key", "value")
542 }
544 return server.xenapi.DPCI.create(dpci_record)
546 def create_scsis(self, vm_ref, scsis):
547 log(DEBUG, "create_scsis")
548 return map(lambda scsi: self.create_scsi(vm_ref, scsi), scsis)
550 def create_scsi(self, vm_ref, scsi):
551 log(DEBUG, "create_scsi")
553 target_ref = None
554 for pscsi_ref in server.xenapi.PSCSI.get_all():
555 if scsi.attributes["p-dev"].value == server.xenapi.PSCSI.get_physical_HCTL(pscsi_ref):
556 target_ref = pscsi_ref
557 break
558 if target_ref is None:
559 log(DEBUG, "create_scsi: scsi device not found")
560 return None
562 dscsi_record = {
563 "VM":
564 vm_ref,
565 "PSCSI":
566 target_ref,
567 "virtual_HCTL":
568 scsi.attributes["v-dev"].value
569 }
571 return server.xenapi.DSCSI.create(dscsi_record)
573 def get_child_by_name(exp, childname, default = None):
574 try:
575 return [child for child in sxp.children(exp)
576 if child[0] == childname][0][1]
577 except:
578 return default
580 # Convert old sxp into new xml
582 class sxp2xml:
584 def convert_sxp_to_xml(self, config, transient=False):
586 devices = [child for child in sxp.children(config)
587 if len(child) > 0 and child[0] == "device"]
589 vbds_sxp = map(lambda x: x[1], [device for device in devices
590 if device[1][0] in ("vbd", "tap")])
592 vifs_sxp = map(lambda x: x[1], [device for device in devices
593 if device[1][0] == "vif"])
595 vtpms_sxp = map(lambda x: x[1], [device for device in devices
596 if device[1][0] == "vtpm"])
598 vfbs_sxp = map(lambda x: x[1], [device for device in devices
599 if device[1][0] == "vfb"])
601 pcis_sxp = map(lambda x: x[1], [device for device in devices
602 if device[1][0] == "pci"])
604 scsis_sxp = map(lambda x: x[1], [device for device in devices
605 if device[1][0] == "vscsi"])
607 # Create XML Document
609 impl = getDOMImplementation()
611 document = impl.createDocument(None, "xm", None)
613 # Lets make the VM tag..
615 vm = document.createElement("vm")
617 # Some string compatibility
619 actions_after_shutdown \
620 = get_child_by_name(config, "on_poweroff", "destroy")
621 actions_after_reboot \
622 = get_child_by_name(config, "on_reboot", "restart")
623 actions_after_crash \
624 = get_child_by_name(config, "on_crash", "restart")
626 def conv_chk(val, vals):
627 val.replace("-", "_")
628 if val not in vals:
629 raise "Invalid value: " + val
630 else:
631 return val
633 actions_after_shutdown = conv_chk(actions_after_shutdown,\
634 XEN_API_ON_NORMAL_EXIT)
635 actions_after_reboot = conv_chk(actions_after_reboot, \
636 XEN_API_ON_NORMAL_EXIT)
637 actions_after_crash = conv_chk(actions_after_crash, \
638 XEN_API_ON_CRASH_BEHAVIOUR)
639 # Flesh out tag attributes
641 vm.attributes["is_a_template"] = "false"
642 vm.attributes["auto_power_on"] = "false"
643 vm.attributes["actions_after_shutdown"] \
644 = actions_after_shutdown
645 vm.attributes["actions_after_reboot"] \
646 = actions_after_reboot
647 vm.attributes["actions_after_crash"] \
648 = actions_after_crash
649 vm.attributes["PCI_bus"] = ""
651 vm.attributes["vcpus_max"] \
652 = str(get_child_by_name(config, "vcpus", 1))
653 vm.attributes["vcpus_at_startup"] \
654 = str(get_child_by_name(config, "vcpus", 1))
655 vm.attributes["s3_integrity"] \
656 = str(get_child_by_name(config, "s3_integrity", 0))
658 sec_data = get_child_by_name(config, "security")
659 if sec_data:
660 try :
661 vm.attributes['security_label'] = \
662 security.set_security_label(sec_data[0][1][1],sec_data[0][2][1])
663 except Exception, e:
664 raise "Invalid security data format: %s" % str(sec_data)
666 # Make the name tag
668 vm.appendChild(self.make_name_tag(
669 get_child_by_name(config, "name"), document))
671 # Make version tag
673 version = document.createElement("version")
674 version.appendChild(document.createTextNode("0"))
675 vm.appendChild(version)
677 # Make pv or hvm tag
679 image = get_child_by_name(config, "image")
681 if image[0] == "linux":
682 pv = document.createElement("pv")
683 pv.attributes["kernel"] \
684 = get_child_by_name(image, "kernel", "")
685 pv.attributes["bootloader"] \
686 = get_child_by_name(config, "bootloader", "")
687 pv.attributes["ramdisk"] \
688 = get_child_by_name(image, "ramdisk", "")
689 pv.attributes["args"] \
690 = "root=" + get_child_by_name(image, "root", "") \
691 + " " + get_child_by_name(image, "args", "")
692 pv.attributes["bootloader_args"] \
693 = get_child_by_name(config, "bootloader_args","")
695 vm.appendChild(pv)
696 elif image[0] == "hvm":
697 hvm = document.createElement("hvm")
698 hvm.attributes["boot_policy"] = "BIOS order"
700 boot_order = document.createElement("boot_param")
701 boot_order.attributes["key"] = "order"
702 boot_order.attributes["value"] \
703 = get_child_by_name(image, "boot", "abcd")
704 hvm.appendChild
706 vm.appendChild(hvm)
708 # Make memory tag
710 memory = document.createElement("memory")
712 memory_str = str(int(
713 get_child_by_name(config, "memory"))*1024*1024)
715 memory.attributes["static_min"] = str(0)
716 memory.attributes["static_max"] = memory_str
717 memory.attributes["dynamic_min"] = memory_str
718 memory.attributes["dynamic_max"] = memory_str
720 if get_child_by_name(config, "maxmem"):
721 memory.attributes["static_max"] = \
722 str(int(get_child_by_name(config, "maxmem")*1024*1024))
724 vm.appendChild(memory)
726 # And now the vbds
728 vbds = map(lambda vbd: self.extract_vbd(vbd, document), vbds_sxp)
730 map(vm.appendChild, vbds)
732 # And now the vifs
734 vifs = map(lambda vif: self.extract_vif(vif, document), vifs_sxp)
736 map(vm.appendChild, vifs)
738 # And now the vTPMs
740 vtpms = map(lambda vtpm: self.extract_vtpm(vtpm, document), vtpms_sxp)
742 map(vm.appendChild, vtpms)
744 # And now the pcis
746 pcis = self.extract_pcis(pcis_sxp, document)
748 map(vm.appendChild, pcis)
750 # And now the scsis
752 scsis = self.extract_scsis(scsis_sxp, document)
754 map(vm.appendChild, scsis)
756 # Last but not least the consoles...
758 consoles = self.extract_consoles(image, document)
760 map(vm.appendChild, consoles)
762 vfbs = map(lambda vfb: self.extract_vfb(vfb, document), vfbs_sxp)
764 map(vm.appendChild, vfbs)
766 # Platform variables...
768 platform = self.extract_platform(image, document)
770 map(vm.appendChild, platform)
772 # transient?
774 if transient:
775 other_config = document.createElement("other_config")
776 other_config.attributes["key"] = "transient"
777 other_config.attributes["value"] = "True"
778 vm.appendChild(other_config)
780 # Add it to doc_root
782 document.documentElement.appendChild(vm)
784 # We want to pull out vdis
786 vdis = map(lambda vdb: self.extract_vdi(vdb, document), vbds_sxp)
788 map(document.documentElement.appendChild, vdis)
790 return document
792 def make_name_tag(self, label_text, document):
793 name = document.createElement("name")
795 label = document.createElement("label")
796 label.appendChild(document.createTextNode(str(label_text)))
797 name.appendChild(label)
799 description = document.createElement("description")
800 description.appendChild(document.createTextNode(" "))
801 name.appendChild(description)
803 return name
805 def extract_vbd(self, vbd_sxp, document):
806 src = get_child_by_name(vbd_sxp, "uname")
807 mode = get_child_by_name(vbd_sxp, "mode")
808 name = str(src.__hash__())
810 vbd = document.createElement("vbd")
812 vbd.attributes["name"] = "vdb" + name
813 vbd.attributes["vdi"] = "vdi" + name
814 vbd.attributes["mode"] \
815 = re.search("^w!{0,1}$", mode) and "RW" or "RO"
816 vbd.attributes["device"] \
817 = re.sub(":cdrom$", "", get_child_by_name(vbd_sxp, "dev"))
818 vbd.attributes["bootable"] = "1"
819 vbd.attributes["type"] \
820 = re.search(":cdrom$", get_child_by_name(vbd_sxp, "dev")) \
821 and "CD" or "disk"
822 vbd.attributes["qos_algorithm_type"] = ""
824 return vbd
826 def extract_vdi(self, vbd_sxp, document):
827 src = get_child_by_name(vbd_sxp, "uname")
828 mode = get_child_by_name(vbd_sxp, "mode")
829 name = "vdi" + str(src.__hash__())
831 vdi = document.createElement("vdi")
833 vdi.attributes["src"] = src
834 vdi.attributes["read_only"] \
835 = re.search("^w!{0,1}$", mode) and "False" or "True"
836 vdi.attributes["size"] = '-1'
837 vdi.attributes["type"] = "system"
838 vdi.attributes["sharable"] \
839 = re.search("^w!$", mode) and "True" or "False"
840 vdi.attributes["name"] = name
842 vdi.appendChild(self.make_name_tag(name, document))
844 return vdi
846 def extract_vif(self, vif_sxp, document):
848 vif = document.createElement("vif")
850 dev = get_child_by_name(vif_sxp, "vifname", None)
852 if dev is None:
853 dev = self.getFreshEthDevice()
855 vif.attributes["name"] \
856 = "vif" + str(dev.__hash__())
857 vif.attributes["mac"] \
858 = get_child_by_name(vif_sxp, "mac", "")
859 vif.attributes["mtu"] \
860 = get_child_by_name(vif_sxp, "mtu", "")
861 vif.attributes["device"] = dev
862 vif.attributes["qos_algorithm_type"] = ""
864 policy = get_child_by_name(vif_sxp, "policy")
865 label = get_child_by_name(vif_sxp, "label")
867 vif.attributes["security_label"] = security.set_security_label(policy, label)
869 if get_child_by_name(vif_sxp, "bridge") is not None:
870 vif.attributes["network"] \
871 = get_child_by_name(vif_sxp, "bridge")
873 return vif
875 def extract_vtpm(self, vtpm_sxp, document):
877 vtpm = document.createElement("vtpm")
879 vtpm.attributes["backend"] \
880 = get_child_by_name(vtpm_sxp, "backend", "0")
882 return vtpm
884 def extract_vfb(self, vfb_sxp, document):
886 vfb = document.createElement("console")
887 vfb.attributes["protocol"] = "rfb"
889 if get_child_by_name(vfb_sxp, "type", "") == "vnc":
890 vfb.appendChild(self.mk_other_config(
891 "type", "vnc",
892 document))
893 vfb.appendChild(self.mk_other_config(
894 "vncunused", get_child_by_name(vfb_sxp, "vncunused", "1"),
895 document))
896 vfb.appendChild(self.mk_other_config(
897 "vnclisten",
898 get_child_by_name(vfb_sxp, "vnclisten", "127.0.0.1"),
899 document))
900 vfb.appendChild(self.mk_other_config(
901 "vncdisplay", get_child_by_name(vfb_sxp, "vncdisplay", "0"),
902 document))
903 vfb.appendChild(self.mk_other_config(
904 "vncpasswd", get_child_by_name(vfb_sxp, "vncpasswd", ""),
905 document))
907 if get_child_by_name(vfb_sxp, "type", "") == "sdl":
908 vfb.appendChild(self.mk_other_config(
909 "type", "sdl",
910 document))
911 vfb.appendChild(self.mk_other_config(
912 "display", get_child_by_name(vfb_sxp, "display", ""),
913 document))
914 vfb.appendChild(self.mk_other_config(
915 "xauthority",
916 get_child_by_name(vfb_sxp, "xauthority", ""),
917 document))
918 vfb.appendChild(self.mk_other_config(
919 "opengl", get_child_by_name(vfb_sxp, "opengl", "1"),
920 document))
922 return vfb
924 def extract_pcis(self, pcis_sxp, document):
926 pcis = []
928 for pci_sxp in pcis_sxp:
929 for dev_sxp in sxp.children(pci_sxp, "dev"):
930 pci = document.createElement("pci")
932 pci.attributes["domain"] \
933 = get_child_by_name(dev_sxp, "domain", "0")
934 pci.attributes["bus"] \
935 = get_child_by_name(dev_sxp, "bus", "0")
936 pci.attributes["slot"] \
937 = get_child_by_name(dev_sxp, "slot", "0")
938 pci.attributes["func"] \
939 = get_child_by_name(dev_sxp, "func", "0")
940 pci.attributes["vslt"] \
941 = get_child_by_name(dev_sxp, "vslt", "0")
942 for opt in get_child_by_name(dev_sxp, "opts", ""):
943 if len(opt) > 0:
944 pci_opt = document.createElement("pci_opt")
945 pci_opt.attributes["key"] = opt[0]
946 pci_opt.attributes["value"] = opt[1]
947 pci.appendChild(pci_opt)
949 pcis.append(pci)
951 return pcis
953 def extract_scsis(self, scsis_sxp, document):
955 scsis = []
957 for scsi_sxp in scsis_sxp:
958 for dev_sxp in sxp.children(scsi_sxp, "dev"):
959 scsi = document.createElement("vscsi")
961 scsi.attributes["p-dev"] \
962 = get_child_by_name(dev_sxp, "p-dev")
963 scsi.attributes["v-dev"] \
964 = get_child_by_name(dev_sxp, "v-dev")
966 scsis.append(scsi)
968 return scsis
970 def mk_other_config(self, key, value, document):
971 other_config = document.createElement("other_config")
972 other_config.attributes["key"] = key
973 other_config.attributes["value"] = value
974 return other_config
976 def extract_consoles(self, image, document):
977 consoles = []
979 if int(get_child_by_name(image, "nographic", "1")) == 1:
980 return consoles
982 if int(get_child_by_name(image, "vnc", "0")) == 1:
983 console = document.createElement("console")
984 console.attributes["protocol"] = "rfb"
985 console.appendChild(self.mk_other_config(
986 "type", "vnc",
987 document))
988 console.appendChild(self.mk_other_config(
989 "vncunused", str(get_child_by_name(image, "vncunused", "1")),
990 document))
991 console.appendChild(self.mk_other_config(
992 "vnclisten",
993 get_child_by_name(image, "vnclisten", "127.0.0.1"),
994 document))
995 console.appendChild(self.mk_other_config(
996 "vncdisplay", str(get_child_by_name(image, "vncdisplay", "0")),
997 document))
998 console.appendChild(self.mk_other_config(
999 "vncpasswd", get_child_by_name(image, "vncpasswd", ""),
1000 document))
1001 consoles.append(console)
1002 if int(get_child_by_name(image, "sdl", "0")) == 1:
1003 console = document.createElement("console")
1004 console.attributes["protocol"] = "rfb"
1005 console.appendChild(self.mk_other_config(
1006 "type", "sdl",
1007 document))
1008 console.appendChild(self.mk_other_config(
1009 "display", get_child_by_name(image, "display", ""),
1010 document))
1011 console.appendChild(self.mk_other_config(
1012 "xauthority", get_child_by_name(image, "xauthority", ""),
1013 document))
1014 console.appendChild(self.mk_other_config(
1015 "opengl", str(get_child_by_name(image, "opengl", "1")),
1016 document))
1017 consoles.append(console)
1019 return consoles
1022 def extract_platform(self, image, document):
1024 platform_keys = [
1025 'acpi',
1026 'apic',
1027 'boot',
1028 'device_model',
1029 'loader',
1030 'fda',
1031 'fdb',
1032 'keymap',
1033 'isa',
1034 'localtime',
1035 'monitor',
1036 'pae',
1037 'rtc_timeoffset',
1038 'serial',
1039 'soundhw',
1040 'stdvga',
1041 'usb',
1042 'usbdevice',
1043 'hpet',
1044 'timer_mode',
1045 'vpt_align',
1046 'viridian',
1047 'vhpt',
1048 'guest_os_type',
1049 'hap',
1050 'pci_msitranslate',
1051 'pci_power_mgmt',
1052 'xen_platform_pci',
1055 platform_configs = []
1056 for key in platform_keys:
1057 value = get_child_by_name(image, key, None)
1058 if value is not None:
1059 platform = document.createElement("platform")
1060 platform.attributes["key"] = key
1061 platform.attributes["value"] = str(value)
1062 platform_configs.append(platform)
1064 return platform_configs
1066 _eths = -1
1068 def getFreshEthDevice(self):
1069 self._eths += 1
1070 return "eth%i" % self._eths