summaryrefslogtreecommitdiffstats
path: root/fuel/deploy/dha_adapters/libvirt_adapter.py
blob: 1eca548e0ef09028d527f4b23b2ddce08cd504d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import common
from lxml import etree
from hardware_adapter import HardwareAdapter

log = common.log
exec_cmd = common.exec_cmd
err = common.err

DEV = {'pxe': 'network',
       'disk': 'hd',
       'iso': 'cdrom'}

class LibvirtAdapter(HardwareAdapter):

    def __init__(self, yaml_path):
        super(LibvirtAdapter, self).__init__(yaml_path)
        self.parser = etree.XMLParser(remove_blank_text=True)

    def node_power_off(self, node_id):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        log('Power OFF Node %s' % vm_name)
        state = exec_cmd('virsh domstate %s' % vm_name)
        if state == 'running':
            exec_cmd('virsh destroy %s' % vm_name, False)

    def node_power_on(self, node_id):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        log('Power ON Node %s' % vm_name)
        state = exec_cmd('virsh domstate %s' % vm_name)
        if state == 'shut off':
            exec_cmd('virsh start %s' % vm_name)

    def node_reset(self, node_id):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        log('Reset Node %s' % vm_name)
        exec_cmd('virsh reset %s' % vm_name)

    def translate(self, boot_order_list):
        translated = []
        for boot_dev in boot_order_list:
            if boot_dev in DEV:
                translated.append(DEV[boot_dev])
            else:
                err('Boot device %s not recognized' % boot_dev)
        return translated

    def node_set_boot_order(self, node_id, boot_order_list):
        boot_order_list = self.translate(boot_order_list)
        vm_name = self.get_node_property(node_id, 'libvirtName')
        temp_dir = exec_cmd('mktemp -d')
        log('Set boot order %s on Node %s' % (boot_order_list, vm_name))
        resp = exec_cmd('virsh dumpxml %s' % vm_name)
        xml_dump = etree.fromstring(resp, self.parser)
        os = xml_dump.xpath('/domain/os')
        for o in os:
            for bootelem in ['boot', 'bootmenu']:
                boot = o.xpath(bootelem)
                for b in boot:
                    o.remove(b)
            for dev in boot_order_list:
                b = etree.Element('boot')
                b.set('dev', dev)
                o.append(b)
            bmenu = etree.Element('bootmenu')
            bmenu.set('enable', 'no')
            o.append(bmenu)
        tree = etree.ElementTree(xml_dump)
        xml_file = temp_dir + '/%s.xml' % vm_name
        with open(xml_file, 'w') as f:
            tree.write(f, pretty_print=True, xml_declaration=True)
        exec_cmd('virsh define %s' % xml_file)
        exec_cmd('rm -fr %s' % temp_dir)

    def node_zero_mbr(self, node_id):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        resp = exec_cmd('virsh dumpxml %s' % vm_name)
        xml_dump = etree.fromstring(resp)
        disks = xml_dump.xpath('/domain/devices/disk')
        for disk in disks:
            if disk.get('device') == 'disk':
                sources = disk.xpath('source')
                for source in sources:
                    disk_file = source.get('file')
                    disk_size = exec_cmd('ls -l %s' % disk_file).split()[4]
                    exec_cmd('rm -f %s' % disk_file)
                    exec_cmd('fallocate -l %s %s' % (disk_size, disk_file))

    def node_eject_iso(self, node_id):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        device = self.get_name_of_device(vm_name, 'cdrom')
        exec_cmd('virsh change-media %s --eject %s' % (vm_name, device), False)

    def node_insert_iso(self, node_id, iso_file):
        vm_name = self.get_node_property(node_id, 'libvirtName')
        device = self.get_name_of_device(vm_name, 'cdrom')
        exec_cmd('virsh change-media %s --insert %s %s'
                 % (vm_name, device, iso_file))

    def get_node_pxe_mac(self, node_id):
        mac_list = []
        vm_name = self.get_node_property(node_id, 'libvirtName')
        resp = exec_cmd('virsh dumpxml %s' % vm_name)
        xml_dump = etree.fromstring(resp)
        interfaces = xml_dump.xpath('/domain/devices/interface')
        for interface in interfaces:
            macs = interface.xpath('mac')
            for mac in macs:
                mac_list.append(mac.get('address').lower())
        return mac_list

    def get_name_of_device(self, vm_name, device_type):
        resp = exec_cmd('virsh dumpxml %s' % vm_name)
        xml_dump = etree.fromstring(resp)
        disks = xml_dump.xpath('/domain/devices/disk')
        for disk in disks:
            if disk.get('device') == device_type:
                targets = disk.xpath('target')
                for target in targets:
                    device = target.get('dev')
                    if device:
                        return device