Merge lp:~trapnine/maas/fix-1499378 into lp:~maas-committers/maas/trunk

Proposed by Jeffrey C Jones
Status: Merged
Approved by: Jeffrey C Jones
Approved revision: no longer in the source branch.
Merged at revision: 4403
Proposed branch: lp:~trapnine/maas/fix-1499378
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 169 lines (+38/-40)
2 files modified
src/provisioningserver/dns/actions.py (+21/-17)
src/provisioningserver/dns/tests/test_actions.py (+17/-23)
To merge this branch: bzr merge lp:~trapnine/maas/fix-1499378
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+275259@code.launchpad.net

Commit message

Prevent rndc from raising an exception that causes regiond to crash.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

Please make the commit message more of a sentence.

"Prevent rndc from raising an exception that causes regiond to crash."

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/dns/actions.py'
2--- src/provisioningserver/dns/actions.py 2015-05-07 18:14:38 +0000
3+++ src/provisioningserver/dns/actions.py 2015-10-22 00:13:47 +0000
4@@ -58,14 +58,18 @@
5
6
7 def bind_reload():
8- """Ask BIND to reload its configuration and all zone files."""
9+ """Ask BIND to reload its configuration and all zone files. This operation
10+ is 'best effort' (with logging) as the server may not be running, and there
11+ is often no context for reporting.
12+
13+ :return: True if success, False otherwise.
14+ """
15 try:
16 execute_rndc_command(("reload",))
17+ return True
18 except CalledProcessError as exc:
19- maaslog.error("Reloading BIND failed: %s", exc)
20- # Log before upgrade so that the output does not go to maaslog.
21- ExternalProcessError.upgrade(exc)
22- raise
23+ maaslog.error("Reloading BIND failed (is it running?): %s", exc)
24+ return False
25
26
27 def bind_reload_with_retries(attempts=10, interval=2):
28@@ -75,29 +79,29 @@
29 :param interval: The time in seconds to sleep between each attempt.
30 """
31 for countdown in xrange(attempts - 1, -1, -1):
32- try:
33- bind_reload()
34- except CalledProcessError:
35- if countdown == 0:
36- raise
37- else:
38- sleep(interval)
39+ if bind_reload():
40+ break
41+ if countdown == 0:
42+ break
43 else:
44- break
45+ sleep(interval)
46
47
48 def bind_reload_zone(zone_name):
49 """Ask BIND to reload the zone file for the given zone.
50
51 :param zone_name: The name of the zone to reload.
52+ :return: True if success, False otherwise.
53 """
54 try:
55 execute_rndc_command(("reload", zone_name))
56+ return True
57 except CalledProcessError as exc:
58- maaslog.error("Reloading BIND zone %r failed: %s", zone_name, exc)
59- # Log before upgrade so that the output does not go to maaslog.
60- ExternalProcessError.upgrade(exc)
61- raise
62+ maaslog.error(
63+ "Reloading BIND zone %r failed (is it running?): %s",
64+ zone_name,
65+ exc)
66+ return False
67
68
69 def bind_write_configuration(zones, trusted_networks):
70
71=== modified file 'src/provisioningserver/dns/tests/test_actions.py'
72--- src/provisioningserver/dns/tests/test_actions.py 2015-05-07 18:14:38 +0000
73+++ src/provisioningserver/dns/tests/test_actions.py 2015-10-22 00:13:47 +0000
74@@ -93,16 +93,16 @@
75 erc = self.patch_autospec(actions, "execute_rndc_command")
76 erc.side_effect = factory.make_CalledProcessError()
77 with FakeLogger("maas") as logger:
78- self.assertRaises(CalledProcessError, actions.bind_reload)
79+ self.assertFalse(actions.bind_reload())
80 self.assertDocTestMatches(
81- "Reloading BIND failed: "
82+ "Reloading BIND failed (is it running?): "
83 "Command ... returned non-zero exit status ...",
84 logger.output)
85
86- def test__upgrades_subprocess_error(self):
87+ def test__false_on_subprocess_error(self):
88 erc = self.patch_autospec(actions, "execute_rndc_command")
89 erc.side_effect = factory.make_CalledProcessError()
90- self.assertRaises(ExternalProcessError, actions.bind_reload)
91+ self.assertFalse(actions.bind_reload())
92
93
94 class TestReloadWithRetries(MAASTestCase):
95@@ -111,11 +111,9 @@
96 def test__calls_bind_reload_count_times(self):
97 self.patch_autospec(actions, "sleep") # Disable.
98 bind_reload = self.patch_autospec(actions, "bind_reload")
99- bind_reload.side_effect = factory.make_CalledProcessError()
100+ bind_reload.return_value = False
101 attempts = randint(3, 13)
102- self.assertRaises(
103- CalledProcessError, actions.bind_reload_with_retries,
104- attempts=attempts)
105+ actions.bind_reload_with_retries(attempts=attempts)
106 expected_calls = [call()] * attempts
107 self.assertThat(
108 actions.bind_reload,
109@@ -124,11 +122,10 @@
110 def test__returns_on_success(self):
111 self.patch_autospec(actions, "sleep") # Disable.
112 bind_reload = self.patch(actions, "bind_reload")
113- bind_reload.side_effect = [
114- factory.make_CalledProcessError(),
115- factory.make_CalledProcessError(),
116- None, # Success
117- ]
118+ bind_reload_return_values = [False, False, True, ]
119+ bind_reload.side_effect = lambda: (
120+ bind_reload_return_values.pop(0))
121+
122 actions.bind_reload_with_retries(attempts=5)
123 expected_calls = [call(), call(), call()]
124 self.assertThat(
125@@ -138,10 +135,9 @@
126 def test__sleeps_interval_seconds_between_attempts(self):
127 self.patch_autospec(actions, "sleep") # Disable.
128 bind_reload = self.patch_autospec(actions, "bind_reload")
129- bind_reload.side_effect = factory.make_CalledProcessError()
130+ bind_reload.return_value = False
131 attempts = randint(3, 13)
132- self.assertRaises(
133- CalledProcessError, actions.bind_reload_with_retries,
134+ actions.bind_reload_with_retries(
135 attempts=attempts, interval=sentinel.interval)
136 expected_sleep_calls = [call(sentinel.interval)] * (attempts - 1)
137 self.assertThat(actions.sleep, MockCallsMatch(*expected_sleep_calls))
138@@ -152,7 +148,7 @@
139
140 def test__executes_rndc_command(self):
141 self.patch_autospec(actions, "execute_rndc_command")
142- actions.bind_reload_zone(sentinel.zone)
143+ self.assertTrue(actions.bind_reload_zone(sentinel.zone))
144 self.assertThat(
145 actions.execute_rndc_command,
146 MockCalledOnceWith(("reload", sentinel.zone)))
147@@ -161,18 +157,16 @@
148 erc = self.patch_autospec(actions, "execute_rndc_command")
149 erc.side_effect = factory.make_CalledProcessError()
150 with FakeLogger("maas") as logger:
151- self.assertRaises(
152- CalledProcessError, actions.bind_reload_zone, sentinel.zone)
153+ self.assertFalse(actions.bind_reload_zone(sentinel.zone))
154 self.assertDocTestMatches(
155- "Reloading BIND zone ... failed: "
156+ "Reloading BIND zone ... failed (is it running?): "
157 "Command ... returned non-zero exit status ...",
158 logger.output)
159
160- def test__upgrades_subprocess_error(self):
161+ def test__false_on_subprocess_error(self):
162 erc = self.patch_autospec(actions, "execute_rndc_command")
163 erc.side_effect = factory.make_CalledProcessError()
164- self.assertRaises(
165- ExternalProcessError, actions.bind_reload_zone, sentinel.zone)
166+ self.assertFalse(actions.bind_reload_zone(sentinel.zone))
167
168
169 class TestConfiguration(PservTestCase):