diff options
Diffstat (limited to 'apex')
-rw-r--r-- | apex/build.py | 1 | ||||
-rw-r--r-- | apex/common/utils.py | 28 | ||||
-rw-r--r-- | apex/deploy.py | 10 | ||||
-rw-r--r-- | apex/overcloud/deploy.py | 15 | ||||
-rw-r--r-- | apex/tests/test_apex_overcloud_deploy.py | 17 | ||||
-rw-r--r-- | apex/tests/test_apex_undercloud.py | 15 | ||||
-rw-r--r-- | apex/tests/test_apex_virtual_utils.py | 20 | ||||
-rw-r--r-- | apex/undercloud/undercloud.py | 28 | ||||
-rw-r--r-- | apex/virtual/exceptions.py | 12 | ||||
-rw-r--r-- | apex/virtual/utils.py | 36 |
10 files changed, 165 insertions, 17 deletions
diff --git a/apex/build.py b/apex/build.py index 08f91abe..dff25ac8 100644 --- a/apex/build.py +++ b/apex/build.py @@ -225,6 +225,7 @@ def main(): console.setLevel(log_level) console.setFormatter(logging.Formatter(formatter)) logging.getLogger('').addHandler(console) + utils.install_ansible() # Since we only support building inside of git repo this should be fine try: apex_root = subprocess.check_output( diff --git a/apex/common/utils.py b/apex/common/utils.py index 13250a45..b727b11a 100644 --- a/apex/common/utils.py +++ b/apex/common/utils.py @@ -8,10 +8,12 @@ ############################################################################## import datetime +import distro import json import logging import os import pprint +import socket import subprocess import tarfile import time @@ -192,3 +194,29 @@ def fetch_upstream_and_unpack(dest, url, targets): tar = tarfile.open(target_dest) tar.extractall(path=dest) tar.close() + + +def install_ansible(): + # we only install for CentOS/Fedora for now + dist = distro.id() + if 'centos' in dist: + pkg_mgr = 'yum' + elif 'fedora' in dist: + pkg_mgr = 'dnf' + else: + return + + # yum python module only exists for 2.x, so use subprocess + try: + subprocess.check_call([pkg_mgr, '-y', 'install', 'ansible']) + except subprocess.CalledProcessError: + logging.warning('Unable to install Ansible') + + +def internet_connectivity(): + try: + urllib.request.urlopen('http://opnfv.org', timeout=3) + return True + except (urllib.request.URLError, socket.timeout): + logging.debug('No internet connectivity detected') + return False diff --git a/apex/deploy.py b/apex/deploy.py index d2f7d50b..5703e081 100644 --- a/apex/deploy.py +++ b/apex/deploy.py @@ -234,6 +234,7 @@ def main(): console.setLevel(log_level) console.setFormatter(logging.Formatter(formatter)) logging.getLogger('').addHandler(console) + utils.install_ansible() validate_deploy_args(args) # Parse all settings deploy_settings = DeploySettings(args.deploy_settings_file) @@ -381,7 +382,8 @@ def main(): args.deploy_dir, root_pw=root_pw, external_network=uc_external, - image_name=os.path.basename(uc_image)) + image_name=os.path.basename(uc_image), + os_version=os_version) undercloud.start() # Generate nic templates @@ -410,8 +412,8 @@ def main(): if not upstream: oc_deploy.prep_env(deploy_settings, net_settings, inventory, opnfv_env, net_env_target, APEX_TEMP_DIR) - oc_deploy.prep_image(deploy_settings, sdn_image, APEX_TEMP_DIR, - root_pw=root_pw) + oc_deploy.prep_image(deploy_settings, net_settings, sdn_image, + APEX_TEMP_DIR, root_pw=root_pw) else: shutil.copyfile(sdn_image, os.path.join(APEX_TEMP_DIR, 'overcloud-full.qcow2')) @@ -448,6 +450,8 @@ def main(): deploy_vars['overcloudrc'] = 'source /home/stack/overcloudrc' deploy_vars['upstream'] = upstream deploy_vars['os_version'] = os_version + deploy_vars['http_proxy'] = net_settings.get('http_proxy', '') + deploy_vars['https_proxy'] = net_settings.get('https_proxy', '') for dns_server in net_settings['dns_servers']: deploy_vars['dns_server_args'] += " --dns-nameserver {}".format( dns_server) diff --git a/apex/overcloud/deploy.py b/apex/overcloud/deploy.py index 19d46e15..5bbcaede 100644 --- a/apex/overcloud/deploy.py +++ b/apex/overcloud/deploy.py @@ -186,10 +186,11 @@ def create_deploy_cmd(ds, ns, inv, tmp_dir, return cmd -def prep_image(ds, img, tmp_dir, root_pw=None): +def prep_image(ds, ns, img, tmp_dir, root_pw=None): """ Locates sdn image and preps for deployment. :param ds: deploy settings + :param ns: network settings :param img: sdn image :param tmp_dir: dir to store modified sdn image :param root_pw: password to configure for overcloud image @@ -219,6 +220,18 @@ def prep_image(ds, img, tmp_dir, root_pw=None): ".service" }]) + if ns.get('http_proxy', ''): + virt_cmds.append({ + con.VIRT_RUN_CMD: + "echo 'http_proxy={}' >> /etc/environment".format( + ns['http_proxy'])}) + + if ns.get('https_proxy', ''): + virt_cmds.append({ + con.VIRT_RUN_CMD: + "echo 'https_proxy={}' >> /etc/environment".format( + ns['https_proxy'])}) + if ds_opts['vpn']: virt_cmds.append({con.VIRT_RUN_CMD: "chmod +x /etc/rc.d/rc.local"}) virt_cmds.append({ diff --git a/apex/tests/test_apex_overcloud_deploy.py b/apex/tests/test_apex_overcloud_deploy.py index 8ff98a8d..420a70d6 100644 --- a/apex/tests/test_apex_overcloud_deploy.py +++ b/apex/tests/test_apex_overcloud_deploy.py @@ -154,7 +154,8 @@ class TestOvercloudDeploy(unittest.TestCase): 'global_params': MagicMock()} ds['deploy_options'].__getitem__.side_effect = \ lambda i: ds_opts.get(i, MagicMock()) - prep_image(ds, 'undercloud.qcow2', '/tmp', root_pw='test') + ns = MagicMock() + prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test') mock_virt_utils.virt_customize.assert_called() @patch('apex.overcloud.deploy.virt_utils') @@ -169,7 +170,8 @@ class TestOvercloudDeploy(unittest.TestCase): 'global_params': MagicMock()} ds['deploy_options'].__getitem__.side_effect = \ lambda i: ds_opts.get(i, MagicMock()) - prep_image(ds, 'undercloud.qcow2', '/tmp', root_pw='test') + ns = MagicMock() + prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test') mock_virt_utils.virt_customize.assert_called() @patch('apex.overcloud.deploy.virt_utils') @@ -188,7 +190,8 @@ class TestOvercloudDeploy(unittest.TestCase): lambda i: ds_opts.get(i, MagicMock()) ds['deploy_options'].__contains__.side_effect = \ lambda i: True if i in ds_opts else MagicMock() - prep_image(ds, 'undercloud.qcow2', '/tmp', root_pw='test') + ns = MagicMock() + prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test') mock_virt_utils.virt_customize.assert_called() @patch('apex.overcloud.deploy.virt_utils') @@ -204,7 +207,8 @@ class TestOvercloudDeploy(unittest.TestCase): 'global_params': MagicMock()} ds['deploy_options'].__getitem__.side_effect = \ lambda i: ds_opts.get(i, MagicMock()) - prep_image(ds, 'undercloud.qcow2', '/tmp', root_pw='test') + ns = MagicMock() + prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test') mock_virt_utils.virt_customize.assert_called() @patch('apex.overcloud.deploy.virt_utils') @@ -219,14 +223,15 @@ class TestOvercloudDeploy(unittest.TestCase): 'global_params': MagicMock()} ds['deploy_options'].__getitem__.side_effect = \ lambda i: ds_opts.get(i, MagicMock()) - prep_image(ds, 'undercloud.qcow2', '/tmp', root_pw='test') + ns = MagicMock() + prep_image(ds, ns, 'undercloud.qcow2', '/tmp', root_pw='test') mock_virt_utils.virt_customize.assert_called() @patch('apex.overcloud.deploy.os.path.isfile') def test_prep_image_no_image(self, mock_isfile): mock_isfile.return_value = False assert_raises(ApexDeployException, prep_image, - {}, 'undercloud.qcow2', '/tmp') + {}, {}, 'undercloud.qcow2', '/tmp') def test_make_ssh_key(self): priv, pub = make_ssh_key() diff --git a/apex/tests/test_apex_undercloud.py b/apex/tests/test_apex_undercloud.py index c821ade5..0df785f9 100644 --- a/apex/tests/test_apex_undercloud.py +++ b/apex/tests/test_apex_undercloud.py @@ -197,3 +197,18 @@ class TestUndercloud(unittest.TestCase): ds = {'global_params': {}} Undercloud('img_path', 'tplt_path').generate_config(ns, ds) + + @patch.object(Undercloud, '_get_vm', return_value=None) + @patch.object(Undercloud, 'create') + @patch('apex.undercloud.undercloud.virt_utils') + def test_update_delorean(self, mock_vutils, mock_uc_create, mock_get_vm): + uc = Undercloud('img_path', 'tmplt_path', external_network=True) + uc._update_delorean_repo() + download_cmd = ( + "curl -L -f -o " + "/etc/yum.repos.d/deloran.repo " + "https://trunk.rdoproject.org/centos7-{}" + "/current-tripleo/delorean.repo".format( + constants.DEFAULT_OS_VERSION)) + test_ops = {'--run-command': download_cmd} + mock_vutils.virt_customize.assert_called_with(test_ops, uc.volume) diff --git a/apex/tests/test_apex_virtual_utils.py b/apex/tests/test_apex_virtual_utils.py index 643069f3..a9eb78dd 100644 --- a/apex/tests/test_apex_virtual_utils.py +++ b/apex/tests/test_apex_virtual_utils.py @@ -12,6 +12,7 @@ import unittest from mock import patch +from apex.virtual.exceptions import ApexVirtualException from apex.virtual.utils import DEFAULT_VIRT_IP from apex.virtual.utils import get_virt_ip from apex.virtual.utils import generate_inventory @@ -66,13 +67,30 @@ class TestVirtualUtils(unittest.TestCase): assert_is_instance(generate_inventory('target_file', ha_enabled=True), dict) + @patch('apex.virtual.utils.get_virt_ip') + @patch('apex.virtual.utils.subprocess.check_output') @patch('apex.virtual.utils.iptc') @patch('apex.virtual.utils.subprocess.check_call') @patch('apex.virtual.utils.vbmc_lib') - def test_host_setup(self, mock_vbmc_lib, mock_subprocess, mock_iptc): + def test_host_setup(self, mock_vbmc_lib, mock_subprocess, mock_iptc, + mock_check_output, mock_get_virt_ip): + mock_get_virt_ip.return_value = '192.168.122.1' + mock_check_output.return_value = b'blah |dummy \nstatus | running' host_setup({'test': 2468}) mock_subprocess.assert_called_with(['vbmc', 'start', 'test']) + @patch('apex.virtual.utils.get_virt_ip') + @patch('apex.virtual.utils.subprocess.check_output') + @patch('apex.virtual.utils.iptc') + @patch('apex.virtual.utils.subprocess.check_call') + @patch('apex.virtual.utils.vbmc_lib') + def test_host_setup_vbmc_fails(self, mock_vbmc_lib, mock_subprocess, + mock_iptc, mock_check_output, + mock_get_virt_ip): + mock_get_virt_ip.return_value = '192.168.122.1' + mock_check_output.return_value = b'blah |dummy \nstatus | stopped' + assert_raises(ApexVirtualException, host_setup, {'test': 2468}) + @patch('apex.virtual.utils.iptc') @patch('apex.virtual.utils.subprocess.check_call') @patch('apex.virtual.utils.vbmc_lib') diff --git a/apex/undercloud/undercloud.py b/apex/undercloud/undercloud.py index d28ed981..915c85f3 100644 --- a/apex/undercloud/undercloud.py +++ b/apex/undercloud/undercloud.py @@ -31,8 +31,10 @@ class Undercloud: """ def __init__(self, image_path, template_path, root_pw=None, external_network=False, - image_name='undercloud.qcow2'): + 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, @@ -73,6 +75,7 @@ class Undercloud: template_dir=self.template_path) self.setup_volumes() self.inject_auth() + self._update_delorean_repo() def _set_ip(self): ip_out = self.vm.interfaceAddresses( @@ -202,8 +205,9 @@ class Undercloud: "undercloud_update_packages false", "undercloud_debug false", "inspection_extras false", - "ipxe {}".format(str(ds['global_params'].get('ipxe', True) and - not config['aarch64'])), + "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]), @@ -236,4 +240,22 @@ class Undercloud: "enabled": ns_external['enabled'] } + 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") diff --git a/apex/virtual/exceptions.py b/apex/virtual/exceptions.py new file mode 100644 index 00000000..e3dff51a --- /dev/null +++ b/apex/virtual/exceptions.py @@ -0,0 +1,12 @@ +############################################################################## +# Copyright (c) 2018 Tim Rozet (trozet@redhat.com) and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +class ApexVirtualException(Exception): + pass diff --git a/apex/virtual/utils.py b/apex/virtual/utils.py index 226af1b5..8b24bc40 100644 --- a/apex/virtual/utils.py +++ b/apex/virtual/utils.py @@ -18,6 +18,8 @@ import xml.etree.ElementTree as ET from apex.common import utils as common_utils from apex.virtual import configure_vm as vm_lib +from apex.virtual import exceptions as exc +from time import sleep from virtualbmc import manager as vbmc_lib DEFAULT_RAM = 8192 @@ -131,11 +133,39 @@ def host_setup(node): chain.insert_rule(rule) try: subprocess.check_call(['vbmc', 'start', name]) - logging.debug("Started vbmc for domain {}".format(name)) + logging.debug("Started VBMC for domain {}".format(name)) except subprocess.CalledProcessError: - logging.error("Failed to start vbmc for {}".format(name)) + logging.error("Failed to start VBMC for {}".format(name)) raise - logging.debug('vmbcs setup: {}'.format(vbmc_manager.list())) + + logging.info("Checking VBMC {} is up".format(name)) + is_running = False + for x in range(0, 4): + logging.debug("Polling to see if VBMC is up, attempt {}".format(x)) + try: + output = subprocess.check_output(['vbmc', 'show', name], + stderr=subprocess.STDOUT) + except subprocess.CalledProcessError: + logging.warning('Unable to issue "vbmc show" cmd') + continue + for line in output.decode('utf-8').split('\n'): + if 'status' in line: + if 'running' in line: + is_running = True + break + else: + logging.debug('VBMC status is not "running"') + break + if is_running: + break + sleep(1) + if is_running: + logging.info("VBMC {} is up and running".format(name)) + else: + logging.error("Failed to verify VBMC is running") + raise exc.ApexVirtualException("Failed to bring up vbmc " + "{}".format(name)) + logging.debug('VBMCs setup: {}'.format(vbmc_manager.list())) def virt_customize(ops, target): |