Changing raw to qcow2 for vFuel/Controller/Compute
[fuel.git] / deploy / dha_adapters / libvirt_adapter.py
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 ###############################################################################
9
10
11 from lxml import etree
12 from hardware_adapter import HardwareAdapter
13 import tempfile
14
15 from common import (
16     log,
17     exec_cmd,
18     err,
19     delete,
20 )
21
22 DEV = {'pxe': 'network',
23        'disk': 'hd',
24        'iso': 'cdrom'}
25
26
27 class LibvirtAdapter(HardwareAdapter):
28
29     def __init__(self, yaml_path):
30         super(LibvirtAdapter, self).__init__(yaml_path)
31         self.parser = etree.XMLParser(remove_blank_text=True)
32
33     def node_power_off(self, node_id):
34         vm_name = self.get_node_property(node_id, 'libvirtName')
35         log('Power OFF Node %s' % vm_name)
36         state = exec_cmd('virsh domstate %s' % vm_name)
37         if state == 'running':
38             exec_cmd('virsh destroy %s' % vm_name, False)
39
40     def node_power_on(self, node_id):
41         vm_name = self.get_node_property(node_id, 'libvirtName')
42         log('Power ON Node %s' % vm_name)
43         state = exec_cmd('virsh domstate %s' % vm_name)
44         if state == 'shut off':
45             exec_cmd('virsh start %s' % vm_name)
46
47     def node_reset(self, node_id):
48         vm_name = self.get_node_property(node_id, 'libvirtName')
49         log('Reset Node %s' % vm_name)
50         exec_cmd('virsh reset %s' % vm_name)
51
52     def translate(self, boot_order_list):
53         translated = []
54         for boot_dev in boot_order_list:
55             if boot_dev in DEV:
56                 translated.append(DEV[boot_dev])
57             else:
58                 err('Boot device %s not recognized' % boot_dev)
59         return translated
60
61     def node_set_boot_order(self, node_id, boot_order_list):
62         boot_order_list = self.translate(boot_order_list)
63         vm_name = self.get_node_property(node_id, 'libvirtName')
64         temp_dir = tempfile.mkdtemp()
65         log('Set boot order %s on Node %s' % (boot_order_list, vm_name))
66         resp = exec_cmd('virsh dumpxml %s' % vm_name)
67         xml_dump = etree.fromstring(resp, self.parser)
68         os = xml_dump.xpath('/domain/os')
69         for o in os:
70             for bootelem in ['boot', 'bootmenu']:
71                 boot = o.xpath(bootelem)
72                 for b in boot:
73                     o.remove(b)
74             for dev in boot_order_list:
75                 b = etree.Element('boot')
76                 b.set('dev', dev)
77                 o.append(b)
78             bmenu = etree.Element('bootmenu')
79             bmenu.set('enable', 'no')
80             o.append(bmenu)
81         tree = etree.ElementTree(xml_dump)
82         xml_file = temp_dir + '/%s.xml' % vm_name
83         with open(xml_file, 'w') as f:
84             tree.write(f, pretty_print=True, xml_declaration=True)
85         exec_cmd('virsh define %s' % xml_file)
86         delete(temp_dir)
87
88     def node_zero_mbr(self, node_id):
89         vm_name = self.get_node_property(node_id, 'libvirtName')
90         resp = exec_cmd('virsh dumpxml %s' % vm_name)
91         xml_dump = etree.fromstring(resp)
92         disks = xml_dump.xpath('/domain/devices/disk')
93         for disk in disks:
94             if disk.get('device') == 'disk':
95                 sources = disk.xpath('source')
96                 for source in sources:
97                     disk_file = source.get('file')
98                     disk_size = exec_cmd('qemu-img info '
99                                          '%s |grep \"virtual size:\"'
100                                          % disk_file).split()[2]
101                     delete(disk_file)
102                     exec_cmd('qemu-img create -f qcow2 %s %s' % (disk_file,
103                                                                  disk_size))
104
105     def node_eject_iso(self, node_id):
106         vm_name = self.get_node_property(node_id, 'libvirtName')
107         device = self.get_name_of_device(vm_name, 'cdrom')
108         exec_cmd('virsh change-media %s --eject %s --config --live'
109                  % (vm_name, device), False)
110
111     def node_insert_iso(self, node_id, iso_file):
112         vm_name = self.get_node_property(node_id, 'libvirtName')
113         device = self.get_name_of_device(vm_name, 'cdrom')
114         exec_cmd('virsh change-media %s --insert %s %s'
115                  % (vm_name, device, iso_file))
116
117     def get_node_pxe_mac(self, node_id):
118         mac_list = []
119         vm_name = self.get_node_property(node_id, 'libvirtName')
120         resp = exec_cmd('virsh dumpxml %s' % vm_name)
121         xml_dump = etree.fromstring(resp)
122         interfaces = xml_dump.xpath('/domain/devices/interface')
123         for interface in interfaces:
124             macs = interface.xpath('mac')
125             for mac in macs:
126                 mac_list.append(mac.get('address').lower())
127         return mac_list
128
129     def get_name_of_device(self, vm_name, device_type):
130         resp = exec_cmd('virsh dumpxml %s' % vm_name)
131         xml_dump = etree.fromstring(resp)
132         disks = xml_dump.xpath('/domain/devices/disk')
133         for disk in disks:
134             if disk.get('device') == device_type:
135                 targets = disk.xpath('target')
136                 for target in targets:
137                     device = target.get('dev')
138                     if device:
139                         return device
140
141     def get_virt_net_conf_dir(self):
142         return self.dha_struct['virtNetConfDir']