Merge ~cgrabowski/maas:backport_lp2062107_fix_3.4 into maas:3.4

Proposed by Christian Grabowski
Status: Merged
Approved by: Christian Grabowski
Approved revision: e5a2fb2a7a8fa2cfbf148c394f7b08de5a66f1c3
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~cgrabowski/maas:backport_lp2062107_fix_3.4
Merge into: maas:3.4
Diff against target: 127 lines (+60/-6)
3 files modified
src/maasserver/region_controller.py (+5/-5)
src/maasserver/tests/test_region_controller.py (+55/-0)
src/provisioningserver/dns/zoneconfig.py (+0/-1)
Reviewer Review Type Date Requested Status
Christian Grabowski Approve
Review via email: mp+465008@code.launchpad.net

Commit message

fix: handle BIND failures when notifies are delayed
(cherry picked from commit 19ac75f3d5e2bcb7d4934579aa94717dc1823104)

To post a comment you must log in.
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

self-approving backport

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/region_controller.py b/src/maasserver/region_controller.py
2index 7cc6428..590ca1d 100644
3--- a/src/maasserver/region_controller.py
4+++ b/src/maasserver/region_controller.py
5@@ -329,10 +329,6 @@ class RegionControllerService(Service):
6 return None
7 serial, reloaded, domain_names = result
8
9- # check that there is not a newer serial we should query instead
10- if self._dns_latest_serial and self._dns_latest_serial > serial:
11- return result
12-
13 if not reloaded:
14 raise DNSReloadError(
15 "Failed to reload DNS; timeout or rdnc command failed."
16@@ -340,6 +336,10 @@ class RegionControllerService(Service):
17 not_matching_domains = set(domain_names)
18 loop = 0
19 while len(not_matching_domains) > 0 and loop != 30:
20+ # check that there is not a newer serial we should query instead
21+ if self._dns_latest_serial and self._dns_latest_serial > serial:
22+ return result
23+
24 for domain in list(not_matching_domains):
25 try:
26 answers, _, _ = yield self.dnsResolver.lookupAuthority(
27@@ -401,7 +401,7 @@ class RegionControllerService(Service):
28 def _onDNSReloadFailure(self, failure):
29 """Force kill and restart bind9."""
30 failure.trap(DNSReloadError)
31- if not self.retryOnFailure:
32+ if not self.retryOnFailure or self._dns_update_in_progress:
33 return failure
34 log.err(failure, "Failed configuring DNS; killing and restarting")
35 d = service_monitor.killService("bind9")
36diff --git a/src/maasserver/tests/test_region_controller.py b/src/maasserver/tests/test_region_controller.py
37index 0b45912..bdcd75f 100644
38--- a/src/maasserver/tests/test_region_controller.py
39+++ b/src/maasserver/tests/test_region_controller.py
40@@ -24,6 +24,7 @@ from maasserver.region_controller import (
41 RegionControllerService,
42 )
43 from maasserver.secrets import SecretManager
44+from maasserver.service_monitor import service_monitor
45 from maasserver.testing.factory import factory
46 from maasserver.testing.testcase import (
47 MAASServerTestCase,
48@@ -346,6 +347,28 @@ class TestRegionControllerService(MAASServerTestCase):
49
50 @wait_for_reactor
51 @inlineCallbacks
52+ def test_process_waits_for_in_progress_update_for_dns_failure_restart(
53+ self,
54+ ):
55+ service = self.make_service(sentinel.listener, sentinel.dbtasks)
56+ service.needsDNSUpdate = True
57+ mock_kill_service = self.patch(service_monitor, "killService")
58+ self.patch(region_controller, "dns_update_all_zones")
59+
60+ def set_in_progress(*args):
61+ service._dns_update_in_progress = True
62+
63+ self.patch(
64+ region_controller, "_clear_dynamic_dns_update"
65+ ).side_effect = set_in_progress
66+ mock_dns_check_serial = self.patch(region_controller, "_checkSerial")
67+ mock_dns_check_serial.side_effect = fail(DNSReloadError())
68+ service.startProcessing()
69+ yield service.processingDefer
70+ mock_kill_service.assert_not_called()
71+
72+ @wait_for_reactor
73+ @inlineCallbacks
74 def test_process_updates_proxy_logs_failure(self):
75 service = self.make_service(sentinel.listener, sentinel.dbtasks)
76 service.needsProxyUpdate = True
77@@ -512,6 +535,38 @@ class TestRegionControllerService(MAASServerTestCase):
78 with ExpectedException(DNSReloadError):
79 yield service._checkSerial((formatted_serial, True, dns_names))
80
81+ @wait_for_reactor
82+ @inlineCallbacks
83+ def test_check_serial_returns_early_if_newer_serial_exists(self):
84+ service = self.make_service(sentinel.listern, sentinel.dbtasks)
85+ first_serial = random.randint(1, 1000)
86+ second_serial = first_serial + 1
87+ formatted_first_serial = f"{first_serial:10d}"
88+ formatted_second_serial = f"{second_serial:10d}"
89+ dns_names = [factory.make_name("domain") for _ in range(3)]
90+ mock_lookup = self.patch(service.dnsResolver, "lookupAuthority")
91+ mock_lookup.side_effect = [
92+ # First pass no results.
93+ succeed(([], [], [])),
94+ succeed(([], [], [])),
95+ succeed(([], [], [])),
96+ # First domain valid result.
97+ succeed(([self.make_soa_result(first_serial)], [], [])),
98+ succeed(([], [], [])),
99+ succeed(([], [], [])),
100+ # Second domain wrong serial.
101+ succeed(([self.make_soa_result(first_serial)], [], [])),
102+ succeed(([], [], [])),
103+ # Third domain correct serial.
104+ succeed(([], [], [])),
105+ succeed(([self.make_soa_result(second_serial)], [], [])),
106+ # Second domain correct serial.
107+ succeed(([self.make_soa_result(second_serial)], [], [])),
108+ ]
109+ d = service._checkSerial((formatted_first_serial, True, dns_names))
110+ service._dns_latest_serial = formatted_second_serial
111+ yield d
112+
113 def test_getRBACClient_returns_None_when_no_url(self):
114 service = self.make_service(sentinel.listener, sentinel.dbtasks)
115 service.rbacClient = sentinel.client
116diff --git a/src/provisioningserver/dns/zoneconfig.py b/src/provisioningserver/dns/zoneconfig.py
117index cf8a8ef..2a80cbe 100644
118--- a/src/provisioningserver/dns/zoneconfig.py
119+++ b/src/provisioningserver/dns/zoneconfig.py
120@@ -226,7 +226,6 @@ class DomainConfigBase:
121 uid=os.getuid(),
122 gid=os.getgid(),
123 )
124- pass
125
126
127 class DNSForwardZoneConfig(DomainConfigBase):

Subscribers

People subscribed via source and target branches