Browse Source

Don't allow nested or stacks in FAILED state to be migrated

Stack and its nested stacks should be in *_COMPLETE state for
it to be migrated. Also, we should not allow migration of a
nested stack.

This also changes stack_get_all_by_owner_id() to not select the
backup stacks. This seems to be used only in convergence code
path and migrate_convergence_1().

Change-Id: Icd54465d0c593557a12d853ddee4ee8ce6483499
Closes-Bug: #1767962
Story: #1767962
Task: #17363
changes/25/566225/3
rabi 4 years ago
parent
commit
abfec544d7
  1. 6
      heat/cmd/manage.py
  2. 5
      heat/common/exception.py
  3. 3
      heat/db/sqlalchemy/api.py
  4. 16
      heat/engine/service.py
  5. 1
      heat/tests/db/test_sqlalchemy_api.py

6
heat/cmd/manage.py

@ -122,10 +122,8 @@ def do_migrate():
except exception.NotFound:
raise Exception(_("Stack with id %s can not be found.")
% CONF.command.stack_id)
except exception.ActionInProgress:
raise Exception(_("The stack or some of its nested stacks are "
"in progress. Note, that all the stacks should be "
"in COMPLETE state in order to be migrated."))
except (exception.NotSupported, exception.ActionNotComplete) as ex:
raise Exception(ex.message)
def purge_deleted():

5
heat/common/exception.py

@ -487,6 +487,11 @@ class ActionInProgress(HeatException):
"in progress.")
class ActionNotComplete(HeatException):
msg_fmt = _("Stack %(stack_name)s has an action (%(action)s) "
"in progress or failed state.")
class StopActionFailed(HeatException):
msg_fmt = _("Failed to stop stack (%(stack_name)s) on other engine "
"(%(engine_id)s)")

3
heat/db/sqlalchemy/api.py

@ -605,7 +605,8 @@ def stack_get_status(context, stack_id):
def stack_get_all_by_owner_id(context, owner_id):
results = soft_delete_aware_query(
context, models.Stack).filter_by(owner_id=owner_id).all()
context, models.Stack).filter_by(owner_id=owner_id,
backup=False).all()
return results

16
heat/engine/service.py

@ -2207,14 +2207,30 @@ class EngineService(service.ServiceBase):
parent_stack = parser.Stack.load(ctxt,
stack_id=stack_id,
show_deleted=False)
if parent_stack.owner_id is not None:
msg = _("Migration of nested stack %s") % stack_id
raise exception.NotSupported(feature=msg)
if parent_stack.status != parent_stack.COMPLETE:
raise exception.ActionNotComplete(stack_name=parent_stack.name,
action=parent_stack.action)
if parent_stack.convergence:
LOG.info("Convergence was already enabled for stack %s",
stack_id)
return
db_stacks = stack_object.Stack.get_all_by_root_owner_id(
ctxt, parent_stack.id)
stacks = [parser.Stack.load(ctxt, stack_id=st.id,
stack=st) for st in db_stacks]
# check if any of the nested stacks is in IN_PROGRESS/FAILED state
for stack in stacks:
if stack.status != stack.COMPLETE:
raise exception.ActionNotComplete(stack_name=stack.name,
action=stack.action)
stacks.append(parent_stack)
locks = []
try:

1
heat/tests/db/test_sqlalchemy_api.py

@ -1383,6 +1383,7 @@ def create_stack(ctx, template, user_creds, **kwargs):
'parameters': {},
'user_creds_id': user_creds['id'],
'owner_id': None,
'backup': False,
'timeout': '60',
'disable_rollback': 0,
'current_traversal': 'dummy-uuid',

Loading…
Cancel
Save