Merge lp:~ltrager/maas/hwe_kernel_with_release into lp:~maas-committers/maas/trunk

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: no longer in the source branch.
Merged at revision: 4418
Proposed branch: lp:~ltrager/maas/hwe_kernel_with_release
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 364 lines (+143/-15)
10 files modified
src/maasserver/forms_settings.py (+6/-5)
src/maasserver/static/js/angular/directives/os_select.js (+1/-1)
src/maasserver/static/partials/node-details.html (+1/-1)
src/maasserver/tests/test_forms_commissioning.py (+23/-0)
src/maasserver/utils/osystems.py (+35/-5)
src/maasserver/utils/tests/test_osystems.py (+27/-0)
src/maasserver/websockets/handlers/general.py (+3/-1)
src/maasserver/websockets/handlers/node.py (+2/-1)
src/maasserver/websockets/handlers/tests/test_general.py (+43/-0)
src/maasserver/websockets/handlers/tests/test_node.py (+2/-1)
To merge this branch: bzr merge lp:~ltrager/maas/hwe_kernel_with_release
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+275592@code.launchpad.net

Commit message

Display the release the hwe-kernel comes from in the UI

Description of the change

Display the release the hwe-kernel comes from in the UI. To find this information I first check the BootSourceCache, if it isn't found there I then check UbuntuDistroInfo from the distro_info package. We do have supported hwe-kernels from releases we no longer support. For example Precise has hwe-q but because Quantal is no longer in our simplestreams(due to it being EOL) we need to fall back on UbuntuDistroInfo to get our mapping. I made the hwe-kernel label 'hwe-kernel (release)' e.g 'hwe-v (vivid)' or 'hwe-t (trusty)'. If MAAS can't find a mapping it just displays the kernel e.g 'hwe-q' or 'hwe-r'.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

This all looks good except for the conspicuous absence of tests.

review: Needs Fixing
Revision history for this message
Gavin Panella (allenap) wrote :

The tests you've added look good (with one suggestion) but a few things are still untested.

review: Needs Fixing
Revision history for this message
Lee Trager (ltrager) wrote :

I've added more testing. Let me know if you think this needs anything else.

Revision history for this message
Gavin Panella (allenap) :
Revision history for this message
Gavin Panella (allenap) wrote :

Looks good, thanks doing those extra tests.

review: Approve
Revision history for this message
Andres Rodriguez (andreserl) wrote :

There's a tiny mistake in the branch, it is display HWE kernels as:

hwe-t (trusty)

instead of

trusty (hwe-t)

Please make this change in a following branch.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/forms_settings.py'
2--- src/maasserver/forms_settings.py 2015-10-23 17:53:22 +0000
3+++ src/maasserver/forms_settings.py 2015-10-27 17:51:01 +0000
4@@ -39,6 +39,7 @@
5 list_all_usable_osystems,
6 list_all_usable_releases,
7 list_commissioning_choices,
8+ list_hwe_kernel_choices,
9 list_osystem_choices,
10 release_a_newer_than_b,
11 )
12@@ -125,11 +126,11 @@
13 'commissioning_distro_series')
14 if commissioning_series:
15 commissioning_os_release = "ubuntu/" + commissioning_series
16- kernel_choices += [
17- (kernel, kernel)
18- for kernel in BootResource.objects.get_usable_hwe_kernels(
19- commissioning_os_release)
20- if release_a_newer_than_b(kernel, commissioning_series)]
21+ kernel_choices += list_hwe_kernel_choices(
22+ [kernel
23+ for kernel in BootResource.objects.get_usable_hwe_kernels(
24+ commissioning_os_release)
25+ if release_a_newer_than_b(kernel, commissioning_series)])
26 field = forms.ChoiceField(
27 initial=Config.objects.get_config('default_min_hwe_kernel'),
28 choices=kernel_choices,
29
30=== modified file 'src/maasserver/static/js/angular/directives/os_select.js'
31--- src/maasserver/static/js/angular/directives/os_select.js 2015-10-15 19:36:22 +0000
32+++ src/maasserver/static/js/angular/directives/os_select.js 2015-10-27 17:51:01 +0000
33@@ -20,7 +20,7 @@
34 '<select name="hwe_kernel" data-ng-model="ngModel.hwe_kernel" ',
35 'data-ng-show="hwe_kernels.length"',
36 'data-ng-options="',
37- 'hwe_kernel for hwe_kernel in hwe_kernels">',
38+ 'hwe_kernel[0] as hwe_kernel[1] for hwe_kernel in hwe_kernels">',
39 '<option value="">Default kernel</option>',
40 '</select>'
41 ].join(''));
42
43=== modified file 'src/maasserver/static/partials/node-details.html'
44--- src/maasserver/static/partials/node-details.html 2015-10-26 11:46:36 +0000
45+++ src/maasserver/static/partials/node-details.html 2015-10-27 17:51:01 +0000
46@@ -183,7 +183,7 @@
47 <select name="min_hwe_kernel" id="min_hwe_kernel" placeholder="No minimum kernel"
48 data-ng-disabled="!summary.editing"
49 data-ng-model="summary.min_hwe_kernel.selected"
50- data-ng-options="hwe_kernel for hwe_kernel in summary.min_hwe_kernel.options">
51+ data-ng-options="hwe_kernel[0] as hwe_kernel[1] for hwe_kernel in summary.min_hwe_kernel.options">
52 <option value="">No minimum kernel</option>
53 </select>
54 </div>
55
56=== modified file 'src/maasserver/tests/test_forms_commissioning.py'
57--- src/maasserver/tests/test_forms_commissioning.py 2015-10-23 17:53:22 +0000
58+++ src/maasserver/tests/test_forms_commissioning.py 2015-10-27 17:51:01 +0000
59@@ -14,11 +14,16 @@
60 __metaclass__ = type
61 __all__ = []
62
63+import random
64+
65+from distro_info import UbuntuDistroInfo
66 from django.core.files.uploadedfile import SimpleUploadedFile
67+from maasserver.enum import BOOT_RESOURCE_TYPE
68 from maasserver.forms import (
69 CommissioningForm,
70 CommissioningScriptForm,
71 )
72+from maasserver.models import Config
73 from maasserver.testing.factory import factory
74 from maasserver.testing.testcase import MAASServerTestCase
75 from maasserver.utils.forms import compose_invalid_choice_text
76@@ -44,6 +49,24 @@
77 'default_min_hwe_kernel', field.choices),
78 field.error_messages['invalid_choice'])
79
80+ def test_commissioningform_contains_real_and_ui_choice(self):
81+ ubuntu_releases = UbuntuDistroInfo()
82+ release = random.choice(ubuntu_releases.all).decode("utf-8")
83+ name = 'ubuntu/%s' % release
84+ kernel = 'hwe-' + release[0]
85+ factory.make_usable_boot_resource(
86+ name=name,
87+ extra={'subarches': kernel},
88+ rtype=BOOT_RESOURCE_TYPE.SYNCED)
89+ Config.objects.set_config(
90+ 'commissioning_distro_series',
91+ release)
92+ form = CommissioningForm()
93+ self.assertItemsEqual([
94+ ('', '--- No minimum kernel ---'),
95+ (kernel, '%s (%s)' % (kernel, release))],
96+ form.fields['default_min_hwe_kernel'].choices)
97+
98
99 class TestCommissioningScriptForm(MAASServerTestCase):
100
101
102=== modified file 'src/maasserver/utils/osystems.py'
103--- src/maasserver/utils/osystems.py 2015-09-08 18:41:57 +0000
104+++ src/maasserver/utils/osystems.py 2015-10-27 17:51:01 +0000
105@@ -18,17 +18,23 @@
106 'list_all_usable_osystems',
107 'list_all_usable_releases',
108 'list_all_usable_hwe_kernels',
109+ 'list_hwe_kernel_choices',
110 'list_osystem_choices',
111 'list_release_choices',
112 'list_commissioning_choices',
113+ 'make_hwe_kernel_ui_text',
114 'validate_hwe_kernel',
115 ]
116
117 from operator import itemgetter
118
119+from distro_info import UbuntuDistroInfo
120 from django.core.exceptions import ValidationError
121 from maasserver.clusterrpc.osystems import gen_all_known_operating_systems
122-from maasserver.models import BootResource
123+from maasserver.models import (
124+ BootResource,
125+ BootSourceCache,
126+)
127
128
129 def list_all_usable_osystems():
130@@ -76,13 +82,37 @@
131 kernels[osystem] = {}
132 for release in osystems:
133 os_release = osystem + '/' + release['name']
134- kernels[osystem][release['name']] = sorted([
135- i for i in BootResource.objects.get_usable_hwe_kernels(
136- os_release)
137- if release_a_newer_than_b(i, release['name'])])
138+ kernels[osystem][release['name']] = list_hwe_kernel_choices(
139+ sorted([
140+ i for i in BootResource.objects.get_usable_hwe_kernels(
141+ os_release)
142+ if release_a_newer_than_b(i, release['name'])]))
143 return kernels
144
145
146+def make_hwe_kernel_ui_text(hwe_kernel):
147+ if not hwe_kernel:
148+ return hwe_kernel
149+ release_letter = hwe_kernel.replace('hwe-', '')
150+ boot_sources = BootSourceCache.objects.filter(
151+ release__startswith=release_letter,
152+ subarch=hwe_kernel)
153+ if len(boot_sources) > 0:
154+ return "%s (%s)" % (hwe_kernel, boot_sources[0].release)
155+ else:
156+ ubuntu = UbuntuDistroInfo()
157+ for release in ubuntu.all:
158+ if release.startswith(release_letter):
159+ return "%s (%s)" % (hwe_kernel, release)
160+ return hwe_kernel
161+
162+
163+def list_hwe_kernel_choices(hwe_kernels):
164+ return [(hwe_kernel, make_hwe_kernel_ui_text(hwe_kernel))
165+ for hwe_kernel in hwe_kernels
166+ ]
167+
168+
169 def list_all_releases_requiring_keys(osystems):
170 """Return dictionary of OS name mapping to `releases` that require
171 license keys."""
172
173=== modified file 'src/maasserver/utils/tests/test_osystems.py'
174--- src/maasserver/utils/tests/test_osystems.py 2015-09-08 18:41:57 +0000
175+++ src/maasserver/utils/tests/test_osystems.py 2015-10-27 17:51:01 +0000
176@@ -17,11 +17,13 @@
177 from operator import itemgetter
178 import random
179
180+from distro_info import UbuntuDistroInfo
181 from django.core.exceptions import ValidationError
182 from maasserver.clusterrpc.testing.osystems import (
183 make_rpc_osystem,
184 make_rpc_release,
185 )
186+from maasserver.enum import BOOT_RESOURCE_TYPE
187 from maasserver.models import BootResource
188 from maasserver.testing.factory import factory
189 from maasserver.testing.osystems import make_usable_osystem
190@@ -36,6 +38,7 @@
191 list_commissioning_choices,
192 list_osystem_choices,
193 list_release_choices,
194+ make_hwe_kernel_ui_text,
195 release_a_newer_than_b,
196 validate_hwe_kernel,
197 validate_osystem_and_distro_series,
198@@ -260,6 +263,30 @@
199 ]
200 self.assertEqual(choices, list_commissioning_choices([osystem]))
201
202+ def test_make_hwe_kernel_ui_text_finds_release_from_bootsourcecache(self):
203+ ubuntu_releases = UbuntuDistroInfo()
204+ release = random.choice(ubuntu_releases.all).decode("utf-8")
205+ kernel = 'hwe-' + release[0]
206+ factory.make_usable_boot_resource(
207+ name="ubuntu/%s" % release,
208+ extra={'subarches': kernel},
209+ rtype=BOOT_RESOURCE_TYPE.SYNCED)
210+ self.assertEqual(
211+ '%s (%s)' % (kernel, release),
212+ make_hwe_kernel_ui_text(kernel))
213+
214+ def test_make_hwe_kernel_ui_finds_release_from_ubuntudistroinfo(self):
215+ self.assertEqual('hwe-t (trusty)', make_hwe_kernel_ui_text('hwe-t'))
216+
217+ def test_make_hwe_kernel_ui_returns_kernel_when_none_found(self):
218+ # Since this is testing that our fall final fall back returns just the
219+ # kernel name when the release isn't found in BootSourceCache or
220+ # UbuntuDistroInfo we patch out UbuntuDistroInfo so nothing is found.
221+ self.patch(UbuntuDistroInfo, 'all').value = []
222+ self.assertEqual(
223+ 'hwe-m',
224+ make_hwe_kernel_ui_text('hwe-m'))
225+
226
227 class TestValidateOsystemAndDistroSeries(MAASServerTestCase):
228
229
230=== modified file 'src/maasserver/websockets/handlers/general.py'
231--- src/maasserver/websockets/handlers/general.py 2015-10-23 17:53:22 +0000
232+++ src/maasserver/websockets/handlers/general.py 2015-10-27 17:51:01 +0000
233@@ -31,6 +31,7 @@
234 list_all_usable_hwe_kernels,
235 list_all_usable_osystems,
236 list_all_usable_releases,
237+ list_hwe_kernel_choices,
238 list_osystem_choices,
239 list_release_choices,
240 )
241@@ -60,7 +61,8 @@
242
243 def hwe_kernels(self, params):
244 """Return all supported hwe_kernels."""
245- return BootResource.objects.get_usable_hwe_kernels()
246+ return list_hwe_kernel_choices(
247+ BootResource.objects.get_usable_hwe_kernels())
248
249 def default_min_hwe_kernel(self, params):
250 """Return the default_min_hwe_kernel."""
251
252=== modified file 'src/maasserver/websockets/handlers/node.py'
253--- src/maasserver/websockets/handlers/node.py 2015-10-27 00:37:52 +0000
254+++ src/maasserver/websockets/handlers/node.py 2015-10-27 17:51:01 +0000
255@@ -73,6 +73,7 @@
256 XMLToYAML,
257 )
258 from maasserver.utils.orm import transactional
259+from maasserver.utils.osystems import make_hwe_kernel_ui_text
260 from maasserver.utils.threads import deferToDatabase
261 from maasserver.websockets.base import (
262 HandlerDoesNotExistError,
263@@ -276,7 +277,7 @@
264 data["show_os_info"] = self.dehydrate_show_os_info(obj)
265 data["osystem"] = obj.get_osystem()
266 data["distro_series"] = obj.get_distro_series()
267- data["hwe_kernel"] = obj.hwe_kernel
268+ data["hwe_kernel"] = make_hwe_kernel_ui_text(obj.hwe_kernel)
269
270 # Network
271 data["interfaces"] = [
272
273=== modified file 'src/maasserver/websockets/handlers/tests/test_general.py'
274--- src/maasserver/websockets/handlers/tests/test_general.py 2015-10-21 19:45:50 +0000
275+++ src/maasserver/websockets/handlers/tests/test_general.py 2015-10-27 17:51:01 +0000
276@@ -14,17 +14,21 @@
277 __metaclass__ = type
278 __all__ = []
279
280+from distro_info import UbuntuDistroInfo
281 from maasserver.enum import (
282 BOND_LACP_RATE_CHOICES,
283 BOND_MODE_CHOICES,
284 BOND_XMIT_HASH_POLICY_CHOICES,
285+ BOOT_RESOURCE_TYPE,
286 NODE_PERMISSION,
287 )
288+from maasserver.models import BootSourceCache
289 from maasserver.models.config import Config
290 from maasserver.node_action import ACTIONS_DICT
291 from maasserver.testing.factory import factory
292 from maasserver.testing.osystems import make_osystem_with_releases
293 from maasserver.testing.testcase import MAASServerTestCase
294+from maasserver.utils.orm import post_commit_hooks
295 from maasserver.websockets.handlers import general
296 from maasserver.websockets.handlers.general import GeneralHandler
297 from mock import sentinel
298@@ -52,6 +56,45 @@
299 handler = GeneralHandler(factory.make_User(), {})
300 self.assertEquals(sorted(arches), handler.architectures({}))
301
302+ def test_hwe_kernels(self):
303+ ubuntu_releases = UbuntuDistroInfo()
304+ expected_output = []
305+ # Stub out the post commit tasks otherwise the test fails due to
306+ # unrun post-commit tasks at the end of the test.
307+ self.patch(BootSourceCache, "post_commit_do")
308+ # Start with the first release MAAS supported. We do this
309+ # because the lookup between hwe- kernel and release can fail
310+ # when multiple releases start with the same letter. For
311+ # example both warty(4.10) and wily(15.10) will have an hwe-w
312+ # kernel. Because of this the mapping between kernel and
313+ # release will pick the release which was downloaded
314+ # first. Since precise no release has used the same first
315+ # letter so we do not have this problem with supported
316+ # releases.
317+ for release in ubuntu_releases.all[
318+ ubuntu_releases.all.index('precise'):]:
319+ release = release.decode("utf-8")
320+ kernel = 'hwe-' + release[0]
321+ arch = factory.make_name('arch')
322+ architecture = "%s/%s" % (arch, kernel)
323+ factory.make_usable_boot_resource(
324+ name="ubuntu/" + release,
325+ extra={'subarches': kernel},
326+ architecture=architecture,
327+ rtype=BOOT_RESOURCE_TYPE.SYNCED)
328+ # Force run the post commit tasks as we make new boot sources
329+ with post_commit_hooks:
330+ factory.make_BootSourceCache(
331+ os="ubuntu",
332+ arch=arch,
333+ subarch=kernel,
334+ release=release)
335+ expected_output.append((kernel, '%s (%s)' % (kernel, release)))
336+ handler = GeneralHandler(factory.make_User(), {})
337+ self.assertItemsEqual(
338+ sorted(expected_output, key=lambda choice: choice[0]),
339+ sorted(handler.hwe_kernels({}), key=lambda choice: choice[0]))
340+
341 def test_osinfo(self):
342 handler = GeneralHandler(factory.make_User(), {})
343 osystem = make_osystem_with_releases(self)
344
345=== modified file 'src/maasserver/websockets/handlers/tests/test_node.py'
346--- src/maasserver/websockets/handlers/tests/test_node.py 2015-10-27 02:32:56 +0000
347+++ src/maasserver/websockets/handlers/tests/test_node.py 2015-10-27 17:51:01 +0000
348@@ -71,6 +71,7 @@
349 get_one,
350 transactional,
351 )
352+from maasserver.utils.osystems import make_hwe_kernel_ui_text
353 from maasserver.utils.threads import deferToDatabase
354 from maasserver.websockets.base import (
355 HandlerDoesNotExistError,
356@@ -171,7 +172,7 @@
357 for mac_address in node.get_extra_macs()
358 ],
359 "fqdn": node.fqdn,
360- "hwe_kernel": node.hwe_kernel,
361+ "hwe_kernel": make_hwe_kernel_ui_text(node.hwe_kernel),
362 "hostname": node.hostname,
363 "id": node.id,
364 "installation_results": handler.dehydrate_node_results(