dhcp: ensure that cleaning DHCP process with one segment happens first

Previously, the code used to clean up old DHCP processes for a network
before creating new ones supporting multiple segments per network
could potentially not be executed first. Since disabling applies to
cleaning the namespace, this could have led to the network setup being
destroyed after being done.

This change moves the part that cleans up the old DHCP setup to ensure
it is executed first.

Closes-bug: #2049615
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@industrialdiscipline.com>
Change-Id: Iecdb2d81ee077c9b9057d0708c5c88e159970039
This commit is contained in:
Sahid Orentino Ferdjaoui 2024-01-15 17:11:23 +01:00
parent 4e9d03d29f
commit 5453c92a2e
2 changed files with 39 additions and 14 deletions

View File

@ -221,21 +221,18 @@ class DhcpAgent(manager.Manager):
sid_subnets[subnet.get('segment_id')].append(subnet)
if sid_subnets:
ret = []
# TODO(sahid): This whole block bellow should be removed in future,
# when we know that all environements have migrated to at least
# zed. This is expected to help for environements that already
# have deployed RPN. First, disable the dhcp agent for the
# network. Then the process will recreate it considering a dhcp
# agent per segmentation id.
if action in ['enable', 'disable']:
self._call_driver(
'disable', network, segment=None, block=True)
for seg_id, subnets in sid_subnets.items():
# TODO(sahid): This whole block bellow should be removed in
# future, when we know that all environements have migrated to
# at least zed. This is expected to help for environements
# that already have deployed RPN. For any first segment
# associated to a subnet we want to disable its dhcp
# agent. Then the process will recreate it considering a dhcp
# agent per segmentation id.
segment = sid_segment.get(seg_id)
if segment and segment.segment_index == 0:
if action in ['enable', 'disable']:
self._call_driver(
'disable', network, segment=None, block=True)
net_seg = copy.deepcopy(network)
net_seg.subnets = subnets
ret.append(self._call_driver(

View File

@ -373,6 +373,34 @@ class TestDhcpAgent(base.BaseTestCase):
mock.ANY,
None)
def test_call_driver_enable_with_segments(self):
seg0 = dhcp.DictModel(id='seg0', segment_index=0)
seg1 = dhcp.DictModel(id='seg1', segment_index=1)
sub0 = dhcp.DictModel(id='sub0', segment_id=seg0.id)
sub1 = dhcp.DictModel(id='sub1', segment_id=seg1.id)
network = dhcp.NetModel(
id=FAKE_NETWORK_UUID,
project_id=FAKE_PROJECT_ID,
admin_state_up=True,
subnets=[sub0, sub1],
# We don't know order of segments stored.
segments=[seg1, seg0])
agent = dhcp_agent.DhcpAgent(cfg.CONF)
with mock.patch.object(agent,
'_call_driver') as _call_driver:
self.assertTrue(agent.call_driver('enable', network))
# The public function call_driver() is calling the private
# _call_driver().
_call_driver.assert_has_calls([
mock.call("disable", network, segment=None, block=True),
# It is not possible to assert on 'network' as there is a copy
# happening. The copy will be removed, see bug #2051729.
mock.call("enable", mock.ANY, segment=seg0),
mock.call("enable", mock.ANY, segment=seg1)])
def test_call_driver_no_network(self):
network = None
dhcp = dhcp_agent.DhcpAgent(cfg.CONF)