Install prerequisites for undercloud deploy
Address the tech debt introduced in the quickstart-extras undercloud-deploy role. Move installation of the packages into the 'openstack undercloud deploy' prerequisites phase, executed as a separate deployment step. Add new flag --install-kolla, defaults to False. If enabled, adds the openatack-kolla package to the prerequisites. Add release notes for undercloud deploy. Add missing python-heat-agent-ansible prerequisite. Change-Id: I54445b73891ff414acc6d3323aa378243d4d655f Signed-off-by: Bogdan Dobrelya <bdobreli@redhat.com>
This commit is contained in:
parent
be2a20637a
commit
dcaecb4dad
@ -0,0 +1,13 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
EXPERIMENTAL feature to install the undercloud with openstack heat
|
||||
add support for a containerized undercloud. It checks for prequisites
|
||||
and installs missing packages then deploys undercloud with heat-all.
|
||||
|
||||
- |
|
||||
New flag `--install-kolla`, defaults to False. Adds or removes Kolla
|
||||
packages to/from the list of required packages to be installed by the
|
||||
``openstack undercloud deploy`` command. Set it to True, if you want
|
||||
to build Kolla containers on the undercloud node as the part of your
|
||||
continuous deployment pipeline.
|
@ -15,6 +15,7 @@
|
||||
|
||||
import mock
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
||||
|
||||
@ -35,6 +36,8 @@ class TestUndercloudDeploy(TestPluginV1):
|
||||
|
||||
# Get the command object to test
|
||||
self.cmd = undercloud_deploy.DeployUndercloud(self.app, None)
|
||||
# Substitute required packages
|
||||
self.cmd.prerequisites = iter(['foo', 'bar', 'baz'])
|
||||
|
||||
@mock.patch('os.path.exists')
|
||||
@mock.patch('tripleo_common.utils.passwords.generate_passwords')
|
||||
@ -83,3 +86,42 @@ class TestUndercloudDeploy(TestPluginV1):
|
||||
mock_dump.assert_called_once_with(expected_dict,
|
||||
mock_open_handle,
|
||||
default_flow_style=False)
|
||||
|
||||
@mock.patch('subprocess.check_call', autospec=True)
|
||||
def test_install_prerequisites(self, mock_check_call):
|
||||
mock_check_call.side_effect = [
|
||||
True, subprocess.CalledProcessError(1, ''), True,
|
||||
subprocess.CalledProcessError(1, ''), True]
|
||||
arglist = ['--install-kolla']
|
||||
verifylist = [('install_kolla', True)]
|
||||
cmd_parser = self.cmd.get_parser('check_parser')
|
||||
parsed_args = cmd_parser.parse_args(arglist)
|
||||
self.check_parser(self.cmd, arglist, verifylist)
|
||||
self.cmd._install_prerequisites(parsed_args.install_kolla)
|
||||
|
||||
mock_check_call.assert_has_calls([
|
||||
mock.call(['rpm', '-q', 'foo']),
|
||||
mock.call(['rpm', '-q', 'bar']),
|
||||
mock.call(['rpm', '-q', 'baz']),
|
||||
mock.call(['rpm', '-q', 'openstack-kolla']),
|
||||
mock.call(['yum', '-y', 'install', 'bar', 'openstack-kolla'])
|
||||
])
|
||||
|
||||
@mock.patch('subprocess.check_call', autospec=True)
|
||||
def test_fail_prerequisites(self, mock_check_call):
|
||||
mock_check_call.side_effect = [
|
||||
True, subprocess.CalledProcessError(127, ''), True, True]
|
||||
arglist = []
|
||||
verifylist = []
|
||||
cmd_parser = self.cmd.get_parser('check_parser')
|
||||
parsed_args = cmd_parser.parse_args(arglist)
|
||||
self.check_parser(self.cmd, arglist, verifylist)
|
||||
try:
|
||||
self.cmd._install_prerequisites(parsed_args.install_kolla)
|
||||
except Exception as e:
|
||||
self.assertTrue('Failed to check for prerequisites: '
|
||||
'bar, the exit status 127' in str(e))
|
||||
|
||||
mock_check_call.assert_has_calls([
|
||||
mock.call(['rpm', '-q', 'foo']),
|
||||
mock.call(['rpm', '-q', 'bar'])])
|
||||
|
@ -15,6 +15,7 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import logging
|
||||
import netaddr
|
||||
import os
|
||||
@ -47,17 +48,64 @@ from tripleoclient import heat_launcher
|
||||
|
||||
from tripleo_common.utils import passwords as password_utils
|
||||
|
||||
# TODO(bogdando) rework the list by real requirements for the
|
||||
# heat-container-image vs heat-native cases
|
||||
REQUIRED_PACKAGES = iter([
|
||||
'openstack-heat-api',
|
||||
'openstack-heat-engine',
|
||||
'openstack-heat-monolith',
|
||||
'python-heat-agent',
|
||||
'python-heat-agent-apply-config',
|
||||
'python-heat-agent-hiera',
|
||||
'python-heat-agent-puppet',
|
||||
'python-heat-agent-docker-cmd',
|
||||
'python-heat-agent-json-file',
|
||||
'python-heat-agent-ansible',
|
||||
'python-ipaddr',
|
||||
'python-tripleoclient',
|
||||
'docker',
|
||||
'openvswitch',
|
||||
'openstack-puppet-modules',
|
||||
'yum-plugin-priorities',
|
||||
'openstack-tripleo-common',
|
||||
'openstack-tripleo-heat-templates',
|
||||
'deltarpm'
|
||||
])
|
||||
|
||||
|
||||
class DeployUndercloud(command.Command):
|
||||
"""Deploy Undercloud (experimental feature)"""
|
||||
|
||||
log = logging.getLogger(__name__ + ".DeployUndercloud")
|
||||
auth_required = False
|
||||
prerequisites = REQUIRED_PACKAGES
|
||||
|
||||
def _get_hostname(self):
|
||||
p = subprocess.Popen(["hostname", "-s"], stdout=subprocess.PIPE)
|
||||
return p.communicate()[0].rstrip()
|
||||
|
||||
def _install_prerequisites(self, add_kolla):
|
||||
print('Checking for installed prerequisites ...')
|
||||
processed = []
|
||||
if add_kolla:
|
||||
self.prerequisites = itertools.chain(
|
||||
self.prerequisites, ['openstack-kolla'])
|
||||
|
||||
for p in self.prerequisites:
|
||||
try:
|
||||
subprocess.check_call(['rpm', '-q', p])
|
||||
except subprocess.CalledProcessError as e:
|
||||
if e.returncode == 1:
|
||||
processed.append(p)
|
||||
elif e.returncode != 0:
|
||||
raise Exception('Failed to check for prerequisites: '
|
||||
'%s, the exit status %s'
|
||||
% (p, e.returncode))
|
||||
|
||||
if len(processed) > 0:
|
||||
print('Installing prerequisites ...')
|
||||
subprocess.check_call(['yum', '-y', 'install'] + processed)
|
||||
|
||||
def _lookup_tripleo_server_stackid(self, client, stack_id):
|
||||
server_stack_id = None
|
||||
|
||||
@ -415,6 +463,14 @@ class DeployUndercloud(command.Command):
|
||||
dest='keep_running',
|
||||
help=_('Keep the process running on failures for debugging')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--install-kolla',
|
||||
action='store_true',
|
||||
dest='install_kolla',
|
||||
default=False,
|
||||
help=_('Require Kolla packages to be installed for building'
|
||||
'containers from the undercloud node')
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
@ -444,6 +500,9 @@ class DeployUndercloud(command.Command):
|
||||
if os.geteuid() != 0:
|
||||
raise exceptions.DeploymentError("Please run as root.")
|
||||
|
||||
# Install required packages
|
||||
self._install_prerequisites(parsed_args.install_kolla)
|
||||
|
||||
keystone_pid = self._fork_fake_keystone()
|
||||
|
||||
# we do this as root to chown config files properly for docker, etc.
|
||||
|
Loading…
Reference in New Issue
Block a user