Fix the failover API to not fail with immutable LB
A patch was added[1] that put an immutable check in the amphora failover flow. However, when failover was triggered by the failover API, the load balancer was already in PENDING_UPDATE. This caused the flow to fail and the load balancer to be left in ERROR. This patch resolves those two code paths to handle the load balancer locking the same. [1] https://review.openstack.org/#/c/479109/ Change-Id: I6c8549c15a302add8c69ab95bde57fb2646455b6
This commit is contained in:
parent
bb9bb2d05b
commit
e0fd00edb1
@ -692,8 +692,17 @@ class ControllerWorker(base_taskflow.BaseTaskFlowEngine):
|
||||
try:
|
||||
amp = self._amphora_repo.get(db_apis.get_session(),
|
||||
id=amphora_id)
|
||||
if amp.status == constants.AMPHORA_ALLOCATED:
|
||||
self._lb_repo.test_and_set_provisioning_status(
|
||||
db_apis.get_session(), amp.load_balancer_id,
|
||||
status=constants.PENDING_UPDATE, raise_exception=True)
|
||||
self._perform_amphora_failover(
|
||||
amp, constants.LB_CREATE_FAILOVER_PRIORITY)
|
||||
LOG.info("Mark ACTIVE in DB for load balancer id: %s",
|
||||
amp.load_balancer_id)
|
||||
self._lb_repo.update(
|
||||
db_apis.get_session(), amp.load_balancer_id,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error("Failover exception: %s", e)
|
||||
@ -706,12 +715,11 @@ class ControllerWorker(base_taskflow.BaseTaskFlowEngine):
|
||||
:raises LBNotFound: The referenced load balancer was not found
|
||||
"""
|
||||
|
||||
# this is a bit pedestrian right now but should be sufficient for now
|
||||
# Note: This expects that the load balancer is already in
|
||||
# provisioning_status=PENDING_UPDATE state
|
||||
try:
|
||||
lb = self._lb_repo.get(db_apis.get_session(),
|
||||
id=load_balancer_id)
|
||||
self._lb_repo.update(db_apis.get_session(), load_balancer_id,
|
||||
provisioning_status=constants.PENDING_UPDATE)
|
||||
|
||||
amps = lb.amphorae
|
||||
for amp in amps:
|
||||
|
@ -292,10 +292,6 @@ class AmphoraFlows(object):
|
||||
failover_amphora_flow.add(lifecycle_tasks.AmphoraToErrorOnRevertTask(
|
||||
rebind={constants.AMPHORA: constants.FAILED_AMPHORA},
|
||||
requires=constants.AMPHORA))
|
||||
if status == constants.AMPHORA_ALLOCATED:
|
||||
failover_amphora_flow.add(
|
||||
database_tasks.TestLBStatusSetPendingInDB(
|
||||
requires=constants.LOADBALANCER_ID))
|
||||
|
||||
# Note: It seems intuitive to boot an amphora prior to deleting
|
||||
# the old amphora, however this is a complicated issue.
|
||||
@ -407,8 +403,6 @@ class AmphoraFlows(object):
|
||||
|
||||
failover_amphora_flow.add(amphora_driver_tasks.ListenersStart(
|
||||
requires=(constants.LOADBALANCER, constants.LISTENERS)))
|
||||
failover_amphora_flow.add(database_tasks.MarkLBActiveInDB(
|
||||
requires=[constants.LOADBALANCER]))
|
||||
|
||||
return failover_amphora_flow
|
||||
|
||||
|
@ -913,24 +913,6 @@ class UpdateAmphoraCertBusyToFalse(BaseDatabaseTask):
|
||||
cert_busy=False)
|
||||
|
||||
|
||||
class TestLBStatusSetPendingInDB(BaseDatabaseTask):
|
||||
"""Test the LB's status to get a lock, and set it to PENDING_UPDATE
|
||||
|
||||
"""
|
||||
|
||||
def execute(self, loadbalancer_id):
|
||||
LOG.debug("Attempting to get a lock for loadbalancer %s to set "
|
||||
"PENDING_UPDATE status", loadbalancer_id)
|
||||
self.loadbalancer_repo.test_and_set_provisioning_status(
|
||||
db_apis.get_session(), loadbalancer_id,
|
||||
status=constants.PENDING_UPDATE, raise_exception=True)
|
||||
LOG.debug("Set loadbalancer %s to PENDING_UPDATE", loadbalancer_id)
|
||||
|
||||
def revert(self, loadbalancer_id, *args, **kwargs):
|
||||
LOG.debug("Marking loadbalancer %s ERROR", loadbalancer_id)
|
||||
self.task_utils.mark_loadbalancer_prov_status_error(loadbalancer_id)
|
||||
|
||||
|
||||
class MarkLBActiveInDB(BaseDatabaseTask):
|
||||
"""Mark the load balancer active in the DB.
|
||||
|
||||
|
@ -1063,30 +1063,6 @@ class TestDatabaseTasks(base.TestCase):
|
||||
AMP_ID,
|
||||
cert_busy=False)
|
||||
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository'
|
||||
'.test_and_set_provisioning_status')
|
||||
def test_test_lb_status_set_pending_in_db(self,
|
||||
mock_loadbalancer_repo_test,
|
||||
mock_generate_uuid,
|
||||
mock_LOG,
|
||||
mock_get_session,
|
||||
mock_loadbalancer_repo_update,
|
||||
mock_listener_repo_update,
|
||||
mock_amphora_repo_update,
|
||||
mock_amphora_repo_delete):
|
||||
test_lb_pending = database_tasks.TestLBStatusSetPendingInDB()
|
||||
test_lb_pending.execute(LB_ID)
|
||||
mock_loadbalancer_repo_test.assert_called_once_with(
|
||||
'TEST', LB_ID, status=constants.PENDING_UPDATE,
|
||||
raise_exception=True)
|
||||
|
||||
# Test the revert
|
||||
test_lb_pending.revert(LB_ID)
|
||||
mock_loadbalancer_repo_update.assert_called_once_with(
|
||||
'TEST',
|
||||
id=LB_ID,
|
||||
provisioning_status=constants.ERROR)
|
||||
|
||||
def test_mark_LB_active_in_db(self,
|
||||
mock_generate_uuid,
|
||||
mock_LOG,
|
||||
|
@ -1105,7 +1105,9 @@ class TestControllerWorker(base.TestCase):
|
||||
@mock.patch('octavia.controller.worker.flows.'
|
||||
'amphora_flows.AmphoraFlows.get_failover_flow',
|
||||
return_value=_flow_mock)
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
||||
def test_failover_amphora(self,
|
||||
mock_update,
|
||||
mock_get_update_listener_flow,
|
||||
mock_api_get_session,
|
||||
mock_dyn_log_listener,
|
||||
@ -1135,6 +1137,8 @@ class TestControllerWorker(base.TestCase):
|
||||
}))
|
||||
|
||||
_flow_mock.run.assert_called_once_with()
|
||||
mock_update.assert_called_with('TEST', LB_ID,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
|
||||
@mock.patch('octavia.controller.worker.'
|
||||
'controller_worker.ControllerWorker._perform_amphora_failover')
|
||||
@ -1185,7 +1189,9 @@ class TestControllerWorker(base.TestCase):
|
||||
@mock.patch(
|
||||
'octavia.db.repositories.AmphoraRepository.get_all_lbs_on_amphora',
|
||||
return_value=[_load_balancer_mock])
|
||||
@mock.patch('octavia.db.repositories.LoadBalancerRepository.update')
|
||||
def test_failover_amphora_anti_affinity(self,
|
||||
mock_update,
|
||||
mock_get_update_listener_flow,
|
||||
mock_get_all_lbs_for_amp_mock,
|
||||
mock_api_get_session,
|
||||
@ -1219,6 +1225,8 @@ class TestControllerWorker(base.TestCase):
|
||||
}))
|
||||
|
||||
_flow_mock.run.assert_called_once_with()
|
||||
mock_update.assert_called_with('TEST', LB_ID,
|
||||
provisioning_status=constants.ACTIVE)
|
||||
|
||||
@mock.patch('octavia.controller.worker.flows.'
|
||||
'amphora_flows.AmphoraFlows.cert_rotate_amphora_flow',
|
||||
|
Loading…
Reference in New Issue
Block a user