Merge "Add create vm script and foreman config"
[genesis.git] / fuel / deploy / dha_adapters / libvirt_adapter.py
1 import common
2 from lxml import etree
3 from hardware_adapter import HardwareAdapter
4
5 log = common.log
6 exec_cmd = common.exec_cmd
7 err = common.err
8
9 DEV = {'pxe': 'network',
10        'disk': 'hd',
11        'iso': 'cdrom'}
12
13 class LibvirtAdapter(HardwareAdapter):
14
15     def __init__(self, yaml_path):
16         super(LibvirtAdapter, self).__init__(yaml_path)
17         self.parser = etree.XMLParser(remove_blank_text=True)
18
19     def node_power_off(self, node_id):
20         vm_name = self.get_node_property(node_id, 'libvirtName')
21         log('Power OFF Node %s' % vm_name)
22         state = exec_cmd('virsh domstate %s' % vm_name)
23         if state == 'running':
24             exec_cmd('virsh destroy %s' % vm_name, False)
25
26     def node_power_on(self, node_id):
27         vm_name = self.get_node_property(node_id, 'libvirtName')
28         log('Power ON Node %s' % vm_name)
29         state = exec_cmd('virsh domstate %s' % vm_name)
30         if state == 'shut off':
31             exec_cmd('virsh start %s' % vm_name)
32
33     def node_reset(self, node_id):
34         vm_name = self.get_node_property(node_id, 'libvirtName')
35         log('Reset Node %s' % vm_name)
36         exec_cmd('virsh reset %s' % vm_name)
37
38     def translate(self, boot_order_list):
39         translated = []
40         for boot_dev in boot_order_list:
41             if boot_dev in DEV:
42                 translated.append(DEV[boot_dev])
43             else:
44                 err('Boot device %s not recognized' % boot_dev)
45         return translated
46
47     def node_set_boot_order(self, node_id, boot_order_list):
48         boot_order_list = self.translate(boot_order_list)
49         vm_name = self.get_node_property(node_id, 'libvirtName')
50         temp_dir = exec_cmd('mktemp -d')
51         log('Set boot order %s on Node %s' % (boot_order_list, vm_name))
52         resp = exec_cmd('virsh dumpxml %s' % vm_name)
53         xml_dump = etree.fromstring(resp, self.parser)
54         os = xml_dump.xpath('/domain/os')
55         for o in os:
56             for bootelem in ['boot', 'bootmenu']:
57                 boot = o.xpath(bootelem)
58                 for b in boot:
59                     o.remove(b)
60             for dev in boot_order_list:
61                 b = etree.Element('boot')
62                 b.set('dev', dev)
63                 o.append(b)
64             bmenu = etree.Element('bootmenu')
65             bmenu.set('enable', 'no')
66             o.append(bmenu)
67         tree = etree.ElementTree(xml_dump)
68         xml_file = temp_dir + '/%s.xml' % vm_name
69         with open(xml_file, 'w') as f:
70             tree.write(f, pretty_print=True, xml_declaration=True)
71         exec_cmd('virsh define %s' % xml_file)
72         exec_cmd('rm -fr %s' % temp_dir)
73
74     def node_zero_mbr(self, node_id):
75         vm_name = self.get_node_property(node_id, 'libvirtName')
76         resp = exec_cmd('virsh dumpxml %s' % vm_name)
77         xml_dump = etree.fromstring(resp)
78         disks = xml_dump.xpath('/domain/devices/disk')
79         for disk in disks:
80             if disk.get('device') == 'disk':
81                 sources = disk.xpath('source')
82                 for source in sources:
83                     disk_file = source.get('file')
84                     disk_size = exec_cmd('ls -l %s' % disk_file).split()[4]
85                     exec_cmd('rm -f %s' % disk_file)
86                     exec_cmd('fallocate -l %s %s' % (disk_size, disk_file))
87
88     def node_eject_iso(self, node_id):
89         vm_name = self.get_node_property(node_id, 'libvirtName')
90         device = self.get_name_of_device(vm_name, 'cdrom')
91         exec_cmd('virsh change-media %s --eject %s' % (vm_name, device), False)
92
93     def node_insert_iso(self, node_id, iso_file):
94         vm_name = self.get_node_property(node_id, 'libvirtName')
95         device = self.get_name_of_device(vm_name, 'cdrom')
96         exec_cmd('virsh change-media %s --insert %s %s'
97                  % (vm_name, device, iso_file))
98
99     def get_node_pxe_mac(self, node_id):
100         mac_list = []
101         vm_name = self.get_node_property(node_id, 'libvirtName')
102         resp = exec_cmd('virsh dumpxml %s' % vm_name)
103         xml_dump = etree.fromstring(resp)
104         interfaces = xml_dump.xpath('/domain/devices/interface')
105         for interface in interfaces:
106             macs = interface.xpath('mac')
107             for mac in macs:
108                 mac_list.append(mac.get('address').lower())
109         return mac_list
110
111     def get_name_of_device(self, vm_name, device_type):
112         resp = exec_cmd('virsh dumpxml %s' % vm_name)
113         xml_dump = etree.fromstring(resp)
114         disks = xml_dump.xpath('/domain/devices/disk')
115         for disk in disks:
116             if disk.get('device') == device_type:
117                 targets = disk.xpath('target')
118                 for target in targets:
119                     device = target.get('dev')
120                     if device:
121                         return device