Revert "Hard delete backup stack after successful update."

This reverts commit 7cf6e52cac.

This change appears to be the cause of many Tempest test breakages.  Prior
to this a new raw_template entry was created in the database after an
update, and the pointer to the new raw_template and the stack status were
changed atomically. Now those two pieces of data are being updated
separately... it seems like it is possible for the database to return the
new version of the stack on one call followed by the old version of the
template on another call. Tempest is observing the stack status change to
UPDATE_COMPLETE but then still getting data from the old template when
doing a resource list immediately after.

Change-Id: Ieea739bc45dcc365ccb6f09d0e848e310d327134
Partial-Bug: #1370865
This commit is contained in:
Zane Bitter 2014-10-06 16:46:55 -04:00
parent c511d076b8
commit ce22b59b62
5 changed files with 3 additions and 72 deletions

View File

@ -154,10 +154,6 @@ def stack_delete(context, stack_id):
return IMPL.stack_delete(context, stack_id) return IMPL.stack_delete(context, stack_id)
def stack_delete_hard(context, stack_id):
return IMPL.stack_delete_hard(context, stack_id)
def stack_lock_create(stack_id, engine_id): def stack_lock_create(stack_id, engine_id):
return IMPL.stack_lock_create(stack_id, engine_id) return IMPL.stack_lock_create(stack_id, engine_id)

View File

@ -429,27 +429,6 @@ def stack_delete(context, stack_id):
session.flush() session.flush()
def stack_delete_hard(context, stack_id):
s = stack_get(context, stack_id)
if not s:
raise exception.NotFound(_('Attempt to hard-delete a stack with id: '
'%(id)s %(msg)s') % {
'id': stack_id,
'msg': 'that does not exist'})
session = Session.object_session(s)
for r in s.resources:
session.delete(r)
for e in s.events:
session.delete(e)
session.delete(s)
session.flush()
def stack_lock_create(stack_id, engine_id): def stack_lock_create(stack_id, engine_id):
session = get_session() session = get_session()
with session.begin(): with session.begin():

View File

@ -121,8 +121,7 @@ class Stack(BASE, HeatBase, SoftDelete, StateAware):
sqlalchemy.Integer, sqlalchemy.Integer,
sqlalchemy.ForeignKey('raw_template.id'), sqlalchemy.ForeignKey('raw_template.id'),
nullable=False) nullable=False)
raw_template = relationship(RawTemplate, cascade="all,delete", raw_template = relationship(RawTemplate, backref=backref('stack'))
backref=backref('stack'))
username = sqlalchemy.Column(sqlalchemy.String(256)) username = sqlalchemy.Column(sqlalchemy.String(256))
tenant = sqlalchemy.Column(sqlalchemy.String(256)) tenant = sqlalchemy.Column(sqlalchemy.String(256))
parameters = sqlalchemy.Column('parameters', Json) parameters = sqlalchemy.Column('parameters', Json)

View File

@ -775,9 +775,7 @@ class Stack(collections.Mapping):
LOG.debug('Deleting backup stack') LOG.debug('Deleting backup stack')
backup_stack.delete(backup=True) backup_stack.delete(backup=True)
# Flip the template to the newstack values, but keep # flip the template to the newstack values
# reference to old stack id to overwrite DB entry
newstack.t.id = self.t.id
self.t = newstack.t self.t = newstack.t
template_outputs = self.t[self.t.OUTPUTS] template_outputs = self.t[self.t.OUTPUTS]
self.outputs = self.resolve_static_data(template_outputs) self.outputs = self.resolve_static_data(template_outputs)
@ -960,10 +958,7 @@ class Stack(collections.Mapping):
if stack_status != self.FAILED: if stack_status != self.FAILED:
# delete the stack # delete the stack
try: try:
if backup: db_api.stack_delete(self.context, self.id)
db_api.stack_delete_hard(self.context, self.id)
else:
db_api.stack_delete(self.context, self.id)
except exception.NotFound: except exception.NotFound:
LOG.info(_("Tried to delete stack that does not exist " LOG.info(_("Tried to delete stack that does not exist "
"%s ") % self.id) "%s ") % self.id)

View File

@ -1330,44 +1330,6 @@ class DBAPIStackTest(HeatTestCase):
self.assertRaises(exception.NotFound, db_api.resource_get, self.assertRaises(exception.NotFound, db_api.resource_get,
self.ctx, resource.id) self.ctx, resource.id)
def test_stack_delete_hard(self):
stack = create_stack(self.ctx, self.template, self.user_creds)
stack_id = stack.id
resource = create_resource(self.ctx, stack)
template_id = stack.raw_template.id
db_api.stack_delete_hard(self.ctx, stack_id)
self.assertIsNone(db_api.stack_get(self.ctx, stack_id,
show_deleted=False))
self.assertRaises(exception.NotFound, db_api.stack_delete,
self.ctx, stack_id)
# Even soft-delete aware should not find it
self.assertIsNone(db_api.stack_get(self.ctx, stack_id,
show_deleted=True))
# Testing child resources deletion
self.assertRaises(exception.NotFound, db_api.resource_get,
self.ctx, resource.id)
# Testing raw_template deletion
self.assertRaises(exception.NotFound, db_api.raw_template_get,
self.ctx, template_id)
def test_stack_delete_hard_deletes_events(self):
stack = create_stack(self.ctx, self.template, self.user_creds)
stack_id = stack.id
values = [
{'stack_id': stack_id, 'resource_name': 'res1'},
{'stack_id': stack_id, 'resource_name': 'res2'},
]
[create_event(self.ctx, **val) for val in values]
db_api.stack_delete_hard(self.ctx, stack_id)
events = db_api.event_get_all_by_stack(self.ctx, stack_id)
self.assertEqual(0, len(events))
def test_stack_update(self): def test_stack_update(self):
stack = create_stack(self.ctx, self.template, self.user_creds) stack = create_stack(self.ctx, self.template, self.user_creds)
values = { values = {