Add context to stack lock function arguments
Context is added as the first argument to stack_lock_* db functions but is currently ignored for getting the session used for stack lock operations. This is required later for bug 1479723 but is added in its own change here to ease reviewing load. Change-Id: Ieb3e4e2ee67150777cbe1e961d0d1806cf1f7e46 Related-Bug: #1479723
This commit is contained in:
parent
a65bd2b19d
commit
9e007acc44
|
@ -206,20 +206,21 @@ def stack_delete(context, stack_id):
|
|||
return IMPL.stack_delete(context, stack_id)
|
||||
|
||||
|
||||
def stack_lock_create(stack_id, engine_id):
|
||||
return IMPL.stack_lock_create(stack_id, engine_id)
|
||||
def stack_lock_create(context, stack_id, engine_id):
|
||||
return IMPL.stack_lock_create(context, stack_id, engine_id)
|
||||
|
||||
|
||||
def stack_lock_get_engine_id(stack_id):
|
||||
return IMPL.stack_lock_get_engine_id(stack_id)
|
||||
def stack_lock_get_engine_id(context, stack_id):
|
||||
return IMPL.stack_lock_get_engine_id(context, stack_id)
|
||||
|
||||
|
||||
def stack_lock_steal(stack_id, old_engine_id, new_engine_id):
|
||||
return IMPL.stack_lock_steal(stack_id, old_engine_id, new_engine_id)
|
||||
def stack_lock_steal(context, stack_id, old_engine_id, new_engine_id):
|
||||
return IMPL.stack_lock_steal(context, stack_id, old_engine_id,
|
||||
new_engine_id)
|
||||
|
||||
|
||||
def stack_lock_release(stack_id, engine_id):
|
||||
return IMPL.stack_lock_release(stack_id, engine_id)
|
||||
def stack_lock_release(context, stack_id, engine_id):
|
||||
return IMPL.stack_lock_release(context, stack_id, engine_id)
|
||||
|
||||
|
||||
def persist_state_and_release_lock(context, stack_id, engine_id, values):
|
||||
|
|
|
@ -619,7 +619,7 @@ def stack_delete(context, stack_id):
|
|||
|
||||
@oslo_db_api.wrap_db_retry(max_retries=3, retry_on_deadlock=True,
|
||||
retry_interval=0.5, inc_retry_interval=True)
|
||||
def stack_lock_create(stack_id, engine_id):
|
||||
def stack_lock_create(context, stack_id, engine_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
lock = session.query(models.StackLock).get(stack_id)
|
||||
|
@ -628,7 +628,7 @@ def stack_lock_create(stack_id, engine_id):
|
|||
session.add(models.StackLock(stack_id=stack_id, engine_id=engine_id))
|
||||
|
||||
|
||||
def stack_lock_get_engine_id(stack_id):
|
||||
def stack_lock_get_engine_id(context, stack_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
lock = session.query(models.StackLock).get(stack_id)
|
||||
|
@ -652,7 +652,7 @@ def persist_state_and_release_lock(context, stack_id, engine_id, values):
|
|||
return True
|
||||
|
||||
|
||||
def stack_lock_steal(stack_id, old_engine_id, new_engine_id):
|
||||
def stack_lock_steal(context, stack_id, old_engine_id, new_engine_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
lock = session.query(models.StackLock).get(stack_id)
|
||||
|
@ -664,7 +664,7 @@ def stack_lock_steal(stack_id, old_engine_id, new_engine_id):
|
|||
return lock.engine_id if lock is not None else True
|
||||
|
||||
|
||||
def stack_lock_release(stack_id, engine_id):
|
||||
def stack_lock_release(context, stack_id, engine_id):
|
||||
session = get_session()
|
||||
with session.begin():
|
||||
rows_affected = session.query(
|
||||
|
|
|
@ -407,7 +407,8 @@ class StackResource(resource.Resource):
|
|||
if status == self.IN_PROGRESS:
|
||||
return False
|
||||
elif status == self.COMPLETE:
|
||||
ret = stack_lock.StackLock.get_engine_id(self.resource_id) is None
|
||||
ret = stack_lock.StackLock.get_engine_id(
|
||||
self.context, self.resource_id) is None
|
||||
if ret:
|
||||
# Reset nested, to indicate we changed status
|
||||
self._nested = None
|
||||
|
|
|
@ -35,14 +35,16 @@ class StackLock(object):
|
|||
self.listener = None
|
||||
|
||||
def get_engine_id(self):
|
||||
return stack_lock_object.StackLock.get_engine_id(self.stack_id)
|
||||
return stack_lock_object.StackLock.get_engine_id(self.context,
|
||||
self.stack_id)
|
||||
|
||||
def try_acquire(self):
|
||||
"""Try to acquire a stack lock.
|
||||
|
||||
Don't raise an ActionInProgress exception or try to steal lock.
|
||||
"""
|
||||
return stack_lock_object.StackLock.create(self.stack_id,
|
||||
return stack_lock_object.StackLock.create(self.context,
|
||||
self.stack_id,
|
||||
self.engine_id)
|
||||
|
||||
def acquire(self, retry=True):
|
||||
|
@ -51,7 +53,8 @@ class StackLock(object):
|
|||
:param retry: When True, retry if lock was released while stealing.
|
||||
:type retry: boolean
|
||||
"""
|
||||
lock_engine_id = stack_lock_object.StackLock.create(self.stack_id,
|
||||
lock_engine_id = stack_lock_object.StackLock.create(self.context,
|
||||
self.stack_id,
|
||||
self.engine_id)
|
||||
if lock_engine_id is None:
|
||||
LOG.debug("Engine %(engine)s acquired lock on stack "
|
||||
|
@ -74,7 +77,8 @@ class StackLock(object):
|
|||
"%(engine)s will attempt to steal the lock"),
|
||||
{'stack': self.stack_id, 'engine': self.engine_id})
|
||||
|
||||
result = stack_lock_object.StackLock.steal(self.stack_id,
|
||||
result = stack_lock_object.StackLock.steal(self.context,
|
||||
self.stack_id,
|
||||
lock_engine_id,
|
||||
self.engine_id)
|
||||
|
||||
|
@ -105,7 +109,8 @@ class StackLock(object):
|
|||
"""Release a stack lock."""
|
||||
|
||||
# Only the engine that owns the lock will be releasing it.
|
||||
result = stack_lock_object.StackLock.release(self.stack_id,
|
||||
result = stack_lock_object.StackLock.release(self.context,
|
||||
self.stack_id,
|
||||
self.engine_id)
|
||||
if result is True:
|
||||
LOG.warning(_LW("Lock was already released on stack %s!"),
|
||||
|
|
|
@ -34,19 +34,19 @@ class StackLock(
|
|||
}
|
||||
|
||||
@classmethod
|
||||
def create(cls, stack_id, engine_id):
|
||||
return db_api.stack_lock_create(stack_id, engine_id)
|
||||
def create(cls, context, stack_id, engine_id):
|
||||
return db_api.stack_lock_create(context, stack_id, engine_id)
|
||||
|
||||
@classmethod
|
||||
def steal(cls, stack_id, old_engine_id, new_engine_id):
|
||||
return db_api.stack_lock_steal(stack_id,
|
||||
def steal(cls, context, stack_id, old_engine_id, new_engine_id):
|
||||
return db_api.stack_lock_steal(context, stack_id,
|
||||
old_engine_id,
|
||||
new_engine_id)
|
||||
|
||||
@classmethod
|
||||
def release(cls, stack_id, engine_id):
|
||||
return db_api.stack_lock_release(stack_id, engine_id)
|
||||
def release(cls, context, stack_id, engine_id):
|
||||
return db_api.stack_lock_release(context, stack_id, engine_id)
|
||||
|
||||
@classmethod
|
||||
def get_engine_id(cls, stack_id):
|
||||
return db_api.stack_lock_get_engine_id(stack_id)
|
||||
def get_engine_id(cls, context, stack_id):
|
||||
return db_api.stack_lock_get_engine_id(context, stack_id)
|
||||
|
|
|
@ -1776,7 +1776,7 @@ class DBAPIStackTest(common.HeatTestCase):
|
|||
'timeout': '90',
|
||||
'current_traversal': 'another-dummy-uuid',
|
||||
}
|
||||
db_api.stack_lock_create(stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, stack.id, UUID1)
|
||||
observed = db_api.persist_state_and_release_lock(self.ctx, stack.id,
|
||||
UUID1, values)
|
||||
self.assertIsNone(observed)
|
||||
|
@ -1798,7 +1798,7 @@ class DBAPIStackTest(common.HeatTestCase):
|
|||
'timeout': '90',
|
||||
'current_traversal': 'another-dummy-uuid',
|
||||
}
|
||||
db_api.stack_lock_create(stack.id, UUID2)
|
||||
db_api.stack_lock_create(self.ctx, stack.id, UUID2)
|
||||
observed = db_api.persist_state_and_release_lock(self.ctx, stack.id,
|
||||
UUID1, values)
|
||||
self.assertTrue(observed)
|
||||
|
@ -1813,7 +1813,7 @@ class DBAPIStackTest(common.HeatTestCase):
|
|||
'timeout': '90',
|
||||
'current_traversal': 'another-dummy-uuid',
|
||||
}
|
||||
db_api.stack_lock_create(stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, stack.id, UUID1)
|
||||
observed = db_api.persist_state_and_release_lock(self.ctx, UUID2,
|
||||
UUID1, values)
|
||||
self.assertTrue(observed)
|
||||
|
@ -2356,63 +2356,66 @@ class DBAPIStackLockTest(common.HeatTestCase):
|
|||
self.stack = create_stack(self.ctx, self.template, self.user_creds)
|
||||
|
||||
def test_stack_lock_create_success(self):
|
||||
observed = db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
self.assertIsNone(observed)
|
||||
|
||||
def test_stack_lock_create_fail_double_same(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
self.assertEqual(UUID1, observed)
|
||||
|
||||
def test_stack_lock_create_fail_double_different(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_create(self.stack.id, UUID2)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_create(self.ctx, self.stack.id, UUID2)
|
||||
self.assertEqual(UUID1, observed)
|
||||
|
||||
def test_stack_lock_get_id_success(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_get_engine_id(self.stack.id)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_get_engine_id(self.ctx, self.stack.id)
|
||||
self.assertEqual(UUID1, observed)
|
||||
|
||||
def test_stack_lock_get_id_return_none(self):
|
||||
observed = db_api.stack_lock_get_engine_id(self.stack.id)
|
||||
observed = db_api.stack_lock_get_engine_id(self.ctx, self.stack.id)
|
||||
self.assertIsNone(observed)
|
||||
|
||||
def test_stack_lock_steal_success(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_steal(self.stack.id, UUID1, UUID2)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_steal(self.ctx, self.stack.id,
|
||||
UUID1, UUID2)
|
||||
self.assertIsNone(observed)
|
||||
|
||||
def test_stack_lock_steal_fail_gone(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
db_api.stack_lock_release(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_steal(self.stack.id, UUID1, UUID2)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
db_api.stack_lock_release(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_steal(self.ctx, self.stack.id,
|
||||
UUID1, UUID2)
|
||||
self.assertTrue(observed)
|
||||
|
||||
def test_stack_lock_steal_fail_stolen(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
|
||||
# Simulate stolen lock
|
||||
db_api.stack_lock_release(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.stack.id, UUID2)
|
||||
db_api.stack_lock_release(self.ctx, self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID2)
|
||||
|
||||
observed = db_api.stack_lock_steal(self.stack.id, UUID3, UUID2)
|
||||
observed = db_api.stack_lock_steal(self.ctx, self.stack.id,
|
||||
UUID3, UUID2)
|
||||
self.assertEqual(UUID2, observed)
|
||||
|
||||
def test_stack_lock_release_success(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.ctx, self.stack.id, UUID1)
|
||||
self.assertIsNone(observed)
|
||||
|
||||
def test_stack_lock_release_fail_double(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
db_api.stack_lock_release(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
db_api.stack_lock_release(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.ctx, self.stack.id, UUID1)
|
||||
self.assertTrue(observed)
|
||||
|
||||
def test_stack_lock_release_fail_wrong_engine_id(self):
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.stack.id, UUID2)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
observed = db_api.stack_lock_release(self.ctx, self.stack.id, UUID2)
|
||||
self.assertTrue(observed)
|
||||
|
||||
@mock.patch.object(time, 'sleep')
|
||||
|
@ -2420,7 +2423,8 @@ class DBAPIStackLockTest(common.HeatTestCase):
|
|||
with mock.patch('sqlalchemy.orm.Session.add',
|
||||
side_effect=db_exception.DBDeadlock) as mock_add:
|
||||
self.assertRaises(db_exception.DBDeadlock,
|
||||
db_api.stack_lock_create, self.stack.id, UUID1)
|
||||
db_api.stack_lock_create, self.ctx,
|
||||
self.stack.id, UUID1)
|
||||
self.assertEqual(4, mock_add.call_count)
|
||||
|
||||
|
||||
|
@ -3493,12 +3497,14 @@ class ResetStackStatusTests(common.HeatTestCase):
|
|||
|
||||
def test_status_reset(self):
|
||||
db_api.stack_update(self.ctx, self.stack.id, {'status': 'IN_PROGRESS'})
|
||||
db_api.stack_lock_create(self.stack.id, UUID1)
|
||||
db_api.stack_lock_create(self.ctx, self.stack.id, UUID1)
|
||||
db_api.reset_stack_status(self.ctx, self.stack.id)
|
||||
self.assertEqual('FAILED', self.stack.status)
|
||||
self.assertEqual('Stack status manually reset',
|
||||
self.stack.status_reason)
|
||||
self.assertEqual(True, db_api.stack_lock_release(self.stack.id, UUID1))
|
||||
self.assertEqual(True, db_api.stack_lock_release(self.ctx,
|
||||
self.stack.id,
|
||||
UUID1))
|
||||
|
||||
def test_resource_reset(self):
|
||||
resource_progress = create_resource(self.ctx, self.stack,
|
||||
|
|
|
@ -105,7 +105,8 @@ class StackDeleteTest(common.HeatTestCase):
|
|||
sid = stack.store()
|
||||
|
||||
# Insert a fake lock into the db
|
||||
stack_lock_object.StackLock.create(stack.id, self.man.engine_id)
|
||||
stack_lock_object.StackLock.create(
|
||||
self.ctx, stack.id, self.man.engine_id)
|
||||
|
||||
# Create a fake ThreadGroup too
|
||||
self.man.thread_group_mgr.groups[stack.id] = tools.DummyThreadGroup()
|
||||
|
@ -135,7 +136,7 @@ class StackDeleteTest(common.HeatTestCase):
|
|||
sid = stack.store()
|
||||
|
||||
# Insert a fake lock into the db
|
||||
stack_lock_object.StackLock.create(stack.id, OTHER_ENGINE)
|
||||
stack_lock_object.StackLock.create(self.ctx, stack.id, OTHER_ENGINE)
|
||||
|
||||
st = stack_object.Stack.get_by_id(self.ctx, sid)
|
||||
mock_load.return_value = stack
|
||||
|
@ -170,7 +171,7 @@ class StackDeleteTest(common.HeatTestCase):
|
|||
sid = stack.store()
|
||||
|
||||
# Insert a fake lock into the db
|
||||
stack_lock_object.StackLock.create(stack.id, OTHER_ENGINE)
|
||||
stack_lock_object.StackLock.create(self.ctx, stack.id, OTHER_ENGINE)
|
||||
|
||||
st = stack_object.Stack.get_by_id(self.ctx, sid)
|
||||
mock_load.return_value = stack
|
||||
|
@ -202,7 +203,8 @@ class StackDeleteTest(common.HeatTestCase):
|
|||
sid = stack.store()
|
||||
|
||||
# Insert a fake lock into the db
|
||||
stack_lock_object.StackLock.create(stack.id, "other-engine-fake-uuid")
|
||||
stack_lock_object.StackLock.create(
|
||||
self.ctx, stack.id, "other-engine-fake-uuid")
|
||||
|
||||
st = stack_object.Stack.get_by_id(self.ctx, sid)
|
||||
mock_load.return_value = stack
|
||||
|
|
|
@ -47,7 +47,8 @@ class StackLockTest(common.HeatTestCase):
|
|||
self.engine_id)
|
||||
slock.acquire()
|
||||
|
||||
mock_create.assert_called_once_with(self.stack_id, self.engine_id)
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, self.stack_id, self.engine_id)
|
||||
|
||||
def test_failed_acquire_existing_lock_current_engine(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -63,7 +64,8 @@ class StackLockTest(common.HeatTestCase):
|
|||
self.stack_id,
|
||||
tenant_safe=False,
|
||||
show_deleted=True)
|
||||
mock_create.assert_called_once_with(self.stack_id, self.engine_id)
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, self.stack_id, self.engine_id)
|
||||
|
||||
def test_successful_acquire_existing_lock_engine_dead(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -78,9 +80,10 @@ class StackLockTest(common.HeatTestCase):
|
|||
self.patchobject(service_utils, 'engine_alive', return_value=False)
|
||||
slock.acquire()
|
||||
|
||||
mock_create.assert_called_once_with(self.stack_id, self.engine_id)
|
||||
mock_steal.assert_called_once_with(self.stack_id, 'fake-engine-id',
|
||||
self.engine_id)
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, self.stack_id, self.engine_id)
|
||||
mock_steal.assert_called_once_with(
|
||||
self.context, self.stack_id, 'fake-engine-id', self.engine_id)
|
||||
|
||||
def test_failed_acquire_existing_lock_engine_alive(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -97,7 +100,8 @@ class StackLockTest(common.HeatTestCase):
|
|||
tenant_safe=False,
|
||||
show_deleted=True)
|
||||
|
||||
mock_create.assert_called_once_with(self.stack_id, self.engine_id)
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, self.stack_id, self.engine_id)
|
||||
|
||||
def test_failed_acquire_existing_lock_engine_dead(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -117,9 +121,10 @@ class StackLockTest(common.HeatTestCase):
|
|||
tenant_safe=False,
|
||||
show_deleted=True)
|
||||
|
||||
mock_create.assert_called_once_with(self.stack_id, self.engine_id)
|
||||
mock_steal.assert_called_once_with(self.stack_id, 'fake-engine-id',
|
||||
self.engine_id)
|
||||
mock_create.assert_called_once_with(
|
||||
self.context, self.stack_id, self.engine_id)
|
||||
mock_steal.assert_called_once_with(
|
||||
self.context, self.stack_id, 'fake-engine-id', self.engine_id)
|
||||
|
||||
def test_successful_acquire_with_retry(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -135,9 +140,10 @@ class StackLockTest(common.HeatTestCase):
|
|||
slock.acquire()
|
||||
|
||||
mock_create.assert_has_calls(
|
||||
[mock.call(self.stack_id, self.engine_id)] * 2)
|
||||
[mock.call(self.context, self.stack_id, self.engine_id)] * 2)
|
||||
mock_steal.assert_has_calls(
|
||||
[mock.call(self.stack_id, 'fake-engine-id', self.engine_id)] * 2)
|
||||
[mock.call(self.context, self.stack_id,
|
||||
'fake-engine-id', self.engine_id)] * 2)
|
||||
|
||||
def test_failed_acquire_one_retry_only(self):
|
||||
mock_create = self.patchobject(stack_lock_object.StackLock,
|
||||
|
@ -158,9 +164,10 @@ class StackLockTest(common.HeatTestCase):
|
|||
show_deleted=True)
|
||||
|
||||
mock_create.assert_has_calls(
|
||||
[mock.call(self.stack_id, self.engine_id)] * 2)
|
||||
[mock.call(self.context, self.stack_id, self.engine_id)] * 2)
|
||||
mock_steal.assert_has_calls(
|
||||
[mock.call(self.stack_id, 'fake-engine-id', self.engine_id)] * 2)
|
||||
[mock.call(self.context, self.stack_id,
|
||||
'fake-engine-id', self.engine_id)] * 2)
|
||||
|
||||
def test_context_mgr_exception(self):
|
||||
stack_lock_object.StackLock.create = mock.Mock(return_value=None)
|
||||
|
|
|
@ -745,6 +745,7 @@ class StackResourceCheckCompleteTest(StackResourceBaseTest):
|
|||
self.mock_status.assert_called_once_with(
|
||||
self.parent_resource.context, self.parent_resource.resource_id)
|
||||
self.mock_lock.assert_called_once_with(
|
||||
self.parent_resource.context,
|
||||
self.parent_resource.resource_id)
|
||||
|
||||
def test_state_err(self):
|
||||
|
|
Loading…
Reference in New Issue