X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=apex%2Fundercloud%2Fundercloud.py;h=e799d3716dac6ad6773ca89007b47273738be72d;hb=f6dbb3929d904b4d5a9ee01f8270051e29ac1ec3;hp=a1af4d00674dc6b8e814be909cd02db7cdb73c8d;hpb=0c78953b8184255eba2c55316bc6cbb746796a5f;p=apex.git diff --git a/apex/undercloud/undercloud.py b/apex/undercloud/undercloud.py index a1af4d00..e799d371 100644 --- a/apex/undercloud/undercloud.py +++ b/apex/undercloud/undercloud.py @@ -10,10 +10,12 @@ import libvirt import logging import os +import platform import shutil +import subprocess import time -from apex.virtual import virtual_utils as virt_utils +from apex.virtual import utils as virt_utils from apex.virtual import configure_vm as vm_lib from apex.common import constants from apex.common import utils @@ -28,13 +30,17 @@ class Undercloud: This class represents an Apex Undercloud VM """ def __init__(self, image_path, template_path, - root_pw=None, external_network=False): + root_pw=None, external_network=False, + image_name='undercloud.qcow2', + os_version=constants.DEFAULT_OS_VERSION): self.ip = None + self.os_version = os_version self.root_pw = root_pw self.external_net = external_network self.volume = os.path.join(constants.LIBVIRT_VOLUME_PATH, 'undercloud.qcow2') self.image_path = image_path + self.image_name = image_name self.template_path = template_path self.vm = None if Undercloud._get_vm(): @@ -56,16 +62,20 @@ class Undercloud: networks = ['admin'] if self.external_net: networks.append('external') + console = 'ttyAMA0' if platform.machine() == 'aarch64' else 'ttyS0' + root = 'vda' if platform.machine() == 'aarch64' else 'sda' + self.vm = vm_lib.create_vm(name='undercloud', image=self.volume, baremetal_interfaces=networks, direct_boot='overcloud-full', - kernel_args=['console=ttyS0', - 'root=/dev/sda'], + kernel_args=['console={}'.format(console), + 'root=/dev/{}'.format(root)], default_network=True, template_dir=self.template_path) self.setup_volumes() self.inject_auth() + self._update_delorean_repo() def _set_ip(self): ip_out = self.vm.interfaceAddresses( @@ -104,35 +114,56 @@ class Undercloud: "Unable to find IP for undercloud. Check if VM booted " "correctly") - def configure(self, net_settings, playbook, apex_temp_dir): + def configure(self, net_settings, deploy_settings, + playbook, apex_temp_dir, virtual_oc=False): """ Configures undercloud VM - :return: + :param net_settings: Network settings for deployment + :param deploy_settings: Deployment settings for deployment + :param playbook: playbook to use to configure undercloud + :param apex_temp_dir: temporary apex directory to hold configs/logs + :param virtual_oc: Boolean to determine if overcloud is virt + :return: None """ - # TODO(trozet): If undercloud install fails we can add a retry + logging.info("Configuring Undercloud...") # run ansible - ansible_vars = Undercloud.generate_config(net_settings) + ansible_vars = Undercloud.generate_config(net_settings, + deploy_settings) ansible_vars['apex_temp_dir'] = apex_temp_dir - utils.run_ansible(ansible_vars, playbook, host=self.ip, user='stack') + ansible_vars['virtual_overcloud'] = virtual_oc + try: + utils.run_ansible(ansible_vars, playbook, host=self.ip, + user='stack') + except subprocess.CalledProcessError: + logging.error( + "Failed to install undercloud..." + "please check log: {}".format(os.path.join( + apex_temp_dir, 'apex-undercloud-install.log'))) + raise ApexUndercloudException('Failed to install undercloud') logging.info("Undercloud installed!") def setup_volumes(self): for img_file in ('overcloud-full.vmlinuz', 'overcloud-full.initrd', - 'undercloud.qcow2'): + self.image_name): src_img = os.path.join(self.image_path, img_file) - dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, img_file) + if img_file == self.image_name: + dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, + 'undercloud.qcow2') + else: + dest_img = os.path.join(constants.LIBVIRT_VOLUME_PATH, + img_file) if not os.path.isfile(src_img): raise ApexUndercloudException( "Required source file does not exist:{}".format(src_img)) if os.path.exists(dest_img): os.remove(dest_img) shutil.copyfile(src_img, dest_img) - + shutil.chown(dest_img, user='qemu', group='qemu') + os.chmod(dest_img, 0o0744) # TODO(trozet):check if resize needed right now size is 50gb # there is a lib called vminspect which has some dependencies and is # not yet available in pip. Consider switching to this lib later. - # execute ansible playbook def inject_auth(self): virt_ops = list() @@ -157,20 +188,28 @@ class Undercloud: virt_utils.virt_customize(virt_ops, self.volume) @staticmethod - def generate_config(ns): + def generate_config(ns, ds): """ Generates a dictionary of settings for configuring undercloud :param ns: network settings to derive undercloud settings + :param ds: deploy settings to derive undercloud settings :return: dictionary of settings """ ns_admin = ns['networks']['admin'] intro_range = ns['apex']['networks']['admin']['introspection_range'] config = dict() + # Check if this is an ARM deployment + config['aarch64'] = platform.machine() == 'aarch64' + # Configuration for undercloud.conf config['undercloud_config'] = [ "enable_ui false", "undercloud_update_packages false", "undercloud_debug false", + "inspection_extras false", + "ipxe_enabled {}".format( + str(ds['global_params'].get('ipxe', True) and + not config['aarch64'])), "undercloud_hostname undercloud.{}".format(ns['dns-domain']), "local_ip {}/{}".format(str(ns_admin['installer_vm']['ip']), str(ns_admin['cidr']).split('/')[1]), @@ -202,8 +241,32 @@ class Undercloud: "prefix": str(ns_external['cidr']).split('/')[1], "enabled": ns_external['enabled'] } - - # FIXME (trozet): for now hardcoding aarch64 to false - config['aarch64'] = False + # TODO(trozet): clean this logic up and merge with above + if 'external' in ns.enabled_network_list: + nat_cidr = ns_external['cidr'] + else: + nat_cidr = ns['networks']['admin']['cidr'] + config['nat_cidr'] = str(nat_cidr) + if nat_cidr.version == 6: + config['nat_network_ipv6'] = True + else: + config['nat_network_ipv6'] = False + config['http_proxy'] = ns.get('http_proxy', '') + config['https_proxy'] = ns.get('https_proxy', '') return config + + def _update_delorean_repo(self): + if utils.internet_connectivity(): + logging.info('Updating delorean repo on Undercloud') + delorean_repo = ( + "https://trunk.rdoproject.org/centos7-{}" + "/current-tripleo/delorean.repo".format(self.os_version)) + cmd = ("curl -L -f -o " + "/etc/yum.repos.d/deloran.repo {}".format(delorean_repo)) + try: + virt_utils.virt_customize({constants.VIRT_RUN_CMD: cmd}, + self.volume) + except Exception: + logging.warning("Failed to download and update delorean repo " + "for Undercloud")