Merge lp:~mpontillo/maas/fix-1524091-unmanaged-dhcp-for-deploy-and-delete-trunk into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 4546
Proposed branch: lp:~mpontillo/maas/fix-1524091-unmanaged-dhcp-for-deploy-and-delete-trunk
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 207 lines (+54/-28)
2 files modified
src/provisioningserver/rpc/dhcp.py (+30/-7)
src/provisioningserver/rpc/tests/test_dhcp.py (+24/-21)
To merge this branch: bzr merge lp:~mpontillo/maas/fix-1524091-unmanaged-dhcp-for-deploy-and-delete-trunk
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+279962@code.launchpad.net

Commit message

Don't require DHCP to be on if it should be off.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

Just need to change the function name.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.0 MiB)

The attempt to merge lp:~mpontillo/maas/fix-1524091-unmanaged-dhcp-for-deploy-and-delete-trunk into lp:maas failed. Below is the output from the failed tests.

Hit http://security.ubuntu.com xenial-security InRelease
Get:1 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial InRelease [227 kB]
Hit http://ppa.launchpad.net xenial InRelease
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates InRelease
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-backports InRelease
Hit http://security.ubuntu.com xenial-security/main Sources
Hit http://security.ubuntu.com xenial-security/restricted Sources
Hit http://security.ubuntu.com xenial-security/universe Sources
Hit http://security.ubuntu.com xenial-security/multiverse Sources
Hit http://ppa.launchpad.net xenial/main amd64 Packages
Hit http://security.ubuntu.com xenial-security/main amd64 Packages
Hit http://security.ubuntu.com xenial-security/restricted amd64 Packages
Hit http://security.ubuntu.com xenial-security/universe amd64 Packages
Hit http://ppa.launchpad.net xenial/main Translation-en
Hit http://security.ubuntu.com xenial-security/multiverse amd64 Packages
Hit http://security.ubuntu.com xenial-security/main Translation-en
Hit http://security.ubuntu.com xenial-security/multiverse Translation-en
Hit http://security.ubuntu.com xenial-security/restricted Translation-en
Hit http://security.ubuntu.com xenial-security/universe Translation-en
Get:2 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/main Sources [1,120 kB]
Get:3 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/restricted Sources [7,228 B]
Get:4 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/universe Sources [7,529 kB]
Get:5 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/multiverse Sources [177 kB]
Get:6 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/main amd64 Packages [1,450 kB]
Get:7 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/restricted amd64 Packages [15.8 kB]
Get:8 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/universe amd64 Packages [7,065 kB]
Get:9 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/multiverse amd64 Packages [139 kB]
Get:10 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/main Translation-en [845 kB]
Get:11 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/multiverse Translation-en [108 kB]
Get:12 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/restricted Translation-en [4,302 B]
Get:13 http://prodstack-zone-1.clouds.archive.ubuntu.com xenial/universe Translation-en [4,745 kB]
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/main Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/restricted Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/universe Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/multiverse Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/main amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/restricted amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com xenial-updates/universe amd64 Packag...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/rpc/dhcp.py'
2--- src/provisioningserver/rpc/dhcp.py 2015-12-04 21:57:28 +0000
3+++ src/provisioningserver/rpc/dhcp.py 2015-12-09 21:01:33 +0000
4@@ -138,9 +138,18 @@
5 return False
6
7
8-def _ensure_dhcpv4_is_accessible(exception):
9- """Ensure that the DHCPv4 server is accessible. Raise `exception` if
10- it will not be possible to contact the server."""
11+def _is_dhcpv4_managed_and_active(exception):
12+ """Ensure that the DHCPv4 server is accessible (if necessary), and return
13+ its status.
14+
15+ Returns True if the DHCPv4 server is accessible and should be accessible.
16+ Returns False if the DHCPv4 server is not accessible, and should not be
17+ accessible.
18+ Raise `exception` if the DHCP server should be accessible, but cannot
19+ be started.
20+
21+ :return:bool
22+ """
23 service = ServiceRegistry.get_item("dhcp4")
24 if service.is_on():
25 if service_monitor.get_service_state("dhcp4") != SERVICE_STATE.ON:
26@@ -150,6 +159,8 @@
27 raise exception(
28 "DHCPv4 server started but was unable to connect "
29 "to omshell.")
30+ else:
31+ return True
32 except ServiceActionError as e:
33 # Error is already logged by the service monitor, nothing to
34 # log for this exception.
35@@ -160,9 +171,11 @@
36 raise exception(error_msg)
37 else:
38 # Service should be on and is already on, nothing needs to be done.
39- pass
40+ return True
41 else:
42- raise exception("DHCPv4 server is disabled.")
43+ # This is not an error; it just needs to be distinguished here so it
44+ # can be handled differently.
45+ return False
46
47
48 @synchronous
49@@ -173,7 +186,12 @@
50 ``mac_address`` keys.
51 :param shared_key: The key used to access the DHCP server via OMAPI.
52 """
53- _ensure_dhcpv4_is_accessible(CannotCreateHostMap)
54+ if not _is_dhcpv4_managed_and_active(CannotCreateHostMap):
55+ # This will raise if DHCP is offline, but should be online.
56+ # If the server is offline *and* should be offline, we'll get False
57+ # back, which means this is a no-op.
58+ return
59+
60 # See bug 1039362 regarding server_address.
61 omshell = Omshell(server_address='127.0.0.1', shared_key=shared_key)
62 for mapping in mappings:
63@@ -207,7 +225,12 @@
64 :param mac_addresses: A list of MAC addresses.
65 :param shared_key: The key used to access the DHCP server via OMAPI.
66 """
67- _ensure_dhcpv4_is_accessible(CannotRemoveHostMap)
68+ if not _is_dhcpv4_managed_and_active(CannotRemoveHostMap):
69+ # This will raise if DHCP is offline, but should be online.
70+ # If the server is offline *and* should be offline, we'll get False
71+ # back, which means this is a no-op.
72+ return
73+
74 # See bug 1039362 regarding server_address.
75 omshell = Omshell(server_address='127.0.0.1', shared_key=shared_key)
76 for identifier in identifiers:
77
78=== modified file 'src/provisioningserver/rpc/tests/test_dhcp.py'
79--- src/provisioningserver/rpc/tests/test_dhcp.py 2015-12-01 18:12:59 +0000
80+++ src/provisioningserver/rpc/tests/test_dhcp.py 2015-12-09 21:01:33 +0000
81@@ -39,6 +39,7 @@
82 from provisioningserver.utils.shell import ExternalProcessError
83 from provisioningserver.utils.testing import RegistryFixture
84 from testtools import ExpectedException
85+from testtools.matchers import Equals
86
87
88 class TestConfigureDHCP(MAASTestCase):
89@@ -238,14 +239,14 @@
90 ServiceRegistry.register_item(service.name, service)
91 return service
92
93- def test__raises_exception_if_service_should_be_off(self):
94+ def test__returns_false_if_service_should_be_off(self):
95 service = self.make_dhcpv4_service()
96 service.off()
97 exception_type = factory.make_exception_type()
98- with ExpectedException(exception_type):
99- dhcp._ensure_dhcpv4_is_accessible(exception_type)
100+ return_value = dhcp._is_dhcpv4_managed_and_active(exception_type)
101+ self.assertThat(return_value, Equals(False))
102
103- def test__does_nothing_if_service_already_on(self):
104+ def test__returns_true_if_service_already_on(self):
105 service = self.make_dhcpv4_service()
106 service.on()
107 mock_get_state = self.patch(
108@@ -253,8 +254,10 @@
109 mock_get_state.return_value = SERVICE_STATE.ON
110 mock_ensure_service = self.patch(
111 dhcp.service_monitor, "ensure_service")
112- dhcp._ensure_dhcpv4_is_accessible(factory.make_exception_type())
113+ return_value = dhcp._is_dhcpv4_managed_and_active(
114+ factory.make_exception_type())
115 self.assertThat(mock_ensure_service, MockNotCalled())
116+ self.assertThat(return_value, Equals(True))
117
118 def test__calls_try_connection_to_check_omshell(self):
119 service = self.make_dhcpv4_service()
120@@ -267,7 +270,7 @@
121 mock_omshell = self.patch_autospec(dhcp, "Omshell")
122 mock_try_connection = mock_omshell.return_value.try_connection
123 mock_try_connection.return_value = True
124- dhcp._ensure_dhcpv4_is_accessible(factory.make_exception_type())
125+ dhcp._is_dhcpv4_managed_and_active(factory.make_exception_type())
126 self.assertThat(mock_ensure_service, MockCalledOnceWith("dhcp4"))
127 self.assertThat(mock_try_connection, MockCalledOnceWith())
128
129@@ -285,7 +288,7 @@
130 mock_try_connection.return_value = False
131 fake_exception_type = factory.make_exception_type()
132 with ExpectedException(fake_exception_type):
133- dhcp._ensure_dhcpv4_is_accessible(fake_exception_type)
134+ dhcp._is_dhcpv4_managed_and_active(fake_exception_type)
135 self.assertThat(mock_ensure_service, MockCalledOnceWith("dhcp4"))
136 self.assertEqual(mock_try_connection.call_count, 3)
137
138@@ -300,7 +303,7 @@
139 mock_ensure_service.side_effect = ServiceActionError()
140 exception_type = factory.make_exception_type()
141 with ExpectedException(exception_type):
142- dhcp._ensure_dhcpv4_is_accessible(exception_type)
143+ dhcp._is_dhcpv4_managed_and_active(exception_type)
144
145 def test__raises_exception_on_other_exceptions(self):
146 service = self.make_dhcpv4_service()
147@@ -313,22 +316,22 @@
148 mock_ensure_service.side_effect = factory.make_exception()
149 exception_type = factory.make_exception_type()
150 with ExpectedException(exception_type):
151- dhcp._ensure_dhcpv4_is_accessible(exception_type)
152+ dhcp._is_dhcpv4_managed_and_active(exception_type)
153
154
155 class TestCreateHostMaps(MAASTestCase):
156
157 def setUp(self):
158 super(TestCreateHostMaps, self).setUp()
159- # Patch _ensure_dhcpv4_is_accessible.
160- self._ensure_dhcpv4_is_accessible = self.patch_autospec(
161- dhcp, "_ensure_dhcpv4_is_accessible")
162+ # Patch _is_dhcpv4_managed_and_active.
163+ self._is_dhcpv4_managed_and_active = self.patch_autospec(
164+ dhcp, "_is_dhcpv4_managed_and_active")
165
166- def test_calls__ensure_dhcpv4_is_accessible(self):
167+ def test_calls__is_dhcpv4_managed_and_active(self):
168 self.patch(dhcp, "Omshell")
169 dhcp.create_host_maps([], sentinel.shared_key)
170 self.assertThat(
171- self._ensure_dhcpv4_is_accessible,
172+ self._is_dhcpv4_managed_and_active,
173 MockCalledOnceWith(CannotCreateHostMap))
174
175 def test_creates_omshell(self):
176@@ -381,15 +384,15 @@
177 super(TestRemoveHostMaps, self).setUp()
178 self.patch(Omshell, "remove")
179 self.patch(Omshell, "nullify_lease")
180- # Patch _ensure_dhcpv4_is_accessible.
181- self._ensure_dhcpv4_is_accessible = self.patch_autospec(
182- dhcp, "_ensure_dhcpv4_is_accessible")
183+ # Patch _is_dhcpv4_managed_and_active.
184+ self._is_dhcpv4_managed_and_active = self.patch_autospec(
185+ dhcp, "_is_dhcpv4_managed_and_active")
186
187- def test_calls__ensure_dhcpv4_is_accessible(self):
188+ def test_calls__is_dhcpv4_managed_and_active(self):
189 self.patch(dhcp, "Omshell")
190 dhcp.remove_host_maps([], sentinel.shared_key)
191 self.assertThat(
192- self._ensure_dhcpv4_is_accessible,
193+ self._is_dhcpv4_managed_and_active,
194 MockCalledOnceWith(CannotRemoveHostMap))
195
196 def test_removes_omshell(self):
197@@ -438,8 +441,8 @@
198 def setUp(self):
199 super(TestOmshellError, self).setUp()
200 # Patch _ensure_dhcpv4_is_accessible.
201- self._ensure_dhcpv4_is_accessible = self.patch_autospec(
202- dhcp, "_ensure_dhcpv4_is_accessible")
203+ self._is_dhcpv4_managed_and_active = self.patch_autospec(
204+ dhcp, "_is_dhcpv4_managed_and_active")
205 self.patch(ExternalProcessError, '__str__', lambda x: 'Error')
206
207 def raise_ExternalProcessError(*args, **kwargs):