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 mock
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
from tripleoclient.tests.v1.test_plugin import TestPluginV1
|
||||||
|
|
||||||
@ -35,6 +36,8 @@ class TestUndercloudDeploy(TestPluginV1):
|
|||||||
|
|
||||||
# Get the command object to test
|
# Get the command object to test
|
||||||
self.cmd = undercloud_deploy.DeployUndercloud(self.app, None)
|
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('os.path.exists')
|
||||||
@mock.patch('tripleo_common.utils.passwords.generate_passwords')
|
@mock.patch('tripleo_common.utils.passwords.generate_passwords')
|
||||||
@ -83,3 +86,42 @@ class TestUndercloudDeploy(TestPluginV1):
|
|||||||
mock_dump.assert_called_once_with(expected_dict,
|
mock_dump.assert_called_once_with(expected_dict,
|
||||||
mock_open_handle,
|
mock_open_handle,
|
||||||
default_flow_style=False)
|
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
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import itertools
|
||||||
import logging
|
import logging
|
||||||
import netaddr
|
import netaddr
|
||||||
import os
|
import os
|
||||||
@ -47,17 +48,64 @@ from tripleoclient import heat_launcher
|
|||||||
|
|
||||||
from tripleo_common.utils import passwords as password_utils
|
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):
|
class DeployUndercloud(command.Command):
|
||||||
"""Deploy Undercloud (experimental feature)"""
|
"""Deploy Undercloud (experimental feature)"""
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + ".DeployUndercloud")
|
log = logging.getLogger(__name__ + ".DeployUndercloud")
|
||||||
auth_required = False
|
auth_required = False
|
||||||
|
prerequisites = REQUIRED_PACKAGES
|
||||||
|
|
||||||
def _get_hostname(self):
|
def _get_hostname(self):
|
||||||
p = subprocess.Popen(["hostname", "-s"], stdout=subprocess.PIPE)
|
p = subprocess.Popen(["hostname", "-s"], stdout=subprocess.PIPE)
|
||||||
return p.communicate()[0].rstrip()
|
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):
|
def _lookup_tripleo_server_stackid(self, client, stack_id):
|
||||||
server_stack_id = None
|
server_stack_id = None
|
||||||
|
|
||||||
@ -415,6 +463,14 @@ class DeployUndercloud(command.Command):
|
|||||||
dest='keep_running',
|
dest='keep_running',
|
||||||
help=_('Keep the process running on failures for debugging')
|
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
|
return parser
|
||||||
|
|
||||||
def take_action(self, parsed_args):
|
def take_action(self, parsed_args):
|
||||||
@ -444,6 +500,9 @@ class DeployUndercloud(command.Command):
|
|||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
raise exceptions.DeploymentError("Please run as root.")
|
raise exceptions.DeploymentError("Please run as root.")
|
||||||
|
|
||||||
|
# Install required packages
|
||||||
|
self._install_prerequisites(parsed_args.install_kolla)
|
||||||
|
|
||||||
keystone_pid = self._fork_fake_keystone()
|
keystone_pid = self._fork_fake_keystone()
|
||||||
|
|
||||||
# we do this as root to chown config files properly for docker, etc.
|
# we do this as root to chown config files properly for docker, etc.
|
||||||
|
Loading…
Reference in New Issue
Block a user