Merge ~cgrabowski/maas:fix_dns_update_race_condition into maas:master

Proposed by Christian Grabowski
Status: Merged
Approved by: Alexsander de Souza
Approved revision: a2e3f48b6d1b268f2bc9c4935df538227aa117d0
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~cgrabowski/maas:fix_dns_update_race_condition
Merge into: maas:master
Diff against target: 141 lines (+65/-5)
3 files modified
src/maasserver/region_controller.py (+13/-2)
src/maasserver/tests/test_region_controller.py (+52/-0)
src/provisioningserver/dns/zoneconfig.py (+0/-3)
Reviewer Review Type Date Requested Status
Alexsander de Souza Approve
MAAS Lander Approve
Review via email: mp+436566@code.launchpad.net

Commit message

store updates in a separate list while updating BIND

no longer remove BIND jnl

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix_dns_update_race_condition lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: a2e3f48b6d1b268f2bc9c4935df538227aa117d0

review: Approve
Revision history for this message
Alexsander de Souza (alexsander-souza) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/region_controller.py b/src/maasserver/region_controller.py
index a7fa69c..a8cb828 100644
--- a/src/maasserver/region_controller.py
+++ b/src/maasserver/region_controller.py
@@ -98,6 +98,8 @@ class RegionControllerService(Service):
98 self.needsProxyUpdate = False98 self.needsProxyUpdate = False
99 self.needsRBACUpdate = False99 self.needsRBACUpdate = False
100 self._dns_updates = []100 self._dns_updates = []
101 self._queued_updates = []
102 self._dns_update_in_progress = False
101 self._dns_requires_full_reload = True103 self._dns_requires_full_reload = True
102 self.postgresListener = postgresListener104 self.postgresListener = postgresListener
103 self.dnsResolver = Resolver(105 self.dnsResolver = Resolver(
@@ -185,7 +187,10 @@ class RegionControllerService(Service):
185 self._dns_requires_full_reload = (187 self._dns_requires_full_reload = (
186 self._dns_requires_full_reload or need_reload188 self._dns_requires_full_reload or need_reload
187 )189 )
188 self._dns_updates += new_updates190 if self._dns_update_in_progress:
191 self._queued_updates += new_updates
192 else:
193 self._dns_updates += new_updates
189194
190 def startProcessing(self):195 def startProcessing(self):
191 """Start the process looping call."""196 """Start the process looping call."""
@@ -217,13 +222,19 @@ class RegionControllerService(Service):
217 return pause(delay)222 return pause(delay)
218223
219 def _clear_dynamic_dns_updates(d):224 def _clear_dynamic_dns_updates(d):
220 self._dns_updates = []225 if len(self._queued_updates) > 0:
226 self._dns_updates = self._queued_updates
227 self._queued_updates = []
228 else:
229 self._dns_updates = []
221 self._dns_requires_full_reload = False230 self._dns_requires_full_reload = False
231 self._dns_update_in_progress = False
222 return d232 return d
223233
224 defers = []234 defers = []
225 if self.needsDNSUpdate:235 if self.needsDNSUpdate:
226 self.needsDNSUpdate = False236 self.needsDNSUpdate = False
237 self._dns_update_in_progress = True
227 d = deferToDatabase(238 d = deferToDatabase(
228 transactional(239 transactional(
229 dns_update_all_zones,240 dns_update_all_zones,
diff --git a/src/maasserver/tests/test_region_controller.py b/src/maasserver/tests/test_region_controller.py
index 4e97cdd..072d3b3 100644
--- a/src/maasserver/tests/test_region_controller.py
+++ b/src/maasserver/tests/test_region_controller.py
@@ -36,6 +36,7 @@ from maastesting.matchers import (
36 MockCallsMatch,36 MockCallsMatch,
37 MockNotCalled,37 MockNotCalled,
38)38)
39from provisioningserver.dns.config import DynamicDNSUpdate
39from provisioningserver.utils.events import Event40from provisioningserver.utils.events import Event
4041
41wait_for_reactor = wait_for()42wait_for_reactor = wait_for()
@@ -841,3 +842,54 @@ class TestRegionControllerServiceTransactional(MAASTransactionServerTestCase):
841 self.assertEqual(rbac_sync.id, last_sync.id)842 self.assertEqual(rbac_sync.id, last_sync.id)
842 self.assertEqual(last_sync.resource_type, "resource-pool")843 self.assertEqual(last_sync.resource_type, "resource-pool")
843 self.assertEqual(last_sync.sync_id, "x-y-z")844 self.assertEqual(last_sync.sync_id, "x-y-z")
845
846 @wait_for_reactor
847 @inlineCallbacks
848 def test_queueDynamicDNSUpdate_queues_in_separate_list_while_update_in_progress(
849 self,
850 ):
851 domain = yield deferToDatabase(factory.make_Domain)
852 update_result = (random.randint(0, 10), True, [domain.name])
853 record = yield deferToDatabase(factory.make_DNSResource, domain=domain)
854 service = RegionControllerService(sentinel.listener)
855
856 update_zones = self.patch(region_controller, "dns_update_all_zones")
857 update_zones.return_value = update_result
858 check_serial = self.patch(service, "_checkSerial")
859 check_serial.return_value = succeed(update_result)
860
861 service._dns_update_in_progress = True
862 service.queueDynamicDNSUpdate(
863 factory.make_name(),
864 f"INSERT {domain.name} {record.name} A 30 10.10.10.10",
865 )
866 self.assertCountEqual(service._dns_updates, [])
867 self.assertCountEqual(
868 service._queued_updates,
869 [
870 DynamicDNSUpdate(
871 operation="INSERT",
872 name=f"{record.name}.{domain.name}",
873 zone=domain.name,
874 rectype="A",
875 ttl=30,
876 answer="10.10.10.10",
877 )
878 ],
879 )
880 service.needsDNSUpdate = True
881 yield service.process()
882 self.assertCountEqual(
883 service._dns_updates,
884 [
885 DynamicDNSUpdate(
886 operation="INSERT",
887 name=f"{record.name}.{domain.name}",
888 zone=domain.name,
889 rectype="A",
890 ttl=30,
891 answer="10.10.10.10",
892 )
893 ],
894 )
895 self.assertCountEqual(service._queued_updates, [])
diff --git a/src/provisioningserver/dns/zoneconfig.py b/src/provisioningserver/dns/zoneconfig.py
index ec5da14..2992337 100644
--- a/src/provisioningserver/dns/zoneconfig.py
+++ b/src/provisioningserver/dns/zoneconfig.py
@@ -7,7 +7,6 @@
7from datetime import datetime7from datetime import datetime
8from itertools import chain8from itertools import chain
9import os9import os
10from pathlib import Path
1110
12from netaddr import IPAddress, IPNetwork, spanning_cidr11from netaddr import IPAddress, IPNetwork, spanning_cidr
13from netaddr.core import AddrFormatError12from netaddr.core import AddrFormatError
@@ -347,7 +346,6 @@ class DNSForwardZoneConfig(DomainConfigBase):
347 labels={"zone": self.domain},346 labels={"zone": self.domain},
348 )347 )
349 else:348 else:
350 Path(f"{zi.target_path}.jnl").unlink(missing_ok=True)
351 self.requires_reload = True349 self.requires_reload = True
352 needs_freeze_thaw = self.zone_file_exists(zi)350 needs_freeze_thaw = self.zone_file_exists(zi)
353 with freeze_thaw_zone(needs_freeze_thaw, zone=zi.zone_name):351 with freeze_thaw_zone(needs_freeze_thaw, zone=zi.zone_name):
@@ -649,7 +647,6 @@ class DNSReverseZoneConfig(DomainConfigBase):
649 labels={"zone": self.domain},647 labels={"zone": self.domain},
650 )648 )
651 else:649 else:
652 Path(f"{zi.target_path}.jnl").unlink(missing_ok=True)
653 self.requires_reload = True650 self.requires_reload = True
654 needs_freeze_thaw = self.zone_file_exists(zi)651 needs_freeze_thaw = self.zone_file_exists(zi)
655 with freeze_thaw_zone(needs_freeze_thaw, zone=zi.zone_name):652 with freeze_thaw_zone(needs_freeze_thaw, zone=zi.zone_name):

Subscribers

People subscribed via source and target branches