Merge lp:~blake-rouse/maas/no-power-action-when-off into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 3922
Proposed branch: lp:~blake-rouse/maas/no-power-action-when-off
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 130 lines (+37/-14)
3 files modified
src/maasserver/models/node.py (+13/-7)
src/maasserver/models/tests/test_node.py (+19/-4)
src/maasserver/tests/test_node_action.py (+5/-3)
To merge this branch: bzr merge lp:~blake-rouse/maas/no-power-action-when-off
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
Review via email: mp+259842@code.launchpad.net

Commit message

Stops performing the stop power action during the release action when the node is already off.

This stops a power action from being registered in the power registry when the node is already off and is transitioned directly to ready. Branch also includes a drive-by fix for a test that can random fail from a recent change that was made.

To post a comment you must log in.
Revision history for this message
Andres Rodriguez (andreserl) wrote :

lgtm!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/node.py'
2--- src/maasserver/models/node.py 2015-05-13 19:20:54 +0000
3+++ src/maasserver/models/node.py 2015-05-21 19:35:09 +0000
4@@ -1578,13 +1578,19 @@
5 """Mark allocated or reserved node as available again and power off.
6 """
7 maaslog.info("%s: Releasing node", self.hostname)
8- try:
9- self.stop(self.owner)
10- except Exception as ex:
11- maaslog.error(
12- "%s: Unable to shut node down: %s", self.hostname,
13- unicode(ex))
14- raise
15+
16+ # Don't perform stop the node if its already off. Doing so will
17+ # place an action in the power registry which is not needed and can
18+ # block a following deploy action. See bug 1453954 for an example of
19+ # the issue this will cause.
20+ if self.power_state != POWER_STATE.OFF:
21+ try:
22+ self.stop(self.owner)
23+ except Exception as ex:
24+ maaslog.error(
25+ "%s: Unable to shut node down: %s", self.hostname,
26+ unicode(ex))
27+ raise
28
29 deallocate_ip_address = True
30 if self.power_state == POWER_STATE.OFF:
31
32=== modified file 'src/maasserver/models/tests/test_node.py'
33--- src/maasserver/models/tests/test_node.py 2015-05-16 06:21:20 +0000
34+++ src/maasserver/models/tests/test_node.py 2015-05-21 19:35:09 +0000
35@@ -939,9 +939,11 @@
36 owner = factory.make_User()
37 node = factory.make_Node(
38 status=NODE_STATUS.ALLOCATED, owner=owner, agent_name=agent_name)
39+ self.patch(node, 'stop')
40 self.patch(node, 'start_transition_monitor')
41 node.power_state = POWER_STATE.OFF
42 node.release()
43+ self.expectThat(node.stop, MockNotCalled())
44 self.expectThat(node.start_transition_monitor, MockNotCalled())
45 self.expectThat(node.status, Equals(NODE_STATUS.READY))
46 self.expectThat(node.owner, Is(None))
47@@ -1180,16 +1182,27 @@
48 self.assertEqual("", node.osystem)
49 self.assertEqual("", node.distro_series)
50
51- def test_release_powers_off_node(self):
52+ def test_release_powers_off_node_when_on(self):
53 user = factory.make_User()
54 node = factory.make_Node(
55- status=NODE_STATUS.ALLOCATED, owner=user, power_type='virsh')
56+ status=NODE_STATUS.ALLOCATED, owner=user, power_type='virsh',
57+ power_state=POWER_STATE.ON)
58 self.patch(node, 'start_transition_monitor')
59 node_stop = self.patch(node, 'stop')
60 node.release()
61 self.assertThat(
62 node_stop, MockCalledOnceWith(user))
63
64+ def test_release_doesnt_power_off_node_when_off(self):
65+ user = factory.make_User()
66+ node = factory.make_Node(
67+ status=NODE_STATUS.ALLOCATED, owner=user, power_type='virsh',
68+ power_state=POWER_STATE.OFF)
69+ self.patch(node, 'start_transition_monitor')
70+ node_stop = self.patch(node, 'stop')
71+ node.release()
72+ self.assertThat(node_stop, MockNotCalled())
73+
74 def test_release_deallocates_static_ip_when_node_is_off(self):
75 user = factory.make_User()
76 node = factory.make_Node_with_MACAddress_and_NodeGroupInterface(
77@@ -1255,7 +1268,8 @@
78 self.assertThat(dns_update_zones, MockCalledOnceWith([node.nodegroup]))
79
80 def test_release_logs_and_raises_errors_in_stopping(self):
81- node = factory.make_Node(status=NODE_STATUS.DEPLOYED)
82+ node = factory.make_Node(
83+ status=NODE_STATUS.DEPLOYED, power_state=POWER_STATE.ON)
84 maaslog = self.patch(node_module, 'maaslog')
85 exception_class = factory.make_exception_type()
86 exception = exception_class(factory.make_name())
87@@ -1272,6 +1286,7 @@
88 # will leave the node in its previous state (i.e. DEPLOYED).
89 node = factory.make_Node(
90 status=NODE_STATUS.DEPLOYED, power_type="virsh",
91+ power_state=POWER_STATE.ON,
92 owner=factory.make_User())
93 node_stop = self.patch(node, 'stop')
94 node_stop.side_effect = factory.make_exception()
95@@ -1671,7 +1686,7 @@
96 self.assertEqual(expected_hostname, node.fqdn)
97
98 def test_boot_type_has_fastpath_set_by_default(self):
99- node = factory.make_Node()
100+ node = Node()
101 self.assertEqual(NODE_BOOT.FASTPATH, node.boot_type)
102
103 def test_split_arch_returns_arch_as_tuple(self):
104
105=== modified file 'src/maasserver/tests/test_node_action.py'
106--- src/maasserver/tests/test_node_action.py 2015-05-11 09:51:30 +0000
107+++ src/maasserver/tests/test_node_action.py 2015-05-21 19:35:09 +0000
108@@ -733,9 +733,10 @@
109 self.patch_autospec(node, 'start_transition_monitor')
110 self.patch_autospec(node, 'stop_transition_monitor')
111
112- def make_action(self, action_class, node_status):
113+ def make_action(self, action_class, node_status, power_state=None):
114 node = factory.make_Node(
115- mac=True, status=node_status, power_type='ether_wake')
116+ mac=True, status=node_status, power_type='ether_wake',
117+ power_state=power_state)
118 admin = factory.make_admin()
119 return action_class(node, admin)
120
121@@ -781,7 +782,8 @@
122 unicode(exception))
123
124 def test_Release_handles_rpc_errors(self):
125- action = self.make_action(Release, NODE_STATUS.ALLOCATED)
126+ action = self.make_action(
127+ Release, NODE_STATUS.ALLOCATED, power_state=POWER_STATE.ON)
128 self.patch_rpc_methods(action.node)
129 exception = self.assertRaises(NodeActionError, action.execute)
130 self.assertEqual(