Autodeploy inspired on Prototype #2
[genesis.git] / fuel / deploy / setup_environment.py
1 import sys
2 from lxml import etree
3 import os
4 import glob
5 import common
6
7 from dha import DeploymentHardwareAdapter
8
9 exec_cmd = common.exec_cmd
10 err = common.err
11 log = common.log
12 check_dir_exists = common.check_dir_exists
13 check_file_exists = common.check_file_exists
14 check_if_root = common.check_if_root
15
16
17 class LibvirtEnvironment(object):
18
19     def __init__(self, storage_dir, dha_file):
20         self.dha = DeploymentHardwareAdapter(dha_file)
21         self.storage_dir = storage_dir
22         self.parser = etree.XMLParser(remove_blank_text=True)
23         self.file_dir = os.path.dirname(os.path.realpath(__file__))
24         self.network_dir = '%s/libvirt/networks' % self.file_dir
25         self.vm_dir = '%s/libvirt/vms' % self.file_dir
26         self.node_ids = self.dha.get_all_node_ids()
27         self.fuel_node_id = self.dha.get_fuel_node_id()
28         self.net_names = self.collect_net_names()
29
30     def create_storage(self, node_id, disk_path, disk_sizes):
31         if node_id == self.fuel_node_id:
32            disk_size = disk_sizes['fuel']
33         else:
34            role = self.dha.get_node_role(node_id)
35            disk_size = disk_sizes[role]
36         exec_cmd('fallocate -l %s %s' % (disk_size, disk_path))
37
38     def create_vms(self):
39         temp_dir = exec_cmd('mktemp -d')
40         disk_sizes = self.dha.get_disks()
41         for node_id in self.node_ids:
42             vm_name = self.dha.get_node_property(node_id, 'libvirtName')
43             vm_template = self.dha.get_node_property(node_id,
44                                                      'libvirtTemplate')
45             disk_path = '%s/%s.raw' % (self.storage_dir, vm_name)
46             self.create_storage(node_id, disk_path, disk_sizes)
47             self.define_vm(vm_name, vm_template, temp_dir, disk_path)
48         exec_cmd('rm -fr %s' % temp_dir)
49
50     def define_vm(self, vm_name, vm_template, temp_dir, disk_path):
51         log('Creating VM %s with disks %s' % (vm_name, disk_path))
52         temp_vm_file = '%s/%s' % (temp_dir, vm_name)
53         exec_cmd('cp %s/%s %s' % (self.vm_dir, vm_template, temp_vm_file))
54         with open(temp_vm_file) as f:
55             vm_xml = etree.parse(f)
56             names = vm_xml.xpath('/domain/name')
57             for name in names:
58                 name.text = vm_name
59             uuids = vm_xml.xpath('/domain/uuid')
60             for uuid in uuids:
61                 uuid.getparent().remove(uuid)
62             disks = vm_xml.xpath('/domain/devices/disk')
63             for disk in disks:
64                 sources = disk.xpath('source')
65                 for source in sources:
66                     source.set('file', disk_path)
67         with open(temp_vm_file, 'w') as f:
68             vm_xml.write(f, pretty_print=True, xml_declaration=True)
69         exec_cmd('virsh define %s' % temp_vm_file)
70
71     def create_networks(self):
72         for net_file in glob.glob('%s/*' % self.network_dir):
73             exec_cmd('virsh net-define %s' % net_file)
74         for net in self.net_names:
75             log('Creating network %s' % net)
76             exec_cmd('virsh net-autostart %s' % net)
77             exec_cmd('virsh net-start %s' % net)
78
79     def delete_networks(self):
80         for net in self.net_names:
81             log('Deleting network %s' % net)
82             exec_cmd('virsh net-destroy %s' % net, False)
83             exec_cmd('virsh net-undefine %s' % net, False)
84
85     def get_net_name(self, net_file):
86         with open(net_file) as f:
87             net_xml = etree.parse(f)
88             name_list = net_xml.xpath('/network/name')
89             for name in name_list:
90                 net_name = name.text
91         return net_name
92
93     def collect_net_names(self):
94         net_list = []
95         for net_file in glob.glob('%s/*' % self.network_dir):
96             name = self.get_net_name(net_file)
97             net_list.append(name)
98         return net_list
99
100     def delete_vms(self):
101         for node_id in self.node_ids:
102             vm_name = self.dha.get_node_property(node_id, 'libvirtName')
103             r, c = exec_cmd('virsh dumpxml %s' % vm_name, False)
104             if c > 0:
105                 log(r)
106                 continue
107             self.undefine_vm_delete_disk(r, vm_name)
108
109     def undefine_vm_delete_disk(self, printout, vm_name):
110         disk_files = []
111         xml_dump = etree.fromstring(printout, self.parser)
112         disks = xml_dump.xpath('/domain/devices/disk')
113         for disk in disks:
114             sources = disk.xpath('source')
115             for source in sources:
116                 source_file = source.get('file')
117                 if source_file:
118                     disk_files.append(source_file)
119         log('Deleting VM %s with disks %s' % (vm_name, disk_files))
120         exec_cmd('virsh destroy %s' % vm_name, False)
121         exec_cmd('virsh undefine %s' % vm_name, False)
122         for file in disk_files:
123             exec_cmd('rm -f %s' % file)
124
125     def setup_environment(self):
126         check_if_root()
127         check_dir_exists(self.network_dir)
128         check_dir_exists(self.vm_dir)
129         self.cleanup_environment()
130         self.create_vms()
131         self.create_networks()
132
133     def cleanup_environment(self):
134         self.delete_vms()
135         self.delete_networks()
136
137
138 def usage():
139     print '''
140     Usage:
141     python setup_environment.py <storage_directory> <dha_file>
142
143     Example:
144             python setup_environment.py /mnt/images dha.yaml
145     '''
146
147 def parse_arguments():
148     if len(sys.argv) != 3:
149         log('Incorrect number of arguments')
150         usage()
151         sys.exit(1)
152     storage_dir = sys.argv[-2]
153     dha_file = sys.argv[-1]
154     check_dir_exists(storage_dir)
155     check_file_exists(dha_file)
156     return storage_dir, dha_file
157
158 def main():
159     storage_dir, dha_file = parse_arguments()
160
161     virt = LibvirtEnvironment(storage_dir, dha_file)
162     virt.setup_environment()
163
164 if __name__ == '__main__':
165     main()