Skip to content
Permalink
Browse files

Implement minor update workflow with config download

This change aim to refactor the way of doing the minor upgrade
via ansible playbook download by the config download
It will depend on a mistral change which will get the
ansible update_task and run it via mistral
The user will have two ways for performing the minor update:
  - the stack update command which will make an automatic minor
    upgrade (or just upgrade a given set of nodes)
  - running it manually via ansible on the undercloud

Closes-Bug: #1715557
Closes-Bug: #1723108
Change-Id: I4fcd443d975894a1da0286b19506d00682c5768c
  • Loading branch information...
matbu committed Jul 26, 2017
1 parent 9fb4314 commit 8a7da9fe26e8b8db6ee26dfdae940f36c9b55488
@@ -93,7 +93,6 @@ openstack.tripleoclient.v1 =
overcloud_role_list = tripleoclient.v1.overcloud_roles:RoleList
overcloud_roles_generate = tripleoclient.v1.overcloud_roles:RolesGenerate
overcloud_support_report_collect = tripleoclient.v1.overcloud_support:ReportExecute
overcloud_update_clear_breakpoints = tripleoclient.v1.overcloud_update:ClearBreakpointsOvercloud
overcloud_update_stack = tripleoclient.v1.overcloud_update:UpdateOvercloud
overcloud_execute = tripleoclient.v1.overcloud_execute:RemoteExecute
overcloud_generate_fencing = tripleoclient.v1.overcloud_parameters:GenerateFencingParameters

This file was deleted.

@@ -10,15 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.

import fixtures
import mock
import os

from mock import call
from mock import patch
from osc_lib.tests import utils

from tripleoclient.tests.v1.overcloud_config import fakes
from tripleoclient.v1 import overcloud_config


@@ -32,138 +27,14 @@ def setUp(self):
self.app.client_manager.orchestration = mock.Mock()
self.workflow = self.app.client_manager.workflow_engine

@patch.object(overcloud_config.DownloadConfig, '_mkdir')
@patch.object(overcloud_config.DownloadConfig, '_open_file')
@mock.patch('tempfile.mkdtemp', autospec=True)
def test_overcloud_config_generate_config(self,
mock_tmpdir,
mock_open,
mock_mkdir):
@mock.patch('tripleo_common.utils.config.Config.download_config')
def test_overcloud_download_config(self, mock_config):
arglist = ['--name', 'overcloud', '--config-dir', '/tmp']
verifylist = [
('name', 'overcloud'),
('config_dir', '/tmp')
]
config_type_list = ['config_settings', 'global_config_settings',
'logging_sources', 'monitoring_subscriptions',
'service_config_settings',
'service_metadata_settings',
'service_names',
'upgrade_batch_tasks', 'upgrade_tasks']
fake_role = [role for role in
fakes.FAKE_STACK['outputs'][1]['output_value']]

parsed_args = self.check_parser(self.cmd, arglist, verifylist)
clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_tmpdir.return_value = "/tmp/tht"
self.cmd.take_action(parsed_args)
expected_mkdir_calls = [call('/tmp/tht/%s' % r) for r in fake_role]
mock_mkdir.assert_has_calls(expected_mkdir_calls, any_order=True)
expected_calls = []
for config in config_type_list:
for role in fake_role:
if config == 'step_config':
expected_calls += [call('/tmp/tht/%s/%s.pp' %
(role, config))]
else:
expected_calls += [call('/tmp/tht/%s/%s.yaml' %
(role, config))]
mock_open.assert_has_calls(expected_calls, any_order=True)

@patch.object(overcloud_config.DownloadConfig, '_mkdir')
@patch.object(overcloud_config.DownloadConfig, '_open_file')
@mock.patch('tempfile.mkdtemp', autospec=True)
def test_overcloud_config_one_config_type(self,
mock_tmpdir,
mock_open,
mock_mkdir):

arglist = ['--name', 'overcloud', '--config-dir', '/tmp',
'--config-type', ['config_settings']]
verifylist = [
('name', 'overcloud'),
('config_dir', '/tmp'),
('config_type', ['config_settings'])
]
expected_config_type = 'config_settings'
fake_role = [role for role in
fakes.FAKE_STACK['outputs'][1]['output_value']]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)

clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_tmpdir.return_value = "/tmp/tht"
self.cmd.take_action(parsed_args)
expected_mkdir_calls = [call('/tmp/tht/%s' % r) for r in fake_role]
expected_calls = [call('/tmp/tht/%s/%s.yaml'
% (r, expected_config_type))
for r in fake_role]
mock_mkdir.assert_has_calls(expected_mkdir_calls, any_order=True)
mock_open.assert_has_calls(expected_calls, any_order=True)

@mock.patch('os.mkdir')
@mock.patch('six.moves.builtins.open')
@mock.patch('tempfile.mkdtemp', autospec=True)
def test_overcloud_config_wrong_config_type(self, mock_tmpdir,
mock_open, mock_mkdir):

arglist = [
'--name', 'overcloud',
'--config-dir',
'/tmp', '--config-type', ['bad_config']]
verifylist = [
('name', 'overcloud'),
('config_dir', '/tmp'),
('config_type', ['bad_config'])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
clients = self.app.client_manager
mock_tmpdir.return_value = "/tmp/tht"
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
self.assertRaises(
KeyError,
self.cmd.take_action, parsed_args)

@mock.patch('tripleoclient.utils.get_role_data', autospec=True)
def test_overcloud_config_upgrade_tasks(self, mock_get_role_data):

clients = self.app.client_manager
orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
self.tmp_dir = self.useFixture(fixtures.TempDir()).path
fake_role = [role for role in
fakes.FAKE_STACK['outputs'][1]['output_value']]
expected_tasks = {'FakeController': [{'name': 'Stop fake service',
'service': 'name=fake '
'state=stopped',
'tags': 'step1',
'when': 'step|int == 1'}],
'FakeCompute': [{'name': 'Stop fake service',
'service':
'name=fake state=stopped',
'tags': 'step1',
'when': ['existingcondition',
'step|int == 1']},
{'name': 'Stop nova-'
'compute service',
'service':
'name=openstack-nova-'
'compute state=stopped',
'tags': 'step1',
'when': ['existing',
'list', 'step|int == 1']}]}
mock_get_role_data.return_value = fake_role

for role in fake_role:
filedir = os.path.join(self.tmp_dir, role)
os.makedirs(filedir)
filepath = os.path.join(filedir, "upgrade_tasks_playbook.yaml")
playbook_tasks = self.cmd._write_playbook_get_tasks(
fakes.FAKE_STACK['outputs'][1]['output_value'][role]
['upgrade_tasks'], role, filepath)
self.assertTrue(os.path.isfile(filepath))
self.assertEqual(expected_tasks[role], playbook_tasks)
mock_config.assert_called_once_with('overcloud', '/tmp', None)
@@ -14,6 +14,7 @@
#

import mock
import uuid

from tripleoclient import exceptions
from tripleoclient.tests.v1.overcloud_update import fakes
@@ -30,44 +31,89 @@ def setUp(self):
app_args.verbose_level = 1
self.cmd = overcloud_update.UpdateOvercloud(self.app, app_args)

uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4")
self.mock_uuid4 = uuid4_patcher.start()
self.addCleanup(self.mock_uuid4.stop)

@mock.patch('tripleoclient.utils.get_stack',
autospec=True)
@mock.patch('tripleoclient.v1.overcloud_update.UpdateOvercloud.log',
autospec=True)
@mock.patch('tripleoclient.workflows.package_update.update_and_wait',
@mock.patch('tripleoclient.workflows.package_update.update',
autospec=True)
def test_update_out(self, mock_update_wait, mock_logger, mock_get_stack):
mock_update_wait.return_value = 'COMPLETE'
@mock.patch('six.moves.builtins.open')
@mock.patch('os.path.abspath')
@mock.patch('yaml.load')
def test_update_out(self, mock_yaml, mock_abspath, mock_open, mock_update,
mock_logger, mock_get_stack):
mock_stack = mock.Mock()
mock_stack.stack_name = 'mystack'
mock_get_stack.return_value = mock_stack
# mock_logger.return_value = mock.Mock()

argslist = ['overcloud', '-i', '--templates']
mock_abspath.return_value = '/home/fake/my-fake-registry.yaml'
mock_yaml.return_value = {'fake_container': 'fake_value'}
argslist = ['--stack', 'overcloud', '--init-minor-update',
'--container-registry-file', 'my-fake-registry.yaml']
verifylist = [
('stack', 'overcloud'),
('interactive', True),
('templates', '/usr/share/openstack-tripleo-heat-templates/')
('init_minor_update', True),
('container_registry_file', 'my-fake-registry.yaml')
]

parsed_args = self.check_parser(self.cmd, argslist, verifylist)
self.cmd.take_action(parsed_args)
mock_update_wait.assert_called_once_with(
mock_logger,
mock_update.assert_called_once_with(
self.app.client_manager,
mock_stack, 'mystack', 1, 0)
container='mystack',
container_registry={'fake_container': 'fake_value'},
queue_name=str(uuid.uuid4()))

@mock.patch('tripleoclient.workflows.package_update.update_and_wait',
@mock.patch('tripleoclient.workflows.package_update.update',
autospec=True)
def test_update_failed(self, mock_update_wait):
mock_update_wait.return_value = 'FAILED'
argslist = ['overcloud', '-i', '--templates']
@mock.patch('six.moves.builtins.open')
@mock.patch('os.path.abspath')
@mock.patch('yaml.load')
def test_update_failed(self, mock_yaml, mock_abspath, mock_open,
mock_update):
mock_update.side_effect = exceptions.DeploymentError()
mock_abspath.return_value = '/home/fake/my-fake-registry.yaml'
mock_yaml.return_value = {'fake_container': 'fake_value'}
argslist = ['--stack', 'overcloud', '--init-minor-update',
'--container-registry-file', 'my-fake-registry.yaml']
verifylist = [
('stack', 'overcloud'),
('interactive', True),
('templates', '/usr/share/openstack-tripleo-heat-templates/')
('init_minor_update', True),
('container_registry_file', 'my-fake-registry.yaml')
]
parsed_args = self.check_parser(self.cmd, argslist, verifylist)

self.assertRaises(exceptions.DeploymentError,
self.cmd.take_action, parsed_args)

@mock.patch('tripleoclient.workflows.package_update.update_ansible',
autospec=True)
@mock.patch('os.path.expanduser')
@mock.patch('oslo_concurrency.processutils.execute')
@mock.patch('six.moves.builtins.open')
def test_update_ansible(self, mock_open, mock_execute,
mock_expanduser, update_ansible):
mock_expanduser.return_value = '/home/fake/'
argslist = ['--stack', 'overcloud', '--nodes', 'Compute', '--playbook',
'fake-playbook.yaml']
verifylist = [
('stack', 'overcloud'),
('nodes', 'Compute'),
('generate_inventory', True),
('static_inventory', 'tripleo-hosts-inventory'),
('playbook', 'fake-playbook.yaml')
]

parsed_args = self.check_parser(self.cmd, argslist, verifylist)
with mock.patch('os.path.exists') as mock_exists:
mock_exists.return_value = True
self.cmd.take_action(parsed_args)
update_ansible.assert_called_once_with(
self.app.client_manager,
nodes='Compute',
inventory_file=mock_open().read(),
playbook='fake-playbook.yaml',
queue_name=str(uuid.uuid4()))

0 comments on commit 8a7da9f

Please sign in to comment.
You can’t perform that action at this time.