1 ###############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 # szilard.cserey@ericsson.com
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ###############################################################################
11 from lxml import etree
12 from hardware_adapter import HardwareAdapter
23 DEV = {'pxe': 'network',
27 VOL_XML_TEMPLATE = '''<volume type='file'>
29 <capacity unit='{unit}'>{size!s}</capacity>
31 <format type='{format_type}'/>
35 DEFAULT_POOL = 'jenkins'
37 class LibvirtAdapter(HardwareAdapter):
39 def __init__(self, yaml_path):
40 super(LibvirtAdapter, self).__init__(yaml_path)
41 self.parser = etree.XMLParser(remove_blank_text=True)
43 def node_power_off(self, node_id):
44 vm_name = self.get_node_property(node_id, 'libvirtName')
45 log('Power OFF Node %s' % vm_name)
46 state = exec_cmd('virsh domstate %s' % vm_name)
47 if state == 'running':
48 exec_cmd('virsh destroy %s' % vm_name, False)
50 def node_power_on(self, node_id):
51 vm_name = self.get_node_property(node_id, 'libvirtName')
52 log('Power ON Node %s' % vm_name)
53 state = exec_cmd('virsh domstate %s' % vm_name)
54 if state == 'shut off':
55 exec_cmd('virsh start %s' % vm_name)
57 def node_reset(self, node_id):
58 vm_name = self.get_node_property(node_id, 'libvirtName')
59 log('Reset Node %s' % vm_name)
60 exec_cmd('virsh reset %s' % vm_name)
62 def translate(self, boot_order_list):
64 for boot_dev in boot_order_list:
66 translated.append(DEV[boot_dev])
68 err('Boot device %s not recognized' % boot_dev)
71 def node_set_boot_order(self, node_id, boot_order_list):
72 boot_order_list = self.translate(boot_order_list)
73 vm_name = self.get_node_property(node_id, 'libvirtName')
74 temp_dir = tempfile.mkdtemp()
75 log('Set boot order %s on Node %s' % (boot_order_list, vm_name))
76 resp = exec_cmd('virsh dumpxml %s' % vm_name)
77 xml_dump = etree.fromstring(resp, self.parser)
78 os = xml_dump.xpath('/domain/os')
80 for bootelem in ['boot', 'bootmenu']:
81 boot = o.xpath(bootelem)
84 for dev in boot_order_list:
85 b = etree.Element('boot')
88 bmenu = etree.Element('bootmenu')
89 bmenu.set('enable', 'no')
91 tree = etree.ElementTree(xml_dump)
92 xml_file = temp_dir + '/%s.xml' % vm_name
93 with open(xml_file, 'w') as f:
94 tree.write(f, pretty_print=True, xml_declaration=True)
95 exec_cmd('virsh define %s' % xml_file)
98 def node_zero_mbr(self, node_id):
99 vm_name = self.get_node_property(node_id, 'libvirtName')
100 resp = exec_cmd('virsh dumpxml %s' % vm_name)
101 xml_dump = etree.fromstring(resp)
102 disks = xml_dump.xpath('/domain/devices/disk')
104 if disk.get('device') == 'disk':
105 sources = disk.xpath('source')
106 for source in sources:
107 disk_file = source.get('file')
108 disk_size = exec_cmd('qemu-img info '
109 '%s |grep \"virtual size:\"'
110 % disk_file).split()[2]
112 exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_file,
115 def node_eject_iso(self, node_id):
116 vm_name = self.get_node_property(node_id, 'libvirtName')
117 device = self.get_name_of_device(vm_name, 'cdrom')
118 exec_cmd('virsh change-media %s --eject %s --config --live'
119 % (vm_name, device), False)
121 def node_insert_iso(self, node_id, iso_file):
122 vm_name = self.get_node_property(node_id, 'libvirtName')
123 device = self.get_name_of_device(vm_name, 'cdrom')
124 exec_cmd('virsh change-media %s --insert %s %s'
125 % (vm_name, device, iso_file))
127 def get_node_pxe_mac(self, node_id):
129 vm_name = self.get_node_property(node_id, 'libvirtName')
130 resp = exec_cmd('virsh dumpxml %s' % vm_name)
131 xml_dump = etree.fromstring(resp)
132 interfaces = xml_dump.xpath('/domain/devices/interface')
133 for interface in interfaces:
134 macs = interface.xpath('mac')
136 mac_list.append(mac.get('address').lower())
139 def get_name_of_device(self, vm_name, device_type):
140 resp = exec_cmd('virsh dumpxml %s' % vm_name)
141 xml_dump = etree.fromstring(resp)
142 disks = xml_dump.xpath('/domain/devices/disk')
144 if disk.get('device') == device_type:
145 targets = disk.xpath('target')
146 for target in targets:
147 device = target.get('dev')
151 def get_virt_net_conf_dir(self):
152 return self.dha_struct['virtNetConfDir']
154 def upload_iso(self, iso_file):
155 size = os.path.getsize(iso_file)
156 vol_name = os.path.basename(iso_file)
157 vol_xml = VOL_XML_TEMPLATE.format(name=vol_name, unit='bytes',
158 size=size, format_type='raw')
159 fd, fname = tempfile.mkstemp(text=True, suffix='deploy')
160 os.write(fd, vol_xml)
164 pool = DEFAULT_POOL # FIXME
165 exec_cmd('virsh vol-create --pool %s %s' % (pool, fname))
166 vol_path = exec_cmd('virsh vol-path --pool %s %s' % (pool, vol_name))
168 exec_cmd('virsh vol-upload %s %s' % (vol_path, iso_file),
169 attempts=5, delay=10, verbose=True)