Merge lp:~julian-edwards/maas/boot_image_messages into lp:~maas-committers/maas/trunk

Proposed by Julian Edwards
Status: Merged
Approved by: Julian Edwards
Approved revision: no longer in the source branch.
Merged at revision: 1307
Proposed branch: lp:~julian-edwards/maas/boot_image_messages
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 110 lines (+50/-7)
3 files modified
src/maasserver/api.py (+16/-6)
src/maasserver/components.py (+3/-1)
src/maasserver/tests/test_api.py (+31/-0)
To merge this branch: bzr merge lp:~julian-edwards/maas/boot_image_messages
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+131409@code.launchpad.net

Commit message

Fix the persistent errors for missing boot images so that a message appears if any of the nodegroups are missing images.

To post a comment you must log in.
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

As discussed IRL, don't assume that the UI lives at “/” in the http tree!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api.py'
2--- src/maasserver/api.py 2012-10-25 11:09:54 +0000
3+++ src/maasserver/api.py 2012-10-25 14:35:23 +0000
4@@ -162,7 +162,10 @@
5 compose_preseed_url,
6 )
7 from maasserver.server_address import get_maas_facing_server_address
8-from maasserver.utils import map_enum
9+from maasserver.utils import (
10+ absolute_reverse,
11+ map_enum,
12+ )
13 from maasserver.utils.orm import get_one
14 from piston.handler import (
15 AnonymousBaseHandler,
16@@ -1884,14 +1887,21 @@
17 release=image['release'],
18 purpose=image['purpose'])
19
20- if len(images) == 0:
21+ # Work out if any nodegroups are missing images.
22+ nodegroup_ids_with_images = BootImage.objects.values_list(
23+ "nodegroup_id", flat=True)
24+ nodegroups_missing_images = NodeGroup.objects.exclude(
25+ id__in=nodegroup_ids_with_images).filter(
26+ status=NODEGROUP_STATUS.ACCEPTED)
27+ if nodegroups_missing_images.exists():
28 warning = dedent("""\
29- No boot images have been imported yet. Either the
30+ Some cluster controllers are missing boot images. Either the
31 maas-import-pxe-files script has not run yet, or it failed.
32
33- Try running it manually. If it succeeds, this message will
34- go away within 5 minutes.
35- """)
36+ Try running it manually on the affected
37+ <a href="%s#accepted-clusters">cluster controllers.</a>
38+ If it succeeds, this message will go away within 5 minutes.
39+ """ % absolute_reverse("settings"))
40 register_persistent_error(COMPONENT.IMPORT_PXE_FILES, warning)
41 else:
42 discard_persistent_error(COMPONENT.IMPORT_PXE_FILES)
43
44=== modified file 'src/maasserver/components.py'
45--- src/maasserver/components.py 2012-09-28 18:42:16 +0000
46+++ src/maasserver/components.py 2012-10-25 14:35:23 +0000
47@@ -17,6 +17,7 @@
48 "register_persistent_error",
49 ]
50
51+from django.utils.safestring import mark_safe
52 from maasserver.models import ComponentError
53 from maasserver.utils.orm import get_one
54
55@@ -50,4 +51,5 @@
56
57 def get_persistent_errors():
58 """Return list of current persistent error messages."""
59- return sorted(err.error for err in ComponentError.objects.all())
60+ return sorted(
61+ mark_safe(err.error) for err in ComponentError.objects.all())
62
63=== modified file 'src/maasserver/tests/test_api.py'
64--- src/maasserver/tests/test_api.py 2012-10-25 11:09:54 +0000
65+++ src/maasserver/tests/test_api.py 2012-10-25 14:35:23 +0000
66@@ -4124,6 +4124,7 @@
67
68 def test_report_boot_images_warns_if_no_images_found(self):
69 nodegroup = NodeGroup.objects.ensure_master()
70+ factory.make_node_group() # Second nodegroup with no images.
71 recorder = self.patch(api, 'register_persistent_error')
72 client = make_worker_client(nodegroup)
73 response = self.report_images(nodegroup, [], client=client)
74@@ -4134,6 +4135,36 @@
75 self.assertIn(
76 COMPONENT.IMPORT_PXE_FILES,
77 [args[0][0] for args in recorder.call_args_list])
78+ # Check that the persistent error message contains a link to the
79+ # clusters listing.
80+ self.assertIn(
81+ "/settings/#accepted-clusters", recorder.call_args_list[0][0][1])
82+
83+ def test_report_boot_images_warns_if_any_nodegroup_has_no_images(self):
84+ nodegroup = NodeGroup.objects.ensure_master()
85+ # Second nodegroup with no images.
86+ factory.make_node_group(status=NODEGROUP_STATUS.ACCEPTED)
87+ recorder = self.patch(api, 'register_persistent_error')
88+ client = make_worker_client(nodegroup)
89+ image = make_boot_image_params()
90+ response = self.report_images(nodegroup, [image], client=client)
91+ self.assertEqual(
92+ (httplib.OK, "OK"),
93+ (response.status_code, response.content))
94+
95+ self.assertIn(
96+ COMPONENT.IMPORT_PXE_FILES,
97+ [args[0][0] for args in recorder.call_args_list])
98+
99+ def test_report_boot_images_ignores_non_accepted_groups(self):
100+ nodegroup = factory.make_node_group(status=NODEGROUP_STATUS.ACCEPTED)
101+ factory.make_node_group(status=NODEGROUP_STATUS.PENDING)
102+ factory.make_node_group(status=NODEGROUP_STATUS.REJECTED)
103+ recorder = self.patch(api, 'register_persistent_error')
104+ client = make_worker_client(nodegroup)
105+ image = make_boot_image_params()
106+ response = self.report_images(nodegroup, [image], client=client)
107+ self.assertEqual(0, recorder.call_count)
108
109 def test_report_boot_images_removes_warning_if_images_found(self):
110 self.patch(api, 'register_persistent_error')