1 ##############################################################################
2 # Copyright (c) 2017 Tim Rozet (trozet@redhat.com) and others.
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 ##############################################################################
17 import xml.etree.ElementTree as ET
19 from apex.common import utils as common_utils
20 from apex.virtual import configure_vm as vm_lib
21 from apex.virtual import exceptions as exc
22 from time import sleep
23 from virtualbmc import manager as vbmc_lib
26 DEFAULT_PM_PORT = 6230
27 DEFAULT_USER = 'admin'
28 DEFAULT_PASS = 'password'
29 DEFAULT_VIRT_IP = '192.168.122.1'
34 virsh_net_xml = subprocess.check_output(['virsh', 'net-dumpxml',
36 stderr=subprocess.STDOUT)
37 except subprocess.CalledProcessError:
38 logging.warning('Unable to detect default virsh network IP. Will '
40 return DEFAULT_VIRT_IP
42 tree = ET.fromstring(virsh_net_xml)
43 ip_tag = tree.find('ip')
44 if ip_tag is not None:
45 virsh_ip = ip_tag.get('address')
47 logging.debug("Detected virsh default network ip: "
48 "{}".format(virsh_ip))
51 return DEFAULT_VIRT_IP
54 def generate_inventory(target_file, ha_enabled=False, num_computes=1,
55 controller_ram=DEFAULT_RAM, arch=platform.machine(),
56 compute_ram=DEFAULT_RAM, vcpus=4):
58 Generates inventory file for virtual deployments
62 :param controller_ram:
69 node = {'mac_address': '',
70 'ipmi_ip': get_virt_ip(),
71 'ipmi_user': DEFAULT_USER,
72 'ipmi_pass': DEFAULT_PASS,
73 'pm_type': 'pxe_ipmitool',
76 'memory': DEFAULT_RAM,
82 inv_output = {'nodes': {}}
88 for idx in range(num_ctrlrs + num_computes):
89 tmp_node = copy.deepcopy(node)
90 tmp_node['mac_address'] = vm_lib.generate_baremetal_macs(1)[0]
91 tmp_node['pm_port'] = DEFAULT_PM_PORT + idx
93 tmp_node['capabilities'] = 'profile:control'
94 tmp_node['memory'] = controller_ram
96 tmp_node['capabilities'] = 'profile:compute'
97 tmp_node['memory'] = compute_ram
98 inv_output['nodes']['node{}'.format(idx)] = copy.deepcopy(tmp_node)
100 common_utils.dump_yaml(inv_output, target_file)
101 logging.info('Virtual environment file created: {}'.format(target_file))
105 def host_setup(node):
107 Handles configuring vmbc and firewalld/iptables
108 :param node: dictionary of domain names and ports for ipmi
111 vbmc_manager = vbmc_lib.VirtualBMCManager()
112 for name, port in node.items():
113 vbmc_manager.add(username=DEFAULT_USER, password=DEFAULT_PASS,
114 port=port, address=get_virt_ip(), domain_name=name,
115 libvirt_uri='qemu:///system',
116 libvirt_sasl_password=False,
117 libvirt_sasl_username=False)
119 # TODO(trozet): add support for firewalld
121 subprocess.check_call(['systemctl', 'stop', 'firewalld'])
122 subprocess.check_call(['systemctl', 'restart', 'libvirtd'])
123 except subprocess.CalledProcessError:
124 logging.warning('Failed to stop firewalld and restart libvirtd')
127 rule.protocol = 'udp'
128 match = rule.create_match('udp')
129 match.dport = str(port)
130 rule.add_match(match)
131 rule.target = iptc.Target(rule, "ACCEPT")
132 chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "INPUT")
133 chain.insert_rule(rule)
135 subprocess.check_call(['vbmc', 'start', name])
136 logging.debug("Started VBMC for domain {}".format(name))
137 except subprocess.CalledProcessError:
138 logging.error("Failed to start VBMC for {}".format(name))
141 logging.info("Checking VBMC {} is up".format(name))
143 for x in range(0, 4):
144 logging.debug("Polling to see if VBMC is up, attempt {}".format(x))
146 output = subprocess.check_output(['vbmc', 'show', name],
147 stderr=subprocess.STDOUT)
148 except subprocess.CalledProcessError:
149 logging.warning('Unable to issue "vbmc show" cmd')
151 for line in output.decode('utf-8').split('\n'):
153 if 'running' in line:
157 logging.debug('VBMC status is not "running"')
163 logging.info("VBMC {} is up and running".format(name))
165 logging.error("Failed to verify VBMC is running")
166 raise exc.ApexVirtualException("Failed to bring up vbmc "
168 logging.debug('VBMCs setup: {}'.format(vbmc_manager.list()))
171 def virt_customize(ops, target):
173 Helper function to virt customize disks
174 :param ops: list of of operations and arguments
175 :param target: target disk to modify
178 logging.info("Virt customizing target disk: {}".format(target))
179 virt_cmd = ['virt-customize']
181 for op_cmd, op_arg in op.items():
182 virt_cmd.append(op_cmd)
183 virt_cmd.append(op_arg)
184 virt_cmd.append('-a')
185 virt_cmd.append(target)
186 if not os.path.isfile(target):
187 raise FileNotFoundError
188 my_env = os.environ.copy()
189 my_env['LIBGUESTFS_BACKEND'] = 'direct'
190 logging.debug("Virt-customizing with: \n{}".format(virt_cmd))
192 logging.debug(subprocess.check_output(virt_cmd, env=my_env,
193 stderr=subprocess.STDOUT))
194 except subprocess.CalledProcessError as e:
195 logging.error("Error executing virt-customize: {}".format(
196 pprint.pformat(e.output)))