Add --force-stack-create
--force-stack-create will force the stack action to be CREATE when UPDATE would otherwise be used. This is useful in scenarios when you had a successful deployment, but did something wrong, so you want to froce a recreate, for example when using a completely wrong roles file. --force-stack-create and --force-stack-update are added to an argparse mutually exclusive group so that both can't be specified at the same time. Also adds unit tests around the stack action handling and adds missing unit tests for --force-stack-update. Change-Id: Ia3edebfe2271710abc4b84ce090b9e7ddf3c9d88
This commit is contained in:
parent
9f41f9556e
commit
26d0ed218e
|
@ -715,3 +715,63 @@ class TestDeployUndercloud(TestPluginV1):
|
|||
'--standalone'], [])
|
||||
self.assertRaises(exceptions.DeploymentError,
|
||||
self.cmd.take_action, parsed_args)
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=False)
|
||||
def test_set_stack_action_default_create(self, mock_isfile):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--local-ip', '127.0.0.1',
|
||||
'--templates', '/tmp/thtroot',
|
||||
'--stack', 'undercloud',
|
||||
'--output-dir', '/my',
|
||||
'--standalone'], [])
|
||||
self.cmd._set_stack_action(parsed_args)
|
||||
self.assertEqual('CREATE', self.cmd.stack_action)
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=True)
|
||||
def test_set_stack_action_default_update(self, mock_isfile):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--local-ip', '127.0.0.1',
|
||||
'--templates', '/tmp/thtroot',
|
||||
'--stack', 'undercloud',
|
||||
'--output-dir', '/my',
|
||||
'--standalone'], [])
|
||||
self.cmd._set_stack_action(parsed_args)
|
||||
self.assertEqual('UPDATE', self.cmd.stack_action)
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=False)
|
||||
def test_set_stack_action_force_update(self, mock_isfile):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--local-ip', '127.0.0.1',
|
||||
'--templates', '/tmp/thtroot',
|
||||
'--stack', 'undercloud',
|
||||
'--output-dir', '/my',
|
||||
'--standalone',
|
||||
'--force-stack-update'], [])
|
||||
self.cmd._set_stack_action(parsed_args)
|
||||
self.assertEqual('UPDATE', self.cmd.stack_action)
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=True)
|
||||
def test_set_stack_action_force_create(self, mock_isfile):
|
||||
parsed_args = self.check_parser(self.cmd,
|
||||
['--local-ip', '127.0.0.1',
|
||||
'--templates', '/tmp/thtroot',
|
||||
'--stack', 'undercloud',
|
||||
'--output-dir', '/my',
|
||||
'--standalone',
|
||||
'--force-stack-create'], [])
|
||||
self.cmd._set_stack_action(parsed_args)
|
||||
self.assertEqual('CREATE', self.cmd.stack_action)
|
||||
|
||||
@mock.patch('os.path.isfile', return_value=True)
|
||||
def test_set_stack_action_mutually_exclusive(self, mock_isfile):
|
||||
self.assertRaises(
|
||||
SystemExit,
|
||||
self.check_parser,
|
||||
self.cmd,
|
||||
['--local-ip', '127.0.0.1',
|
||||
'--templates', '/tmp/thtroot',
|
||||
'--stack', 'undercloud',
|
||||
'--output-dir', '/my',
|
||||
'--standalone',
|
||||
'--force-stack-create',
|
||||
'--force-stack-update'], [])
|
||||
|
|
|
@ -137,6 +137,18 @@ class Deploy(command.Command):
|
|||
else:
|
||||
self.roles_file = os.path.join(templates_dir, file_name)
|
||||
|
||||
def _set_stack_action(self, parsed_args):
|
||||
"""Set the stack action for deployment"""
|
||||
# Prepare the heat stack action we want to start deployment with
|
||||
if ((os.path.isfile(self.stack_update_mark) or
|
||||
parsed_args.force_stack_update) and
|
||||
not parsed_args.force_stack_create):
|
||||
self.stack_action = 'UPDATE'
|
||||
|
||||
self.log.warning(
|
||||
_('The heat stack {0} action is {1}').format(
|
||||
parsed_args.stack, self.stack_action))
|
||||
|
||||
def _get_roles_data(self):
|
||||
"""Load the roles data for deployment"""
|
||||
# only load once
|
||||
|
@ -775,16 +787,6 @@ class Deploy(command.Command):
|
|||
help=_("Name for the ephemeral (one-time create "
|
||||
"and forget) heat stack."),
|
||||
default='standalone')
|
||||
parser.add_argument('--force-stack-update',
|
||||
dest='force_stack_update',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Do a virtual update of the ephemeral "
|
||||
"heat stack (it cannot take real updates). "
|
||||
"New or failed deployments "
|
||||
"always have the stack_action=CREATE. This "
|
||||
"option enforces stack_action=UPDATE."),
|
||||
)
|
||||
parser.add_argument('--output-dir',
|
||||
dest='output_dir',
|
||||
help=_("Directory to output state, processed heat "
|
||||
|
@ -918,6 +920,30 @@ class Deploy(command.Command):
|
|||
'openstack stack list\n '
|
||||
'where 8006 is the port specified by --heat-api-port.')
|
||||
)
|
||||
|
||||
stack_action_group = parser.add_mutually_exclusive_group()
|
||||
|
||||
stack_action_group.add_argument(
|
||||
'--force-stack-update',
|
||||
dest='force_stack_update',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Do a virtual update of the ephemeral "
|
||||
"heat stack (it cannot take real updates). "
|
||||
"New or failed deployments "
|
||||
"always have the stack_action=CREATE. This "
|
||||
"option enforces stack_action=UPDATE."),
|
||||
)
|
||||
stack_action_group.add_argument(
|
||||
'--force-stack-create',
|
||||
dest='force_stack_create',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_("Do a virtual create of the ephemeral "
|
||||
"heat stack. New or failed deployments "
|
||||
"always have the stack_action=CREATE. This "
|
||||
"option enforces stack_action=CREATE."),
|
||||
)
|
||||
return parser
|
||||
|
||||
def _process_hieradata_overrides(self, override_file=None,
|
||||
|
@ -1037,14 +1063,7 @@ class Deploy(command.Command):
|
|||
constants.STANDALONE_EPHEMERAL_STACK_VSTATE,
|
||||
mark_uuid)
|
||||
|
||||
# Prepare the heat stack action we want to start deployment with
|
||||
if (os.path.isfile(self.stack_update_mark) or
|
||||
parsed_args.force_stack_update):
|
||||
self.stack_action = 'UPDATE'
|
||||
|
||||
self.log.warning(
|
||||
_('The heat stack {0} action is {1}').format(
|
||||
parsed_args.stack, self.stack_action))
|
||||
self._set_stack_action(parsed_args)
|
||||
|
||||
# Launch heat.
|
||||
orchestration_client = self._launch_heat(parsed_args)
|
||||
|
|
Loading…
Reference in New Issue