Add --skip-deploy-identifier
Add a new cli argument, --skip-deploy-identifier. The argument will eventually be passed to the tripleo-common DeployStackAction action to disable setting a unique value for the DeployIdentifier parameter, which means the SoftwareDeployment resources in the templates will only be triggered if there is an actual change to their configuration. This argument can be used to avoid always applying configuration, such as during node scale out. Removes the setting of DeployIdentifier completely from tripleoclient, :xa git as that is now handled by the tripleo-common action. Depends-On: Idb901a841846fec33d189b3c95f669b0380498ce Change-Id: I294eabe84e070367981534030b5927062f00c628 Closes-Bug: #1688387 (cherry picked from commitf3acb69ffc
) (cherry picked from commit1b877698ce
)
This commit is contained in:
parent
a93e6d1a15
commit
d98fff454b
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
features:
|
||||
- Add a new cli argument, --skip-deploy-identifier. The argument will disable
|
||||
setting a unique value for the DeployIdentifier parameter, which means the
|
||||
SoftwareDeployment resources in the templates will only be triggered if
|
||||
there is an actual change to their configuration. This argument can be used
|
||||
to avoid always applying configuration, such as during node scale out.
|
||||
This option should be used with Caution, and only if there is confidence
|
||||
that the software configuration does not need to be run, such as when
|
||||
scaling out certain roles.
|
|
@ -404,6 +404,112 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_tarball.tarball_extract_to_swift_container.assert_called_with(
|
||||
clients.tripleoclient.object_store, mock.ANY, 'overcloud')
|
||||
|
||||
@mock.patch('tripleoclient.utils.get_overcloud_endpoint', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_deploy_postconfig', autospec=True)
|
||||
@mock.patch('tripleoclient.workflows.plan_management.tarball',
|
||||
autospec=True)
|
||||
@mock.patch('tripleo_common.update.add_breakpoints_cleanup_into_env',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_validate_args')
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_create_parameters_env', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.create_tempest_deployer_input',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.utils.write_overcloudrc', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.remove_known_hosts', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.wait_for_stack_ready',
|
||||
autospec=True)
|
||||
@mock.patch('heatclient.common.template_utils.'
|
||||
'process_environment_and_files', autospec=True)
|
||||
@mock.patch('heatclient.common.template_utils.get_template_contents',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.utils.check_hypervisor_stats',
|
||||
autospec=True)
|
||||
@mock.patch('os_cloud_config.keystone_pki.generate_certs_into_json',
|
||||
autospec=True)
|
||||
@mock.patch('tripleoclient.utils.create_environment_file',
|
||||
autospec=True)
|
||||
@mock.patch('uuid.uuid1', autospec=True)
|
||||
@mock.patch('time.time', autospec=True)
|
||||
@mock.patch('shutil.rmtree', autospec=True)
|
||||
@mock.patch('shutil.copytree', autospec=True)
|
||||
@mock.patch('tempfile.mkdtemp', autospec=True)
|
||||
def test_tht_deploy_skip_deploy_identifier(
|
||||
self, mock_tmpdir, mock_copy, mock_rm, mock_time,
|
||||
mock_uuid1,
|
||||
mock_environment_file,
|
||||
mock_generate_certs,
|
||||
mock_check_hypervisor_stats,
|
||||
mock_get_template_contents,
|
||||
mock_process_env,
|
||||
wait_for_stack_ready_mock,
|
||||
mock_remove_known_hosts,
|
||||
mock_write_overcloudrc,
|
||||
mock_create_tempest_deployer_input,
|
||||
mock_create_parameters_env, mock_validate_args,
|
||||
mock_breakpoints_cleanup, mock_tarball,
|
||||
mock_postconfig, mock_get_overcloud_endpoint):
|
||||
|
||||
arglist = ['--templates', '--skip-deploy-identifier']
|
||||
verifylist = [
|
||||
('templates', '/usr/share/openstack-tripleo-heat-templates/'),
|
||||
('skip_deploy_identifier', True)
|
||||
]
|
||||
|
||||
mock_tmpdir.return_value = "/tmp/tht"
|
||||
mock_uuid1.return_value = "uuid"
|
||||
mock_time.return_value = 123456789
|
||||
mock_env = fakes.create_env()
|
||||
mock_process_env.return_value = [{}, mock_env]
|
||||
|
||||
clients = self.app.client_manager
|
||||
orchestration_client = clients.orchestration
|
||||
mock_stack = fakes.create_tht_stack()
|
||||
orchestration_client.stacks.get.side_effect = [None, mock.Mock()]
|
||||
workflow_client = clients.workflow_engine
|
||||
workflow_client.environments.get.return_value = mock.MagicMock(
|
||||
variables={'environments': []})
|
||||
workflow_client.action_executions.create.return_value = mock.MagicMock(
|
||||
output='{"result":[]}')
|
||||
|
||||
def _orch_clt_create(**kwargs):
|
||||
orchestration_client.stacks.get.return_value = mock_stack
|
||||
|
||||
orchestration_client.stacks.create.side_effect = _orch_clt_create
|
||||
|
||||
mock_check_hypervisor_stats.return_value = {
|
||||
'count': 4,
|
||||
'memory_mb': 4096,
|
||||
'vcpus': 8,
|
||||
}
|
||||
clients.network.api.find_attr.return_value = {
|
||||
"id": "network id"
|
||||
}
|
||||
mock_get_template_contents.return_value = [{}, "template"]
|
||||
wait_for_stack_ready_mock.return_value = True
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
baremetal = clients.baremetal
|
||||
baremetal.node.list.return_value = range(10)
|
||||
|
||||
testcase = self
|
||||
|
||||
def _custom_create_params_env(self, parameters):
|
||||
testcase.assertTrue('DeployIdentifier' not in parameters)
|
||||
parameter_defaults = {"parameter_defaults": parameters}
|
||||
return parameter_defaults
|
||||
|
||||
mock_create_parameters_env.side_effect = _custom_create_params_env
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
execution_calls = workflow_client.executions.create.call_args_list
|
||||
deploy_plan_call = execution_calls[1]
|
||||
deploy_plan_call_input = deploy_plan_call[1]['workflow_input']
|
||||
self.assertTrue(deploy_plan_call_input['skip_deploy_identifier'])
|
||||
|
||||
@mock.patch('tripleoclient.workflows.plan_management.tarball',
|
||||
autospec=True)
|
||||
@mock.patch("heatclient.common.event_utils.get_events", autospec=True)
|
||||
|
@ -566,7 +672,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
|
||||
def _fake_heat_deploy(self, stack, stack_name, template_path,
|
||||
parameters, environments, timeout, tht_root,
|
||||
env, update_plan_only):
|
||||
env, update_plan_only,
|
||||
skip_deploy_identifier):
|
||||
assertEqual(
|
||||
{'parameter_defaults': {},
|
||||
'resource_registry': {'Test': u'OS::Heat::None'}}, env)
|
||||
|
@ -620,7 +727,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
|
||||
def _fake_heat_deploy(self, stack, stack_name, template_path,
|
||||
parameters, environments, timeout, tht_root,
|
||||
env, update_plan_only):
|
||||
env, update_plan_only,
|
||||
skip_deploy_identifier):
|
||||
assertEqual(
|
||||
{'parameter_defaults': {},
|
||||
'resource_registry': {'Test': u'OS::Heat::None'}}, env)
|
||||
|
@ -966,13 +1074,13 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
self, mock_heat_deploy_func):
|
||||
result = self.cmd._try_overcloud_deploy_with_compat_yaml(
|
||||
'/fake/path', {}, 'overcloud', {}, ['~/overcloud-env.json'], 1,
|
||||
{}, False)
|
||||
{}, False, False)
|
||||
# If it returns None it succeeded
|
||||
self.assertIsNone(result)
|
||||
mock_heat_deploy_func.assert_called_once_with(
|
||||
self.cmd, {}, 'overcloud',
|
||||
'/fake/path/' + constants.OVERCLOUD_YAML_NAME, {},
|
||||
['~/overcloud-env.json'], 1, '/fake/path', {}, False)
|
||||
['~/overcloud-env.json'], 1, '/fake/path', {}, False, False)
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_heat_deploy', autospec=True)
|
||||
|
@ -982,7 +1090,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
self.assertRaises(ValueError,
|
||||
self.cmd._try_overcloud_deploy_with_compat_yaml,
|
||||
'/fake/path', mock.ANY, mock.ANY, mock.ANY,
|
||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY)
|
||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY)
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_heat_deploy', autospec=True)
|
||||
|
@ -993,7 +1101,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
try:
|
||||
self.cmd._try_overcloud_deploy_with_compat_yaml(
|
||||
'/fake/path', mock.ANY, mock.ANY, mock.ANY,
|
||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY)
|
||||
mock.ANY, mock.ANY, mock.ANY, mock.ANY, mock.ANY)
|
||||
except ValueError as value_error:
|
||||
self.assertIn('/fake/path', str(value_error))
|
||||
|
||||
|
@ -1504,7 +1612,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_get_template_contents.return_value = [{}, {}]
|
||||
|
||||
self.cmd._heat_deploy(mock_stack, 'mock_stack', '/tmp', {},
|
||||
{}, 1, '/tmp', {}, True)
|
||||
{}, 1, '/tmp', {}, True, False)
|
||||
|
||||
self.assertFalse(mock_deploy_and_wait.called)
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ class TestOvercloudDeployPlan(utils.TestCommand):
|
|||
'tripleo.deployment.v1.deploy_plan',
|
||||
workflow_input={
|
||||
'container': 'overcast',
|
||||
'queue_name': 'UUID4'
|
||||
'queue_name': 'UUID4',
|
||||
'skip_deploy_identifier': False
|
||||
}
|
||||
)
|
||||
|
|
|
@ -23,7 +23,6 @@ import re
|
|||
import shutil
|
||||
import six
|
||||
import tempfile
|
||||
import time
|
||||
import yaml
|
||||
|
||||
from heatclient.common import template_utils
|
||||
|
@ -59,8 +58,6 @@ class DeployOvercloud(command.Command):
|
|||
|
||||
stack_is_new = stack is None
|
||||
|
||||
timestamp = int(time.time())
|
||||
parameters['DeployIdentifier'] = timestamp
|
||||
parameters['UpdateIdentifier'] = ''
|
||||
parameters['StackAction'] = 'CREATE' if stack_is_new else 'UPDATE'
|
||||
|
||||
|
@ -202,7 +199,8 @@ class DeployOvercloud(command.Command):
|
|||
return env_files, localenv
|
||||
|
||||
def _heat_deploy(self, stack, stack_name, template_path, parameters,
|
||||
env_files, timeout, tht_root, env, update_plan_only):
|
||||
env_files, timeout, tht_root, env, update_plan_only,
|
||||
skip_deploy_identifier):
|
||||
"""Verify the Baremetal nodes are available and do a stack update"""
|
||||
|
||||
clients = self.app.client_manager
|
||||
|
@ -249,8 +247,11 @@ class DeployOvercloud(command.Command):
|
|||
workflow_client)
|
||||
|
||||
if not update_plan_only:
|
||||
deployment.deploy_and_wait(self.log, clients, stack, stack_name,
|
||||
self.app_args.verbose_level, timeout)
|
||||
deployment.deploy_and_wait(
|
||||
self.log, clients, stack, stack_name,
|
||||
self.app_args.verbose_level,
|
||||
timeout=timeout,
|
||||
skip_deploy_identifier=skip_deploy_identifier)
|
||||
|
||||
def _load_environment_directories(self, directories):
|
||||
if os.environ.get('TRIPLEO_ENVIRONMENT_DIRECTORY'):
|
||||
|
@ -462,17 +463,20 @@ class DeployOvercloud(command.Command):
|
|||
|
||||
self._try_overcloud_deploy_with_compat_yaml(
|
||||
tht_root, stack, parsed_args.stack, parameters, env_files,
|
||||
parsed_args.timeout, env, parsed_args.update_plan_only)
|
||||
parsed_args.timeout, env, parsed_args.update_plan_only,
|
||||
parsed_args.skip_deploy_identifier)
|
||||
|
||||
def _try_overcloud_deploy_with_compat_yaml(self, tht_root, stack,
|
||||
stack_name, parameters,
|
||||
env_files, timeout,
|
||||
env, update_plan_only):
|
||||
env, update_plan_only,
|
||||
skip_deploy_identifier):
|
||||
overcloud_yaml = os.path.join(tht_root, constants.OVERCLOUD_YAML_NAME)
|
||||
try:
|
||||
self._heat_deploy(stack, stack_name, overcloud_yaml,
|
||||
parameters, env_files, timeout,
|
||||
tht_root, env, update_plan_only)
|
||||
tht_root, env, update_plan_only,
|
||||
skip_deploy_identifier)
|
||||
except ClientException as e:
|
||||
messages = 'Failed to deploy: %s' % str(e)
|
||||
raise ValueError(messages)
|
||||
|
@ -1072,6 +1076,18 @@ class DeployOvercloud(command.Command):
|
|||
default=False,
|
||||
help=_('Force the overcloud post-deployment configuration.')
|
||||
)
|
||||
parser.add_argument(
|
||||
'--skip-deploy-identifier',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Skip generation of a unique identifier for the '
|
||||
'DeployIdentifier parameter. The software configuration '
|
||||
'deployment steps will only be triggered if there is an '
|
||||
'actual change to the configuration. This option should '
|
||||
'be used with Caution, and only if there is confidence '
|
||||
'that the software configuration does not need to be '
|
||||
'run, such as when scaling out certain roles.')
|
||||
)
|
||||
reg_group = parser.add_argument_group('Registration Parameters')
|
||||
reg_group.add_argument(
|
||||
'--rhel-reg',
|
||||
|
|
|
@ -41,11 +41,12 @@ def deploy(clients, **workflow_input):
|
|||
|
||||
|
||||
def deploy_and_wait(log, clients, stack, plan_name, verbose_level,
|
||||
timeout=None):
|
||||
timeout=None, skip_deploy_identifier=False):
|
||||
"""Start the deploy and wait for it to finish"""
|
||||
|
||||
workflow_input = {
|
||||
"container": plan_name,
|
||||
"skip_deploy_identifier": skip_deploy_identifier,
|
||||
"queue_name": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue