[DHCP] Break reference chain to any Exception object when resync

In the DHCP agent, if an exception is raised during the driver call,
"DhcpAgent.schedule_resync" is called. Before this patch, the
exception instance was passed instead of a string. This instance
reference was stored in the dictionary "needs_resync_reasons" and
used in "_periodic_resync_helper" to resync the DHCP agent
information.

The call to "sync_state" passed the dictionary ".keys()" method. In
python2.7 when that was implemented, this method was creating a list
with the dictionary keys. In python3, this method is a generator
that holds the dictionary content.

This patch breaks this reference chain in two points (actually only
one is needed):
- "sync_state" now passes a list created from the mentioned generator.
- The dictionary "needs_resync_reasons" now stores the exception
  strings only, instead of the exception instance.

Closes-Bug: #1969270
Change-Id: I07e9818021283d321fc32066be7e0f8e2b81e639
(cherry picked from commit e3b3ec9309)
This commit is contained in:
Rodolfo Alonso Hernandez 2022-04-13 23:38:04 +00:00
parent 37e98d3a5d
commit 3b509e11b7
2 changed files with 4 additions and 4 deletions

View File

@ -246,7 +246,7 @@ class DhcpAgent(manager.Manager):
# allocation failure. When the subnet is updated with a new
# allocation pool or a port is deleted to free up an IP, this
# will automatically be retried on the notification
self.schedule_resync(e, network.id)
self.schedule_resync(str(e), network.id)
if (isinstance(e, oslo_messaging.RemoteError) and
e.exc_type == 'NetworkNotFound' or
isinstance(e, exceptions.NetworkNotFound)):
@ -371,7 +371,7 @@ class DhcpAgent(manager.Manager):
net = "*"
LOG.debug("resync (%(network)s): %(reason)s",
{"reason": r, "network": net})
self.sync_state(reasons.keys())
self.sync_state(list(reasons.keys()))
def periodic_resync(self):
"""Spawn a thread to periodically resync the dhcp state."""

View File

@ -630,7 +630,7 @@ class TestDhcpAgent(base.BaseTestCase):
sync_state.side_effect = RuntimeError
with testtools.ExpectedException(RuntimeError):
dhcp._periodic_resync_helper()
sync_state.assert_called_once_with(resync_reasons.keys())
sync_state.assert_called_once_with(list(resync_reasons.keys()))
self.assertEqual(0, len(dhcp.needs_resync_reasons))
def test_periodic_resync_helper_with_event(self):
@ -638,7 +638,7 @@ class TestDhcpAgent(base.BaseTestCase):
dhcp = dhcp_agent.DhcpAgent(HOSTNAME)
dhcp.schedule_resync('reason1', 'a')
dhcp.schedule_resync('reason1', 'b')
reasons = dhcp.needs_resync_reasons.keys()
reasons = list(dhcp.needs_resync_reasons.keys())
with mock.patch.object(dhcp, 'sync_state') as sync_state:
sync_state.side_effect = RuntimeError
with testtools.ExpectedException(RuntimeError):