Fixes removing inventory keys
[apex.git] / apex / virtual / virtual_utils.py
1 ##############################################################################
2 # Copyright (c) 2017 Tim Rozet (trozet@redhat.com) and others.
3 #
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 import copy
11 import iptc
12 import logging
13 import os
14 import platform
15 import pprint
16 import subprocess
17
18 from apex.common import utils
19 from apex.virtual import configure_vm as vm_lib
20 from virtualbmc import manager as vbmc_lib
21
22 DEFAULT_RAM = 8192
23 DEFAULT_PM_PORT = 6230
24 DEFAULT_USER = 'admin'
25 DEFAULT_PASS = 'password'
26 DEFAULT_VIRT_IP = '192.168.122.1'
27
28
29 def generate_inventory(target_file, ha_enabled=False, num_computes=1,
30                        controller_ram=DEFAULT_RAM, arch=platform.machine(),
31                        compute_ram=DEFAULT_RAM, vcpus=4):
32     """
33     Generates inventory file for virtual deployments
34     :param target_file:
35     :param ha_enabled:
36     :param num_computes:
37     :param controller_ram:
38     :param arch:
39     :param compute_ram:
40     :param vcpus:
41     :return:
42     """
43
44     node = {'mac_address': '',
45             'ipmi_ip': DEFAULT_VIRT_IP,
46             'ipmi_user': DEFAULT_USER,
47             'ipmi_pass': DEFAULT_PASS,
48             'pm_type': 'pxe_ipmitool',
49             'pm_port': '',
50             'cpu': vcpus,
51             'memory': DEFAULT_RAM,
52             'disk': 41,
53             'arch': arch,
54             'capabilities': ''
55             }
56
57     inv_output = {'nodes': {}}
58     if ha_enabled:
59         num_ctrlrs = 3
60     else:
61         num_ctrlrs = 1
62
63     for idx in range(num_ctrlrs + num_computes):
64         tmp_node = copy.deepcopy(node)
65         tmp_node['mac_address'] = vm_lib.generate_baremetal_macs(1)[0]
66         tmp_node['pm_port'] = DEFAULT_PM_PORT + idx
67         if idx < num_ctrlrs:
68             tmp_node['capabilities'] = 'profile:control'
69             tmp_node['memory'] = controller_ram
70         else:
71             tmp_node['capabilities'] = 'profile:compute'
72             tmp_node['memory'] = compute_ram
73         inv_output['nodes']['node{}'.format(idx)] = copy.deepcopy(tmp_node)
74
75     utils.dump_yaml(inv_output, target_file)
76
77     logging.info('Virtual environment file created: {}'.format(target_file))
78
79
80 def host_setup(node):
81     """
82     Handles configuring vmbc and firewalld/iptables
83     :param node: dictionary of domain names and ports for ipmi
84     :return:
85     """
86     vbmc_manager = vbmc_lib.VirtualBMCManager()
87     for name, port in node.items():
88         vbmc_manager.add(username=DEFAULT_USER, password=DEFAULT_PASS,
89                          port=port, address=DEFAULT_VIRT_IP, domain_name=name,
90                          libvirt_uri='qemu:///system',
91                          libvirt_sasl_password=False,
92                          libvirt_sasl_username=False)
93
94         # TODO(trozet): add support for firewalld
95         try:
96             subprocess.check_call(['systemctl', 'stop', 'firewalld'])
97             subprocess.check_call(['systemctl', 'restart', 'libvirtd'])
98         except subprocess.CalledProcessError:
99             logging.warning('Failed to stop firewalld and restart libvirtd')
100         # iptables rule
101         rule = iptc.Rule()
102         rule.protocol = 'udp'
103         match = rule.create_match('udp')
104         match.dport = str(port)
105         rule.add_match(match)
106         rule.target = iptc.Target(rule, "ACCEPT")
107         chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "INPUT")
108         chain.insert_rule(rule)
109         try:
110             subprocess.check_call(['vbmc', 'start', name])
111             logging.debug("Started vbmc for domain {}".format(name))
112         except subprocess.CalledProcessError:
113             logging.error("Failed to start vbmc for {}".format(name))
114             raise
115     logging.debug('vmbcs setup: {}'.format(vbmc_manager.list()))
116
117
118 def virt_customize(ops, target):
119     """
120     Helper function to virt customize disks
121     :param ops: list of of operations and arguments
122     :param target: target disk to modify
123     :return: None
124     """
125     logging.info("Virt customizing target disk: {}".format(target))
126     virt_cmd = ['virt-customize']
127     for op in ops:
128         for op_cmd, op_arg in op.items():
129             virt_cmd.append(op_cmd)
130             virt_cmd.append(op_arg)
131     virt_cmd.append('-a')
132     virt_cmd.append(target)
133     if not os.path.isfile(target):
134         raise FileNotFoundError
135     my_env = os.environ.copy()
136     my_env['LIBGUESTFS_BACKEND'] = 'direct'
137     logging.debug("Virt-customizing with: \n{}".format(virt_cmd))
138     try:
139         logging.debug(subprocess.check_output(virt_cmd, env=my_env,
140                                               stderr=subprocess.STDOUT))
141     except subprocess.CalledProcessError as e:
142         logging.error("Error executing virt-customize: {}".format(
143                       pprint.pformat(e.output)))
144         raise