Merge lp:~blake-rouse/maas/fix-1373272 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: 3078
Proposed branch: lp:~blake-rouse/maas/fix-1373272
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 249 lines (+73/-57)
5 files modified
src/maasserver/components.py (+20/-0)
src/maasserver/models/bootresource.py (+26/-1)
src/maasserver/models/tests/test_bootresource.py (+12/-0)
src/maasserver/start_up.py (+7/-19)
src/maasserver/tests/test_start_up.py (+8/-37)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-1373272
Reviewer Review Type Date Requested Status
Jason Hobbs (community) Approve
Review via email: mp+235808@code.launchpad.net

Commit message

Fix the import boot images message to hide once boot resources exist.

To post a comment you must log in.
Revision history for this message
Jason Hobbs (jason-hobbs) wrote :

Looks fine but I think the warning message should change a bit - comment below.

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Thanks for the review.

I have fixed the requested items.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/components.py'
2--- src/maasserver/components.py 2013-10-07 09:12:40 +0000
3+++ src/maasserver/components.py 2014-09-24 17:54:53 +0000
4@@ -17,9 +17,14 @@
5 "get_persistent_error",
6 "get_persistent_errors",
7 "register_persistent_error",
8+ "show_missing_boot_image_error",
9+ "hide_missing_boot_image_error",
10 ]
11
12+from textwrap import dedent
13+
14 from django.utils.safestring import mark_safe
15+from maasserver.enum import COMPONENT
16 from maasserver.models import ComponentError
17 from maasserver.utils.orm import get_one
18
19@@ -55,3 +60,18 @@
20 """Return list of current persistent error messages."""
21 return sorted(
22 mark_safe(err.error) for err in ComponentError.objects.all())
23+
24+
25+def show_missing_boot_image_error():
26+ """Show missing boot images error on the UI."""
27+ warning = dedent("""\
28+ Boot image import process not started. Nodes will not be able to
29+ provision without boot images. Start the boot images import process to
30+ resolve this issue.
31+ """)
32+ register_persistent_error(COMPONENT.IMPORT_PXE_FILES, warning)
33+
34+
35+def hide_missing_boot_image_error():
36+ """Hide missing boot images error on the UI."""
37+ discard_persistent_error(COMPONENT.IMPORT_PXE_FILES)
38
39=== modified file 'src/maasserver/models/bootresource.py'
40--- src/maasserver/models/bootresource.py 2014-09-17 13:17:42 +0000
41+++ src/maasserver/models/bootresource.py 2014-09-24 17:54:53 +0000
42@@ -22,6 +22,10 @@
43 IntegerField,
44 Manager,
45 )
46+from django.db.models.signals import (
47+ post_delete,
48+ post_save,
49+ )
50 from maasserver import DefaultMeta
51 from maasserver.enum import (
52 BOOT_RESOURCE_TYPE,
53@@ -117,7 +121,9 @@
54 arches = set()
55 for resource in self.all():
56 resource_set = resource.get_latest_set()
57- if resource_set.commissionable and resource_set.installable:
58+ if (resource_set is not None and
59+ resource_set.commissionable and
60+ resource_set.installable):
61 arches.add(resource.architecture)
62 if 'subarches' in resource.extra:
63 arch, _ = resource.split_arch()
64@@ -305,3 +311,22 @@
65 return False
66 subarches = self.extra['subarches'].split(',')
67 return subarch in subarches
68+
69+
70+def update_boot_image_error(sender, instance, **kwargs):
71+ """Show or hide missing boot image error on the UI, depending on if any
72+ boot resources exist.
73+ """
74+ # Avoid circular import
75+ from maasserver.components import (
76+ hide_missing_boot_image_error,
77+ show_missing_boot_image_error,
78+ )
79+ if BootResource.objects.all().exists():
80+ hide_missing_boot_image_error()
81+ else:
82+ show_missing_boot_image_error()
83+
84+
85+post_delete.connect(update_boot_image_error, BootResource)
86+post_save.connect(update_boot_image_error, BootResource)
87
88=== modified file 'src/maasserver/models/tests/test_bootresource.py'
89--- src/maasserver/models/tests/test_bootresource.py 2014-09-17 13:18:15 +0000
90+++ src/maasserver/models/tests/test_bootresource.py 2014-09-24 17:54:53 +0000
91@@ -23,12 +23,14 @@
92 BOOT_RESOURCE_FILE_TYPE,
93 BOOT_RESOURCE_TYPE,
94 BOOT_RESOURCE_TYPE_CHOICES_DICT,
95+ COMPONENT,
96 )
97 from maasserver.models import bootresource
98 from maasserver.models.bootresource import (
99 BootResource,
100 RTYPE_REQUIRING_OS_SERIES_NAME,
101 )
102+from maasserver.models.component_error import ComponentError
103 from maasserver.testing.factory import factory
104 from maasserver.testing.testcase import MAASServerTestCase
105
106@@ -430,3 +432,13 @@
107 extra={'subarches': ','.join(subarches)})
108 self.assertFalse(
109 resource.supports_subarch(factory.make_name('subarch')))
110+
111+ def test_shows_and_hides_missing_boot_image_error(self):
112+ resource = factory.make_BootResource()
113+ self.assertFalse(
114+ ComponentError.objects.filter(
115+ component=COMPONENT.IMPORT_PXE_FILES).exists())
116+ resource.delete()
117+ self.assertTrue(
118+ ComponentError.objects.filter(
119+ component=COMPONENT.IMPORT_PXE_FILES).exists())
120
121=== modified file 'src/maasserver/start_up.py'
122--- src/maasserver/start_up.py 2014-09-23 19:54:04 +0000
123+++ src/maasserver/start_up.py 2014-09-24 17:54:53 +0000
124@@ -16,8 +16,6 @@
125 'start_up'
126 ]
127
128-from textwrap import dedent
129-
130 from django.db import (
131 connection,
132 transaction,
133@@ -28,11 +26,10 @@
134 )
135 from maasserver.bootresources import ensure_boot_source_definition
136 from maasserver.components import (
137- get_persistent_error,
138- register_persistent_error,
139+ hide_missing_boot_image_error,
140+ show_missing_boot_image_error,
141 )
142 from maasserver.dns.config import write_full_dns_config
143-from maasserver.enum import COMPONENT
144 from maasserver.fields import register_mac_type
145 from maasserver.models import (
146 BootResource,
147@@ -63,18 +60,6 @@
148 eventloop.start().wait(10)
149
150
151-def update_boot_resource_error():
152- import_script = COMPONENT.IMPORT_PXE_FILES
153- have_resources = BootResource.objects.all().exists()
154- if not have_resources and get_persistent_error(import_script) is None:
155- warning = dedent("""\
156- No boot images are available. Nodes will not be able to provision
157- without boot images. Start the boot images import process to
158- resolve this issue.
159- """)
160- register_persistent_error(import_script, warning)
161-
162-
163 def inner_start_up():
164 """Startup jobs that must run serialized w.r.t. other starting servers."""
165 # Register our MAC data type with psycopg.
166@@ -95,5 +80,8 @@
167 # Regenerate MAAS's DNS configuration. This should be reentrant, really.
168 write_full_dns_config(reload_retry=True)
169
170- # Check whether we have boot images yet.
171- update_boot_resource_error()
172+ # Check whether we have boot resources yet.
173+ if not BootResource.objects.all().exists():
174+ show_missing_boot_image_error()
175+ else:
176+ hide_missing_boot_image_error()
177
178=== modified file 'src/maasserver/tests/test_start_up.py'
179--- src/maasserver/tests/test_start_up.py 2014-09-23 21:21:43 +0000
180+++ src/maasserver/tests/test_start_up.py 2014-09-24 17:54:53 +0000
181@@ -19,11 +19,7 @@
182 locks,
183 start_up,
184 )
185-from maasserver.components import (
186- discard_persistent_error,
187- register_persistent_error,
188- )
189-from maasserver.enum import COMPONENT
190+from maasserver.components import hide_missing_boot_image_error
191 from maasserver.models import (
192 BootSource,
193 NodeGroup,
194@@ -37,12 +33,8 @@
195 MockCalledOnceWith,
196 MockCalledWith,
197 )
198-from mock import ANY
199 from testresources import FixtureResource
200-from testtools.matchers import (
201- HasLength,
202- Not,
203- )
204+from testtools.matchers import HasLength
205
206
207 class LockChecker:
208@@ -120,35 +112,14 @@
209 def test__warns_about_missing_boot_resources(self):
210 # If no boot resources have been created, then the user has not
211 # performed the import process.
212- discard_persistent_error(COMPONENT.IMPORT_PXE_FILES)
213- recorder = self.patch(start_up, 'register_persistent_error')
214-
215+ hide_missing_boot_image_error()
216+ recorder = self.patch(start_up, 'show_missing_boot_image_error')
217 start_up.inner_start_up()
218-
219- self.assertThat(
220- recorder,
221- MockCalledWith(COMPONENT.IMPORT_PXE_FILES, ANY))
222+ self.assertThat(recorder, MockCalledWith())
223
224 def test__does_not_warn_if_boot_resources_are_known(self):
225 # If boot resources are known, there is no warning.
226 factory.make_BootResource()
227- recorder = self.patch(start_up, 'register_persistent_error')
228-
229- start_up.inner_start_up()
230-
231- self.assertThat(
232- recorder,
233- Not(MockCalledWith(COMPONENT.IMPORT_PXE_FILES, ANY)))
234-
235- def test__does_not_warn_if_already_warning(self):
236- # If there already is a warning about missing boot resources, it will
237- # not be replaced.
238- register_persistent_error(
239- COMPONENT.IMPORT_PXE_FILES, factory.make_string())
240- recorder = self.patch(start_up, 'register_persistent_error')
241-
242- start_up.inner_start_up()
243-
244- self.assertThat(
245- recorder,
246- Not(MockCalledWith(COMPONENT.IMPORT_PXE_FILES, ANY)))
247+ recorder = self.patch(start_up, 'hide_missing_boot_image_error')
248+ start_up.inner_start_up()
249+ self.assertThat(recorder, MockCalledWith())