Merge lp:~newell-jensen/maas/fix-1667754 into lp:~maas-committers/maas/trunk

Proposed by Newell Jensen
Status: Merged
Approved by: Newell Jensen
Approved revision: no longer in the source branch.
Merged at revision: 5761
Proposed branch: lp:~newell-jensen/maas/fix-1667754
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 141 lines (+76/-19)
2 files modified
src/provisioningserver/drivers/pod/rsd.py (+12/-2)
src/provisioningserver/drivers/pod/tests/test_rsd.py (+64/-17)
To merge this branch: bzr merge lp:~newell-jensen/maas/fix-1667754
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+318426@code.launchpad.net

Commit message

Add work around for 404 error from RSD PODM when trying to decompose a resource that has already been decomposed.

At some point in the future we will need to re-implement how we handle this from the region.

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

Looks good. Just two comments.

review: Approve
Revision history for this message
Newell Jensen (newell-jensen) :
Revision history for this message
Gavin Panella (allenap) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/drivers/pod/rsd.py'
2--- src/provisioningserver/drivers/pod/rsd.py 2017-02-21 21:10:31 +0000
3+++ src/provisioningserver/drivers/pod/rsd.py 2017-02-28 18:25:17 +0000
4@@ -676,8 +676,18 @@
5 headers = self.make_auth_headers(**context)
6 # Delete machine at node_id.
7 endpoint = b"redfish/v1/Nodes/%s" % node_id
8- yield self.redfish_request(
9- b"DELETE", join(url, endpoint), headers)
10+ try:
11+ yield self.redfish_request(
12+ b"DELETE", join(url, endpoint), headers)
13+ except PartialDownloadError as error:
14+ # XXX newell 2017-02-27 bug=1667754:
15+ # Catch the 404 error when trying to decompose the
16+ # resource that has already been decomposed.
17+ # This is a work around and will need to be handled
18+ # differently on the region so we don't try to
19+ # decompose a machine multiple times.
20+ if int(error.status) != HTTPStatus.NOT_FOUND:
21+ raise
22
23 # Retrieve pod resources.
24 discovered_pod = yield self.get_pod_resources(url, headers)
25
26=== modified file 'src/provisioningserver/drivers/pod/tests/test_rsd.py'
27--- src/provisioningserver/drivers/pod/tests/test_rsd.py 2017-02-15 15:49:54 +0000
28+++ src/provisioningserver/drivers/pod/tests/test_rsd.py 2017-02-28 18:25:17 +0000
29@@ -728,8 +728,8 @@
30
31 with ExpectedException(PartialDownloadError):
32 yield driver.redfish_request(b"GET", uri, headers)
33- self.assertThat(mock_readBody, MockCalledOnceWith(
34- "Response"))
35+ self.assertThat(mock_readBody, MockCalledOnceWith(
36+ "Response"))
37
38 @inlineCallbacks
39 def test__list_resources(self):
40@@ -1284,6 +1284,53 @@
41 discovered_pod))
42
43 @inlineCallbacks
44+ def test_decompose_continues_on_404_error(self):
45+ driver = RSDPodDriver()
46+ context = make_context()
47+ url = driver.get_url(context)
48+ node_id = context.get('node_id').encode('utf-8')
49+ headers = driver.make_auth_headers(**context)
50+ endpoint = b"redfish/v1/Nodes/%s" % node_id
51+ mock_redfish_request = self.patch(driver, 'redfish_request')
52+ error = PartialDownloadError(
53+ response=json.dumps(SAMPLE_JSON_SYSTEMS).encode('utf-8'),
54+ code=HTTPStatus.NOT_FOUND)
55+ mock_redfish_request.side_effect = error
56+ mock_get_pod_resources = self.patch(driver, 'get_pod_resources')
57+ discovered_pod = make_discovered_pod()
58+ mock_get_pod_resources.return_value = discovered_pod
59+ mock_get_pod_hints = self.patch(driver, 'get_pod_hints')
60+
61+ yield driver.decompose(
62+ factory.make_name('system_id'), context)
63+ self.assertThat(mock_redfish_request, MockCalledOnceWith(
64+ b"DELETE", join(url, endpoint), headers))
65+ self.assertThat(mock_get_pod_resources, MockCalledOnceWith(
66+ url, headers))
67+ self.assertThat(mock_get_pod_hints, MockCalledOnceWith(
68+ discovered_pod))
69+
70+ @inlineCallbacks
71+ def test_decompose_raises_when_not_404_error(self):
72+ driver = RSDPodDriver()
73+ context = make_context()
74+ url = driver.get_url(context)
75+ node_id = context.get('node_id').encode('utf-8')
76+ headers = driver.make_auth_headers(**context)
77+ endpoint = b"redfish/v1/Nodes/%s" % node_id
78+ mock_redfish_request = self.patch(driver, 'redfish_request')
79+ error = PartialDownloadError(
80+ response=json.dumps(SAMPLE_JSON_SYSTEMS).encode('utf-8'),
81+ code=HTTPStatus.BAD_REQUEST)
82+ mock_redfish_request.side_effect = error
83+
84+ with ExpectedException(PartialDownloadError):
85+ yield driver.decompose(
86+ factory.make_name('system_id'), context)
87+ self.assertThat(mock_redfish_request, MockCalledOnceWith(
88+ b"DELETE", join(url, endpoint), headers))
89+
90+ @inlineCallbacks
91 def test__set_pxe_boot(self):
92 driver = RSDPodDriver()
93 context = make_context()
94@@ -1380,9 +1427,9 @@
95
96 with ExpectedException(PodFatalError):
97 yield driver.assemble_node(url, node_id, headers)
98- self.assertThat(mock_get_composed_node_state, MockCalledOnceWith(
99- url, node_id, headers))
100- self.assertThat(mock_redfish_request, MockNotCalled())
101+ self.assertThat(mock_get_composed_node_state, MockCalledOnceWith(
102+ url, node_id, headers))
103+ self.assertThat(mock_redfish_request, MockNotCalled())
104
105 @inlineCallbacks
106 def test_assemble_node_raises_error_if_assembling_fails(self):
107@@ -1402,12 +1449,12 @@
108
109 with ExpectedException(PodFatalError):
110 yield driver.assemble_node(url, node_id, headers)
111- self.assertThat(mock_get_composed_node_state, MockCallsMatch(
112- call(url, node_id, headers),
113- call(url, node_id, headers),
114- call(url, node_id, headers)))
115- self.assertThat(mock_redfish_request, MockCalledOnceWith(
116- b"POST", uri, headers))
117+ self.assertThat(mock_get_composed_node_state, MockCallsMatch(
118+ call(url, node_id, headers),
119+ call(url, node_id, headers),
120+ call(url, node_id, headers)))
121+ self.assertThat(mock_redfish_request, MockCalledOnceWith(
122+ b"POST", uri, headers))
123
124 @inlineCallbacks
125 def test_power_issues_power_reset(self):
126@@ -1533,9 +1580,9 @@
127
128 with ExpectedException(PodActionError):
129 yield driver.power_query(system_id, context)
130- self.assertThat(
131- mock_assemble_node,
132- MockCalledOnceWith(url, node_id, headers))
133- self.assertThat(
134- mock_get_composed_node_state,
135- MockCalledOnceWith(url, node_id, headers))
136+ self.assertThat(
137+ mock_assemble_node,
138+ MockCalledOnceWith(url, node_id, headers))
139+ self.assertThat(
140+ mock_get_composed_node_state,
141+ MockCalledOnceWith(url, node_id, headers))