Merge lp:~rvb/maas/fpi-button into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 1685
Proposed branch: lp:~rvb/maas/fpi-button
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 203 lines (+100/-9)
5 files modified
src/maasserver/node_action.py (+39/-0)
src/maasserver/tests/test_forms.py (+3/-1)
src/maasserver/tests/test_node_action.py (+50/-0)
src/maasserver/tests/test_views_nodes.py (+4/-4)
src/maasserver/views/nodes.py (+4/-4)
To merge this branch: bzr merge lp:~rvb/maas/fpi-button
Reviewer Review Type Date Requested Status
Julian Edwards (community) Approve
Review via email: mp+190049@code.launchpad.net

Commit message

Add buttons to enable/disable curtin.

Description of the change

Since I extended the meaning of is_permitted(), I changed the error messages a bit. A better fix would have been to extend the logic of the action classes to include a is_enabled() or something but this would require much more work; besides, I think the logic we have in place is complicated enough already.

Please carefully review the wordings on the buttons. I'm happy with any suggestion but keep in mind that the "display" and "display_bulk" fields have to be small to fit in our design!

To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/node_action.py'
2--- src/maasserver/node_action.py 2013-10-07 09:12:40 +0000
3+++ src/maasserver/node_action.py 2013-10-09 09:08:56 +0000
4@@ -44,6 +44,7 @@
5 Node,
6 SSHKey,
7 )
8+from maasserver.utils import map_enum
9
10 # All node statuses.
11 ALL_STATUSES = set(NODE_STATUS_CHOICES_DICT.keys())
12@@ -180,6 +181,42 @@
13 return "Node commissioning started."
14
15
16+class UseCurtin(NodeAction):
17+ """Set this node to use curtin for installation."""
18+ name = "usecurtin"
19+ display = "Use the fast installer"
20+ display_bulk = "Mark the selected nodes as using the fast installer"
21+ actionable_statuses = map_enum(NODE_STATUS).values()
22+ permission = NODE_PERMISSION.EDIT
23+
24+ def is_permitted(self):
25+ permitted = super(UseCurtin, self).is_permitted()
26+ return permitted and self.node.should_use_traditional_installer()
27+
28+ def execute(self, allow_redirect=True):
29+ """See `NodeAction.execute`."""
30+ self.node.use_fastpath_installer()
31+ return "Node marked as using curtin for install."
32+
33+
34+class UseDI(NodeAction):
35+ """Set this node to use d-i for installation."""
36+ name = "usedi"
37+ display = "Use the default installer"
38+ display_bulk = "Mark the selected nodes as using the default installer"
39+ actionable_statuses = map_enum(NODE_STATUS).values()
40+ permission = NODE_PERMISSION.EDIT
41+
42+ def is_permitted(self):
43+ permitted = super(UseDI, self).is_permitted()
44+ return permitted and self.node.should_use_fastpath_installer()
45+
46+ def execute(self, allow_redirect=True):
47+ """See `NodeAction.execute`."""
48+ self.node.use_traditional_installer()
49+ return "Node marked as using the default installer."
50+
51+
52 class StartNode(NodeAction):
53 """Acquire and start a node."""
54 name = "start"
55@@ -236,6 +273,8 @@
56 Commission,
57 StartNode,
58 StopNode,
59+ UseCurtin,
60+ UseDI,
61 )
62
63
64
65=== modified file 'src/maasserver/tests/test_forms.py'
66--- src/maasserver/tests/test_forms.py 2013-10-08 07:58:09 +0000
67+++ src/maasserver/tests/test_forms.py 2013-10-09 09:08:56 +0000
68@@ -69,6 +69,7 @@
69 Delete,
70 StartNode,
71 StopNode,
72+ UseCurtin,
73 )
74 from maasserver.testing import reload_object
75 from maasserver.testing.factory import factory
76@@ -474,10 +475,11 @@
77 def test_get_action_form_for_admin(self):
78 admin = factory.make_admin()
79 node = factory.make_node(status=NODE_STATUS.DECLARED)
80+ node.use_traditional_installer()
81 form = get_action_form(admin)(node)
82
83 self.assertItemsEqual(
84- [Commission.name, Delete.name],
85+ [Commission.name, Delete.name, UseCurtin.name],
86 form.actions)
87
88 def test_get_action_form_for_user(self):
89
90=== modified file 'src/maasserver/tests/test_node_action.py'
91--- src/maasserver/tests/test_node_action.py 2013-10-07 09:12:40 +0000
92+++ src/maasserver/tests/test_node_action.py 2013-10-09 09:08:56 +0000
93@@ -30,6 +30,8 @@
94 NodeAction,
95 StartNode,
96 StopNode,
97+ UseCurtin,
98+ UseDI,
99 )
100 from maasserver.testing.factory import factory
101 from maasserver.testing.testcase import MAASServerTestCase
102@@ -261,3 +263,51 @@
103 self.assertEqual(
104 'provisioningserver.tasks.power_off',
105 self.celery.tasks[0]['task'].name)
106+
107+
108+class TestUseCurtinNodeAction(MAASServerTestCase):
109+
110+ def test_sets_tag(self):
111+ user = factory.make_user()
112+ node = factory.make_node(owner=user)
113+ node.use_traditional_installer()
114+ action = UseCurtin(node, user)
115+ self.assertTrue(action.is_permitted())
116+ action.execute()
117+ self.assertTrue(node.should_use_fastpath_installer())
118+
119+ def test_requires_edit_permission(self):
120+ user = factory.make_user()
121+ node = factory.make_node()
122+ node.use_traditional_installer()
123+ self.assertFalse(UseCurtin(node, user).is_permitted())
124+
125+ def test_not_permitted_if_already_uses_curtin(self):
126+ node = factory.make_node()
127+ node.use_fastpath_installer()
128+ user = factory.make_admin()
129+ self.assertFalse(UseCurtin(node, user).is_permitted())
130+
131+
132+class TestUseDINodeAction(MAASServerTestCase):
133+
134+ def test_sets_tag(self):
135+ user = factory.make_user()
136+ node = factory.make_node(owner=user)
137+ node.use_fastpath_installer()
138+ action = UseDI(node, user)
139+ self.assertTrue(action.is_permitted())
140+ action.execute()
141+ self.assertTrue(node.should_use_traditional_installer())
142+
143+ def test_requires_edit_permission(self):
144+ user = factory.make_user()
145+ node = factory.make_node()
146+ node.use_fastpath_installer()
147+ self.assertFalse(UseDI(node, user).is_permitted())
148+
149+ def test_not_permitted_if_already_uses_di(self):
150+ node = factory.make_node()
151+ node.use_traditional_installer()
152+ user = factory.make_admin()
153+ self.assertFalse(UseDI(node, user).is_permitted())
154
155=== modified file 'src/maasserver/tests/test_views_nodes.py'
156--- src/maasserver/tests/test_views_nodes.py 2013-10-07 09:12:40 +0000
157+++ src/maasserver/tests/test_views_nodes.py 2013-10-09 09:08:56 +0000
158@@ -915,7 +915,7 @@
159 (Delete, 0, 1, 1),
160 (
161 'could not be performed on 1 node because its state',
162- "could not be performed on 1 node because you don't",
163+ "could not be performed on 1 node because that action",
164 )
165 ),
166 (
167@@ -930,14 +930,14 @@
168 % Delete.display_bulk,
169 'It could not be performed on 4 nodes because their '
170 'state does not allow that action.',
171- "It could not be performed on 2 nodes because you "
172- "don't have the required permissions.",
173+ "It could not be performed on 2 nodes because that "
174+ "action is not permitted on these nodes.",
175 ),
176 ),
177 (
178 (Delete, 0, 0, 3),
179 ('The action "%s" could not be performed on 3 nodes '
180- "because you don't have the required permissions."
181+ "because that action is not permitted on these nodes."
182 % Delete.display_bulk,),
183 ),
184 ]
185
186=== modified file 'src/maasserver/views/nodes.py'
187--- src/maasserver/views/nodes.py 2013-10-07 09:12:40 +0000
188+++ src/maasserver/views/nodes.py 2013-10-09 09:08:56 +0000
189@@ -131,10 +131,10 @@
190 'state does not allow that action.'),
191 ]
192 not_permitted_templates = [
193- ('%s could not be performed on %d node because you '
194- "don't have the required permissions."),
195- ('%s could not be performed on %d nodes because you '
196- "don't have the required permissions."),
197+ ('%s could not be performed on %d node because that '
198+ "action is not permitted on that node."),
199+ ('%s could not be performed on %d nodes because that '
200+ "action is not permitted on these nodes."),
201 ]
202 number_message = [
203 (done, done_templates),