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:
Bogdan Dobrelya 2017-06-08 13:22:38 +02:00
parent be2a20637a
commit dcaecb4dad
3 changed files with 114 additions and 0 deletions

View File

@ -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.

View File

@ -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'])])

View File

@ -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.