Merge lp:~gmb/maas/bug-1274912 into lp:~maas-committers/maas/trunk

Proposed by Graham Binns
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: 1874
Proposed branch: lp:~gmb/maas/bug-1274912
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 86 lines (+30/-5)
2 files modified
src/maasserver/models/node.py (+16/-4)
src/maasserver/models/tests/test_node.py (+14/-1)
To merge this branch: bzr merge lp:~gmb/maas/bug-1274912
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Raphaël Badin (community) Approve
Review via email: mp+204234@code.launchpad.net

Commit message

Trying to stop a node which has no power type configured will no longer result in an unhandled ValueError.

Description of the change

This branch fixes bug 1274912 by correctly handling ValueErrors from get_effective_power_type() in stop_nodes(). If a ValueError is encountered, stop_nodes() will simply skip creating a power event for the node.

To post a comment you must log in.
Revision history for this message
Raphaël Badin (rvb) wrote :

[0]

11 + except ValueError:
12 + continue

It's worth a warning. (Let's also add one in start_nodes please.)

review: Approve
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

As discussed on IRC: let's try not to catch such generic errors coming out of functions that may raise them for other reasons! And if we have to do it in multiple places that call get_effective_power_type(), that suggests that the function could do more to simplify this.

Revision history for this message
MAAS Lander (maas-lander) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
Raphaël Badin (rvb) wrote :

No warning for me I guess :/

Revision history for this message
Graham Binns (gmb) wrote :

On 31 January 2014 14:39, Raphaël Badin <email address hidden> wrote:
> No warning for me I guess :/

Crap, I didn't see your comment, only Jeroen's sorry. E_NOT_LOOKING.
You're right, and I'll add a warning now.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Just one more thing from me: changing the exception type does not break any tests? Looks like that behaviour of get_effective_power_type() is untested! Could you rectify?

With apologies for the anality of it all. :)

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 2014-01-29 10:08:12 +0000
3+++ src/maasserver/models/node.py 2014-01-31 14:22:50 +0000
4@@ -150,6 +150,10 @@
5 }
6
7
8+class UnknownPowerType(Exception):
9+ """Raised when a node has an unknown power type."""
10+
11+
12 class NodeManager(Manager):
13 """A utility to manage the collection of Nodes."""
14
15@@ -297,7 +301,12 @@
16 processed_nodes = []
17 for node in nodes:
18 power_params = node.get_effective_power_parameters()
19- node_power_type = node.get_effective_power_type()
20+ try:
21+ node_power_type = node.get_effective_power_type()
22+ except UnknownPowerType:
23+ # Skip the rest of the loop to avoid creating a power
24+ # event for a node that we can't power down.
25+ continue
26 # WAKE_ON_LAN does not support poweroff.
27 if node_power_type != 'ether_wake':
28 power_off.apply_async(
29@@ -337,7 +346,9 @@
30 power_params = node.get_effective_power_parameters()
31 try:
32 node_power_type = node.get_effective_power_type()
33- except ValueError:
34+ except UnknownPowerType:
35+ # Skip the rest of the loop to avoid creating a power
36+ # event for a node that we can't power up.
37 continue
38 if node_power_type == 'ether_wake':
39 mac = power_params.get('mac_address')
40@@ -686,10 +697,11 @@
41 def get_effective_power_type(self):
42 """Get power-type to use for this node.
43
44- If no power type has been set for the node, raise an error.
45+ If no power type has been set for the node, raise
46+ UnknownPowerType.
47 """
48 if self.power_type == '':
49- raise ValueError("Node power type is unconfigured")
50+ raise UnknownPowerType("Node power type is unconfigured")
51 return self.power_type
52
53 def get_primary_mac(self):
54
55=== modified file 'src/maasserver/models/tests/test_node.py'
56--- src/maasserver/models/tests/test_node.py 2014-01-21 06:27:45 +0000
57+++ src/maasserver/models/tests/test_node.py 2014-01-31 14:22:50 +0000
58@@ -230,7 +230,8 @@
59
60 def test_get_effective_power_type_raises_if_not_set(self):
61 node = factory.make_node(power_type='')
62- self.assertRaises(ValueError, node.get_effective_power_type)
63+ self.assertRaises(
64+ node_module.UnknownPowerType, node.get_effective_power_type)
65
66 def test_get_effective_power_type_reads_node_field(self):
67 power_types = list(get_power_types().keys()) # Python3 proof.
68@@ -1017,6 +1018,18 @@
69 [stoppable_node],
70 Node.objects.stop_nodes(ids, stoppable_node.owner))
71
72+ def test_stop_nodes_does_not_attempt_power_task_if_no_power_type(self):
73+ # If the node has a power_type set to UNKNOWN_POWER_TYPE
74+ # NodeManager.stop_node(this_node) won't create a power event
75+ # for it.
76+ user = factory.make_user()
77+ node, unused = self.make_node_with_mac(
78+ user, power_type='')
79+ output = Node.objects.stop_nodes([node.system_id], user)
80+
81+ self.assertItemsEqual([], output)
82+ self.assertEqual(0, len(self.celery.tasks))
83+
84 def test_start_nodes_starts_nodes(self):
85 user = factory.make_user()
86 node, mac = self.make_node_with_mac(