Merge lp:~blake-rouse/maas/fix-1470591-1.8 into lp:maas/1.8

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 4031
Proposed branch: lp:~blake-rouse/maas/fix-1470591-1.8
Merge into: lp:maas/1.8
Diff against target: 178 lines (+126/-8)
3 files modified
src/maasserver/api/tests/test_maas.py (+75/-0)
src/maasserver/forms.py (+24/-2)
src/maasserver/forms_settings.py (+27/-6)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-1470591-1.8
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+266636@code.launchpad.net

Commit message

Fix setting the default_distro_series over the API.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Backport self review.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/maasserver/api/tests/test_maas.py'
2--- src/maasserver/api/tests/test_maas.py 1970-01-01 00:00:00 +0000
3+++ src/maasserver/api/tests/test_maas.py 2015-07-31 23:40:39 +0000
4@@ -0,0 +1,75 @@
5+# Copyright 2013-2015 Canonical Ltd. This software is licensed under the
6+# GNU Affero General Public License version 3 (see the file LICENSE).
7+
8+"""Tests for maas endpoint in the API."""
9+
10+from __future__ import (
11+ absolute_import,
12+ print_function,
13+ unicode_literals,
14+ )
15+
16+str = None
17+
18+__metaclass__ = type
19+__all__ = []
20+
21+import httplib
22+
23+from django.core.urlresolvers import reverse
24+from maasserver.models.config import Config
25+from maasserver.testing.api import APITestCase
26+from maasserver.testing.factory import factory
27+from maasserver.testing.osystems import (
28+ make_osystem_with_releases,
29+ make_usable_osystem,
30+ patch_usable_osystems,
31+)
32+
33+
34+class MAASHandlerAPITest(APITestCase):
35+
36+ def test_get_config_default_distro_series(self):
37+ self.become_admin()
38+ default_distro_series = factory.make_name("distro_series")
39+ Config.objects.set_config(
40+ "default_distro_series", default_distro_series)
41+ response = self.client.get(
42+ reverse('maas_handler'), {
43+ "op": "get_config",
44+ "name": "default_distro_series",
45+ })
46+ self.assertEquals(httplib.OK, response.status_code, response.content)
47+ self.assertEquals('"%s"' % default_distro_series, response.content)
48+
49+ def test_set_config_default_distro_series(self):
50+ self.become_admin()
51+ osystem = make_usable_osystem(self)
52+ Config.objects.set_config("default_osystem", osystem['name'])
53+ selected_release = osystem['releases'][0]['name']
54+ response = self.client.post(
55+ reverse('maas_handler'), {
56+ "op": "set_config",
57+ "name": "default_distro_series",
58+ "value": selected_release,
59+ })
60+ self.assertEquals(httplib.OK, response.status_code, response.content)
61+ self.assertEquals(
62+ selected_release,
63+ Config.objects.get_config("default_distro_series"))
64+
65+ def test_set_config_only_default_osystem_are_valid_for_distro_series(self):
66+ self.become_admin()
67+ default_osystem = make_osystem_with_releases(self)
68+ other_osystem = make_osystem_with_releases(self)
69+ patch_usable_osystems(self, [default_osystem, other_osystem])
70+ Config.objects.set_config("default_osystem", default_osystem['name'])
71+ invalid_release = other_osystem['releases'][0]['name']
72+ response = self.client.post(
73+ reverse('maas_handler'), {
74+ "op": "set_config",
75+ "name": "default_distro_series",
76+ "value": invalid_release,
77+ })
78+ self.assertEquals(
79+ httplib.BAD_REQUEST, response.status_code, response.content)
80
81=== modified file 'src/maasserver/forms.py'
82--- src/maasserver/forms.py 2015-06-04 14:31:33 +0000
83+++ src/maasserver/forms.py 2015-07-31 23:40:39 +0000
84@@ -110,6 +110,7 @@
85 CONFIG_ITEMS_KEYS,
86 get_config_field,
87 INVALID_SETTING_MSG_TEMPLATE,
88+ validate_missing_boot_images,
89 )
90 from maasserver.models import (
91 BootResource,
92@@ -1369,10 +1370,31 @@
93 # don't want _load_initial called until the field has been added.
94 Form.__init__(self, *args, **kwargs)
95 self.fields['default_osystem'] = get_config_field('default_osystem')
96- self.fields['default_distro_series'] = get_config_field(
97- 'default_distro_series')
98+ self.fields['default_distro_series'] = (
99+ self._get_default_distro_series_field_for_ui())
100 self._load_initials()
101
102+ def _get_default_distro_series_field_for_ui(self):
103+ """This create the field with os/release. This is needed by the UI
104+ to filter the releases based on the OS selection. The API uses the
105+ field defined in forms_settings.py"""
106+ usable_oses = list_all_usable_osystems()
107+ release_choices = list_release_choices(
108+ list_all_usable_releases(usable_oses), include_default=False)
109+ if len(release_choices) == 0:
110+ release_choices = [('---', '--- No Usable Release ---')]
111+ field = forms.ChoiceField(
112+ initial=Config.objects.get_config('default_distro_series'),
113+ choices=release_choices,
114+ validators=[validate_missing_boot_images],
115+ error_messages={
116+ 'invalid_choice': compose_invalid_choice_text(
117+ 'release', release_choices)
118+ },
119+ label="Default OS release used for deployment",
120+ required=False)
121+ return field
122+
123 def _load_initials(self):
124 super(DeployForm, self)._load_initials()
125 initial_os = self.fields['default_osystem'].initial
126
127=== modified file 'src/maasserver/forms_settings.py'
128--- src/maasserver/forms_settings.py 2015-07-03 17:15:01 +0000
129+++ src/maasserver/forms_settings.py 2015-07-31 23:40:39 +0000
130@@ -38,7 +38,6 @@
131 list_all_usable_releases,
132 list_commissioning_choices,
133 list_osystem_choices,
134- list_release_choices,
135 )
136
137
138@@ -73,13 +72,35 @@
139 return field
140
141
142+def get_default_usable_osystem(default_osystem):
143+ """Return the osystem from the clusters that matches the default_osystem.
144+ """
145+ usable_oses = list_all_usable_osystems()
146+ for usable_os in usable_oses:
147+ if usable_os["name"] == default_osystem:
148+ return usable_os
149+ return None
150+
151+
152+def list_choices_for_releases(releases):
153+ """List all the release choices."""
154+ return [
155+ (release['name'], release['title'])
156+ for release in releases
157+ ]
158+
159+
160 def make_default_distro_series_field(*args, **kwargs):
161 """Build and return the default_distro_series field."""
162- usable_oses = list_all_usable_osystems()
163- release_choices = list_release_choices(
164- list_all_usable_releases(usable_oses), include_default=False)
165- if len(release_choices) == 0:
166- release_choices = [('---', '--- No Usable Release ---')]
167+ default_osystem = Config.objects.get_config('default_osystem')
168+ default_usable_os = get_default_usable_osystem(default_osystem)
169+ release_choices = [('---', '--- No Usable Release ---')]
170+ if default_usable_os is not None:
171+ releases = list_all_usable_releases(
172+ [default_usable_os])[default_osystem]
173+ valid_release_choices = list_choices_for_releases(releases)
174+ if len(valid_release_choices) > 0:
175+ release_choices = valid_release_choices
176 field = forms.ChoiceField(
177 initial=Config.objects.get_config('default_distro_series'),
178 choices=release_choices,

Subscribers

People subscribed via source and target branches

to all changes: