Change ha_state property to always return a value
Right now, ha_state could return any value that is in the state file, or even '' if the file is empty. Instead, return 'unknown' if it's empty. We also need to update the translation map in the HA code to deal with this new value to avoid a KeyError. Related-bug: #1755243 Change-Id: I94a39e574cf4ff5facb76df352c14cbaba793e98
This commit is contained in:
parent
c16d15fff2
commit
922cd0a938
|
@ -493,7 +493,7 @@ class L3NATAgent(ha.AgentMixin,
|
|||
is_dvr_only_agent = (self.conf.agent_mode in
|
||||
[lib_const.L3_AGENT_MODE_DVR,
|
||||
lib_const.L3_AGENT_MODE_DVR_NO_EXTERNAL])
|
||||
is_ha_router = getattr(ri, 'ha_state', None) is not None
|
||||
is_ha_router = getattr(ri, 'ha_state', False)
|
||||
# For HA routers check that DB state matches actual state
|
||||
if router.get('ha') and not is_dvr_only_agent and is_ha_router:
|
||||
self.check_ha_state_for_router(
|
||||
|
|
|
@ -30,7 +30,8 @@ KEEPALIVED_STATE_CHANGE_SERVER_BACKLOG = 4096
|
|||
|
||||
TRANSLATION_MAP = {'master': constants.HA_ROUTER_STATE_ACTIVE,
|
||||
'backup': constants.HA_ROUTER_STATE_STANDBY,
|
||||
'fault': constants.HA_ROUTER_STATE_STANDBY}
|
||||
'fault': constants.HA_ROUTER_STATE_STANDBY,
|
||||
'unknown': constants.HA_ROUTER_STATE_UNKNOWN}
|
||||
|
||||
|
||||
class KeepalivedStateChangeHandler(object):
|
||||
|
|
|
@ -76,14 +76,15 @@ class HaRouter(router.RouterInfo):
|
|||
|
||||
@property
|
||||
def ha_state(self):
|
||||
state = None
|
||||
ha_state_path = self.keepalived_manager.get_full_config_file_path(
|
||||
'state')
|
||||
try:
|
||||
with open(ha_state_path, 'r') as f:
|
||||
return f.read()
|
||||
state = f.read()
|
||||
except (OSError, IOError):
|
||||
LOG.debug('Error while reading HA state for %s', self.router_id)
|
||||
return None
|
||||
return state or 'unknown'
|
||||
|
||||
@ha_state.setter
|
||||
def ha_state(self, new_state):
|
||||
|
|
|
@ -20,6 +20,7 @@ from oslo_utils import uuidutils
|
|||
from neutron.agent.l3 import ha_router
|
||||
from neutron.agent.l3 import router_info
|
||||
from neutron.tests import base
|
||||
from neutron.tests import tools
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
|
@ -115,3 +116,28 @@ class TestBasicRouterOperations(base.BaseTestCase):
|
|||
calls = ["sig='str(%d)'" % signal.SIGTERM,
|
||||
"sig='str(%d)'" % signal.SIGKILL]
|
||||
mock_pm.disable.has_calls(calls)
|
||||
|
||||
def _test_ha_state(self, read_return, expected):
|
||||
ri = self._create_router(mock.MagicMock())
|
||||
ri.keepalived_manager = mock.Mock()
|
||||
ri.keepalived_manager.get_full_config_file_path.return_value = (
|
||||
'ha_state')
|
||||
self.mock_open = self.useFixture(
|
||||
tools.OpenFixture('ha_state', read_return)).mock_open
|
||||
self.assertEqual(expected, ri.ha_state)
|
||||
|
||||
def test_ha_state_master(self):
|
||||
self._test_ha_state('master', 'master')
|
||||
|
||||
def test_ha_state_unknown(self):
|
||||
# an empty state file should yield 'unknown'
|
||||
self._test_ha_state('', 'unknown')
|
||||
|
||||
def test_ha_state_ioerror(self):
|
||||
# an error reading the state file should yield 'unknown'
|
||||
ri = self._create_router(mock.MagicMock())
|
||||
ri.keepalived_manager = mock.Mock()
|
||||
ri.keepalived_manager.get_full_config_file_path.return_value = (
|
||||
'ha_state')
|
||||
self.mock_open = IOError
|
||||
self.assertEqual('unknown', ri.ha_state)
|
||||
|
|
Loading…
Reference in New Issue