Merge ~cgrabowski/maas:fix_dns_tx_serialization into maas:master
- Git
- lp:~cgrabowski/maas
- fix_dns_tx_serialization
- Merge into master
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Christian Grabowski | ||||||||
Approved revision: | d161385a8d3f045786adc9de3089895b853d07af | ||||||||
Merge reported by: | MAAS Lander | ||||||||
Merged at revision: | not available | ||||||||
Proposed branch: | ~cgrabowski/maas:fix_dns_tx_serialization | ||||||||
Merge into: | maas:master | ||||||||
Diff against target: |
244 lines (+130/-15) 5 files modified
src/maasserver/region_controller.py (+17/-0) src/maasserver/tests/test_region_controller.py (+20/-0) src/maasserver/triggers/system.py (+16/-11) src/maasserver/triggers/testing.py (+4/-4) src/maasserver/triggers/tests/test_system.py (+73/-0) |
||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Lander | Approve | ||
Alexsander de Souza | Approve | ||
Review via email:
|
Commit message
skip checking serial if a newer one exists
update interface+ip trigger to ignore controllers handled in other trigger
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b fix_dns_
STATUS: FAILED
LOG: http://
COMMIT: 7bc0cde0ab97184
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alexsander de Souza (alexsander-souza) wrote : | # |
+1
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b fix_dns_
STATUS: FAILED
LOG: http://
COMMIT: d161385a8d3f045
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Christian Grabowski (cgrabowski) wrote : | # |
jenkins: !test
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b fix_dns_
STATUS: FAILED
LOG: http://
COMMIT: d161385a8d3f045
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Christian Grabowski (cgrabowski) wrote : | # |
jenkins: !test
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b fix_dns_
STATUS: SUCCESS
COMMIT: d161385a8d3f045
Preview Diff
1 | diff --git a/src/maasserver/region_controller.py b/src/maasserver/region_controller.py | |||
2 | index de5e1e8..1c8e014 100644 | |||
3 | --- a/src/maasserver/region_controller.py | |||
4 | +++ b/src/maasserver/region_controller.py | |||
5 | @@ -101,6 +101,7 @@ class RegionControllerService(Service): | |||
6 | 101 | self._queued_updates = [] | 101 | self._queued_updates = [] |
7 | 102 | self._dns_update_in_progress = False | 102 | self._dns_update_in_progress = False |
8 | 103 | self._dns_requires_full_reload = True | 103 | self._dns_requires_full_reload = True |
9 | 104 | self._dns_latest_serial = None | ||
10 | 104 | self.postgresListener = postgresListener | 105 | self.postgresListener = postgresListener |
11 | 105 | self.dnsResolver = Resolver( | 106 | self.dnsResolver = Resolver( |
12 | 106 | resolv=None, | 107 | resolv=None, |
13 | @@ -232,6 +233,16 @@ class RegionControllerService(Service): | |||
14 | 232 | self._dns_update_in_progress = False | 233 | self._dns_update_in_progress = False |
15 | 233 | return d | 234 | return d |
16 | 234 | 235 | ||
17 | 236 | def _set_latest_serial(result): | ||
18 | 237 | if result: | ||
19 | 238 | (serial, _, _) = result | ||
20 | 239 | if ( | ||
21 | 240 | not self._dns_latest_serial | ||
22 | 241 | or self._dns_latest_serial < serial | ||
23 | 242 | ): | ||
24 | 243 | self._dns_latest_serial = serial | ||
25 | 244 | return result | ||
26 | 245 | |||
27 | 235 | defers = [] | 246 | defers = [] |
28 | 236 | if self.needsDNSUpdate: | 247 | if self.needsDNSUpdate: |
29 | 237 | self.needsDNSUpdate = False | 248 | self.needsDNSUpdate = False |
30 | @@ -244,6 +255,7 @@ class RegionControllerService(Service): | |||
31 | 244 | requires_reload=self._dns_requires_full_reload, | 255 | requires_reload=self._dns_requires_full_reload, |
32 | 245 | ) | 256 | ) |
33 | 246 | d.addCallback(_clear_dynamic_dns_updates) | 257 | d.addCallback(_clear_dynamic_dns_updates) |
34 | 258 | d.addCallback(_set_latest_serial) | ||
35 | 247 | d.addCallback(self._checkSerial) | 259 | d.addCallback(self._checkSerial) |
36 | 248 | d.addCallback(self._logDNSReload) | 260 | d.addCallback(self._logDNSReload) |
37 | 249 | # Order here matters, first needsDNSUpdate is set then pass the | 261 | # Order here matters, first needsDNSUpdate is set then pass the |
38 | @@ -284,6 +296,11 @@ class RegionControllerService(Service): | |||
39 | 284 | if result is None: | 296 | if result is None: |
40 | 285 | return None | 297 | return None |
41 | 286 | serial, reloaded, domain_names = result | 298 | serial, reloaded, domain_names = result |
42 | 299 | |||
43 | 300 | # check that there is not a newer serial we should query instead | ||
44 | 301 | if self._dns_latest_serial and self._dns_latest_serial > serial: | ||
45 | 302 | return result | ||
46 | 303 | |||
47 | 287 | if not reloaded: | 304 | if not reloaded: |
48 | 288 | raise DNSReloadError( | 305 | raise DNSReloadError( |
49 | 289 | "Failed to reload DNS; timeout or rdnc command failed." | 306 | "Failed to reload DNS; timeout or rdnc command failed." |
50 | diff --git a/src/maasserver/tests/test_region_controller.py b/src/maasserver/tests/test_region_controller.py | |||
51 | index e5a1f09..1a9ee32 100644 | |||
52 | --- a/src/maasserver/tests/test_region_controller.py | |||
53 | +++ b/src/maasserver/tests/test_region_controller.py | |||
54 | @@ -163,6 +163,11 @@ class TestRegionControllerService(MAASServerTestCase): | |||
55 | 163 | mock_dns_update_all_zones = self.patch( | 163 | mock_dns_update_all_zones = self.patch( |
56 | 164 | region_controller, "dns_update_all_zones" | 164 | region_controller, "dns_update_all_zones" |
57 | 165 | ) | 165 | ) |
58 | 166 | mock_dns_update_all_zones.returnValue = ( | ||
59 | 167 | random.randint(1, 1000), | ||
60 | 168 | True, | ||
61 | 169 | [factory.make_name("domain") for _ in range(3)], | ||
62 | 170 | ) | ||
63 | 166 | service.startProcessing() | 171 | service.startProcessing() |
64 | 167 | yield service.processingDefer | 172 | yield service.processingDefer |
65 | 168 | mock_dns_update_all_zones.assert_called_once() | 173 | mock_dns_update_all_zones.assert_called_once() |
66 | @@ -947,3 +952,18 @@ class TestRegionControllerServiceTransactional(MAASTransactionServerTestCase): | |||
67 | 947 | call(dynamic_updates=expected_updates, requires_reload=False), | 952 | call(dynamic_updates=expected_updates, requires_reload=False), |
68 | 948 | ] | 953 | ] |
69 | 949 | ) | 954 | ) |
70 | 955 | |||
71 | 956 | @wait_for_reactor | ||
72 | 957 | @inlineCallbacks | ||
73 | 958 | def test_check_serial_is_skipped_if_a_newer_serial_exists(self): | ||
74 | 959 | domain = yield deferToDatabase(factory.make_Domain) | ||
75 | 960 | update_result = (random.randint(0, 10), True, [domain.name]) | ||
76 | 961 | service = RegionControllerService(sentinel.listener) | ||
77 | 962 | |||
78 | 963 | query = self.patch(service.dnsResolver, "lookupAuthority") | ||
79 | 964 | |||
80 | 965 | service._dns_latest_serial = update_result[0] + 1 | ||
81 | 966 | |||
82 | 967 | yield service._checkSerial(update_result) | ||
83 | 968 | |||
84 | 969 | query.assert_not_called() | ||
85 | diff --git a/src/maasserver/triggers/system.py b/src/maasserver/triggers/system.py | |||
86 | index c6313f9..3c38339 100644 | |||
87 | --- a/src/maasserver/triggers/system.py | |||
88 | +++ b/src/maasserver/triggers/system.py | |||
89 | @@ -2061,6 +2061,7 @@ def render_dns_dynamic_update_interface_static_ip_address(op): | |||
90 | 2061 | CREATE OR REPLACE FUNCTION sys_dns_updates_interface_ip_{op}() | 2061 | CREATE OR REPLACE FUNCTION sys_dns_updates_interface_ip_{op}() |
91 | 2062 | RETURNS trigger as $$ | 2062 | RETURNS trigger as $$ |
92 | 2063 | DECLARE | 2063 | DECLARE |
93 | 2064 | node_type int; | ||
94 | 2064 | current_hostname text; | 2065 | current_hostname text; |
95 | 2065 | domain text; | 2066 | domain text; |
96 | 2066 | iface_name text; | 2067 | iface_name text; |
97 | @@ -2070,26 +2071,30 @@ def render_dns_dynamic_update_interface_static_ip_address(op): | |||
98 | 2070 | ASSERT TG_WHEN = 'AFTER', 'May only run as an AFTER trigger'; | 2071 | ASSERT TG_WHEN = 'AFTER', 'May only run as an AFTER trigger'; |
99 | 2071 | ASSERT TG_LEVEL <> 'STATEMENT', 'Should not be used as a STATEMENT level trigger', TG_NAME; | 2072 | ASSERT TG_LEVEL <> 'STATEMENT', 'Should not be used as a STATEMENT level trigger', TG_NAME; |
100 | 2072 | IF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN | 2073 | IF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN |
102 | 2073 | SELECT iface.name, node.hostname, domain_tbl.name, COALESCE(domain_tbl.ttl, 0) INTO iface_name, current_hostname, domain, address_ttl | 2074 | SELECT iface.name, node.hostname, node.node_type, domain_tbl.name, COALESCE(domain_tbl.ttl, 0) INTO iface_name, current_hostname, node_type, domain, address_ttl |
103 | 2074 | FROM maasserver_interface AS iface | 2075 | FROM maasserver_interface AS iface |
104 | 2075 | JOIN maasserver_node AS node ON iface.node_config_id = node.current_config_id | 2076 | JOIN maasserver_node AS node ON iface.node_config_id = node.current_config_id |
105 | 2076 | JOIN maasserver_domain AS domain_tbl ON domain_tbl.id=node.domain_id WHERE iface.id=NEW.interface_id; | 2077 | JOIN maasserver_domain AS domain_tbl ON domain_tbl.id=node.domain_id WHERE iface.id=NEW.interface_id; |
106 | 2077 | SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=NEW.staticipaddress_id; | 2078 | SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=NEW.staticipaddress_id; |
109 | 2078 | PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr); | 2079 | IF (node_type={NODE_TYPE.MACHINE} OR node_type={NODE_TYPE.DEVICE}) THEN |
110 | 2079 | PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr); | 2080 | PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr); |
111 | 2081 | PERFORM pg_notify('sys_dns_updates', 'INSERT ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || address_ttl || ' ' || ip_addr); | ||
112 | 2082 | END IF; | ||
113 | 2080 | ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN | 2083 | ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN |
114 | 2081 | IF EXISTS(SELECT id FROM maasserver_interface WHERE id=OLD.interface_id) THEN | 2084 | IF EXISTS(SELECT id FROM maasserver_interface WHERE id=OLD.interface_id) THEN |
116 | 2082 | SELECT iface.name, node.hostname, domain_tbl.name, COALESCE(domain_tbl.ttl, 0) INTO iface_name, current_hostname, domain, address_ttl | 2085 | SELECT iface.name, node.hostname, node.node_type, domain_tbl.name, COALESCE(domain_tbl.ttl, 0) INTO iface_name, current_hostname, node_type, domain, address_ttl |
117 | 2083 | FROM maasserver_interface AS iface | 2086 | FROM maasserver_interface AS iface |
118 | 2084 | JOIN maasserver_node AS node ON iface.node_config_id = node.current_config_id | 2087 | JOIN maasserver_node AS node ON iface.node_config_id = node.current_config_id |
119 | 2085 | JOIN maasserver_domain AS domain_tbl ON domain_tbl.id=node.domain_id WHERE iface.id=OLD.interface_id; | 2088 | JOIN maasserver_domain AS domain_tbl ON domain_tbl.id=node.domain_id WHERE iface.id=OLD.interface_id; |
127 | 2086 | IF EXISTS(SELECT id FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id) THEN | 2089 | IF (node_type={NODE_TYPE.MACHINE} OR node_type={NODE_TYPE.DEVICE}) THEN |
128 | 2087 | SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id; | 2090 | IF EXISTS(SELECT id FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id) THEN |
129 | 2088 | PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || current_hostname || ' A ' || ip_addr); | 2091 | SELECT host(ip) INTO ip_addr FROM maasserver_staticipaddress WHERE id=OLD.staticipaddress_id; |
130 | 2089 | PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || ip_addr); | 2092 | PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || current_hostname || ' A ' || ip_addr); |
131 | 2090 | ELSE | 2093 | PERFORM pg_notify('sys_dns_updates', 'DELETE ' || domain || ' ' || iface_name || '.' || current_hostname || ' A ' || ip_addr); |
132 | 2091 | PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' A ' || OLD.interface_id); | 2094 | ELSE |
133 | 2092 | PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' AAAA ' || OLD.interface_id); | 2095 | PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' A ' || OLD.interface_id); |
134 | 2096 | PERFORM pg_notify('sys_dns_updates', 'DELETE-IFACE-IP ' || domain || ' ' || current_hostname || ' AAAA ' || OLD.interface_id); | ||
135 | 2097 | END IF; | ||
136 | 2093 | END IF; | 2098 | END IF; |
137 | 2094 | END IF; | 2099 | END IF; |
138 | 2095 | END IF; | 2100 | END IF; |
139 | diff --git a/src/maasserver/triggers/testing.py b/src/maasserver/triggers/testing.py | |||
140 | index 3e6fa68..30d0979 100644 | |||
141 | --- a/src/maasserver/triggers/testing.py | |||
142 | +++ b/src/maasserver/triggers/testing.py | |||
143 | @@ -965,13 +965,13 @@ class NotifyHelperMixin: | |||
144 | 965 | 965 | ||
145 | 966 | @inlineCallbacks | 966 | @inlineCallbacks |
146 | 967 | def listen(self, channel, msg): | 967 | def listen(self, channel, msg): |
148 | 968 | if msg: | 968 | if msg and channel in self.channel_queues: |
149 | 969 | yield self.channel_queues[channel].put(msg) | 969 | yield self.channel_queues[channel].put(msg) |
150 | 970 | 970 | ||
151 | 971 | @inlineCallbacks | ||
152 | 972 | def get_notify(self, channel): | 971 | def get_notify(self, channel): |
155 | 973 | msg = yield self.channel_queues[channel].get() | 972 | if channel in self.channel_queues: |
156 | 974 | return msg | 973 | return self.channel_queues[channel].get() |
157 | 974 | return None | ||
158 | 975 | 975 | ||
159 | 976 | def start_reading(self): | 976 | def start_reading(self): |
160 | 977 | for channel in self.channels: | 977 | for channel in self.channels: |
161 | diff --git a/src/maasserver/triggers/tests/test_system.py b/src/maasserver/triggers/tests/test_system.py | |||
162 | index ce7398e..675fe89 100644 | |||
163 | --- a/src/maasserver/triggers/tests/test_system.py | |||
164 | +++ b/src/maasserver/triggers/tests/test_system.py | |||
165 | @@ -540,6 +540,79 @@ class TestSysDNSUpdates( | |||
166 | 540 | 540 | ||
167 | 541 | @wait_for_reactor | 541 | @wait_for_reactor |
168 | 542 | @inlineCallbacks | 542 | @inlineCallbacks |
169 | 543 | def test_dns_dynamic_update_interface_static_ip_address_ignores_controllers( | ||
170 | 544 | self, | ||
171 | 545 | ): | ||
172 | 546 | listener = self.make_listener_without_delay() | ||
173 | 547 | yield self.set_service(listener) | ||
174 | 548 | yield deferToDatabase( | ||
175 | 549 | self.register_trigger, | ||
176 | 550 | "maasserver_interface_ip_addresses", | ||
177 | 551 | "sys_dns_updates", | ||
178 | 552 | ops=("delete",), | ||
179 | 553 | trigger="sys_dns_updates_interface_ip_delete", | ||
180 | 554 | ) | ||
181 | 555 | vlan = yield deferToDatabase(self.create_vlan) | ||
182 | 556 | subnet1 = yield deferToDatabase( | ||
183 | 557 | self.create_subnet, params={"vlan": vlan} | ||
184 | 558 | ) | ||
185 | 559 | subnet2 = yield deferToDatabase( | ||
186 | 560 | self.create_subnet, params={"vlan": vlan} | ||
187 | 561 | ) | ||
188 | 562 | node1 = yield deferToDatabase( | ||
189 | 563 | self.create_node_with_interface, | ||
190 | 564 | params={ | ||
191 | 565 | "node_type": NODE_TYPE.RACK_CONTROLLER, | ||
192 | 566 | "subnet": subnet1, | ||
193 | 567 | "status": NODE_STATUS.DEPLOYED, | ||
194 | 568 | }, | ||
195 | 569 | ) | ||
196 | 570 | node2 = yield deferToDatabase( | ||
197 | 571 | self.create_node_with_interface, | ||
198 | 572 | params={"subnet": subnet2, "status": NODE_STATUS.DEPLOYED}, | ||
199 | 573 | ) | ||
200 | 574 | domain = yield deferToDatabase(Domain.objects.get_default_domain) | ||
201 | 575 | iface1 = yield deferToDatabase( | ||
202 | 576 | lambda: node1.current_config.interface_set.first() | ||
203 | 577 | ) | ||
204 | 578 | iface2 = yield deferToDatabase( | ||
205 | 579 | lambda: node2.current_config.interface_set.first() | ||
206 | 580 | ) | ||
207 | 581 | ip1 = yield deferToDatabase( | ||
208 | 582 | lambda: self.create_staticipaddress( | ||
209 | 583 | params={ | ||
210 | 584 | "ip": subnet1.get_next_ip_for_allocation()[0], | ||
211 | 585 | "interface": iface1, | ||
212 | 586 | "subnet": subnet1, | ||
213 | 587 | } | ||
214 | 588 | ) | ||
215 | 589 | ) | ||
216 | 590 | ip2 = yield deferToDatabase( | ||
217 | 591 | lambda: self.create_staticipaddress( | ||
218 | 592 | params={ | ||
219 | 593 | "ip": subnet2.get_next_ip_for_allocation()[0], | ||
220 | 594 | "interface": iface2, | ||
221 | 595 | "subnet": subnet2, | ||
222 | 596 | } | ||
223 | 597 | ) | ||
224 | 598 | ) | ||
225 | 599 | self.start_reading() | ||
226 | 600 | try: | ||
227 | 601 | yield deferToDatabase(iface1.unlink_ip_address, ip1) | ||
228 | 602 | yield deferToDatabase(iface2.unlink_ip_address, ip2) | ||
229 | 603 | expected_msgs = ( | ||
230 | 604 | f"DELETE {domain.name} {node2.hostname} A {ip2.ip}", | ||
231 | 605 | f"DELETE {domain.name} {iface2.name}.{node2.hostname} A {ip2.ip}", | ||
232 | 606 | ) | ||
233 | 607 | for exp in expected_msgs: | ||
234 | 608 | msg = yield self.get_notify("sys_dns_updates") | ||
235 | 609 | self.assertEqual(msg, exp) | ||
236 | 610 | finally: | ||
237 | 611 | self.stop_reading() | ||
238 | 612 | yield self.postgres_listener_service.stopService() | ||
239 | 613 | |||
240 | 614 | @wait_for_reactor | ||
241 | 615 | @inlineCallbacks | ||
242 | 543 | def test_dns_dynamc_update_ip_update(self): | 616 | def test_dns_dynamc_update_ip_update(self): |
243 | 544 | listener = self.make_listener_without_delay() | 617 | listener = self.make_listener_without_delay() |
244 | 545 | yield self.set_service(listener) | 618 | yield self.set_service(listener) |
UNIT TESTS tx_serializatio n lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas
-b fix_dns_
STATUS: FAILED maas-ci. internal: 8080/job/ maas-tester/ 2403/console e50fd2c1fa45e95 9995f80054
LOG: http://
COMMIT: 139936def8b8cb1