Merge lp:~andreserl/maas/lp1664248_webui into lp:~maas-committers/maas/trunk
- lp1664248_webui
- Merge into trunk
Proposed by
Andres Rodriguez
Status: | Superseded | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~andreserl/maas/lp1664248_webui | ||||||||
Merge into: | lp:~maas-committers/maas/trunk | ||||||||
Diff against target: |
801 lines (+384/-75) 18 files modified
src/maasserver/api/packagerepositories.py (+11/-2) src/maasserver/api/tests/test_packagerepositories.py (+136/-21) src/maasserver/compose_preseed.py (+40/-24) src/maasserver/forms/packagerepository.py (+48/-0) src/maasserver/forms/tests/test_packagerepository.py (+38/-16) src/maasserver/migrations/builtin/maasserver/0116_add_disabled_components_for_mirrors.py (+20/-0) src/maasserver/models/packagerepository.py (+8/-0) src/maasserver/models/tests/test_packagerepository.py (+5/-0) src/maasserver/static/js/angular/controllers/settings.js (+2/-0) src/maasserver/static/js/angular/controllers/tests/test_settings.js (+2/-0) src/maasserver/static/js/angular/factories/general.js (+7/-0) src/maasserver/static/js/angular/factories/tests/test_general.js (+16/-3) src/maasserver/static/partials/settings.html (+5/-0) src/maasserver/testing/factory.py (+4/-2) src/maasserver/tests/test_preseed.py (+30/-7) src/maasserver/websockets/handlers/general.py (+5/-0) src/maasserver/websockets/handlers/tests/test_general.py (+6/-0) src/maasserver/websockets/handlers/tests/test_packagerepository.py (+1/-0) |
||||||||
To merge this branch: | bzr merge lp:~andreserl/maas/lp1664248_webui | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Maintainers | Pending | ||
Review via email: mp+320124@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/maasserver/api/packagerepositories.py' | |||
2 | --- src/maasserver/api/packagerepositories.py 2017-02-17 14:23:04 +0000 | |||
3 | +++ src/maasserver/api/packagerepositories.py 2017-03-16 22:02:44 +0000 | |||
4 | @@ -22,6 +22,7 @@ | |||
5 | 22 | 'url', | 22 | 'url', |
6 | 23 | 'distributions', | 23 | 'distributions', |
7 | 24 | 'disabled_pockets', | 24 | 'disabled_pockets', |
8 | 25 | 'disabled_components', | ||
9 | 25 | 'components', | 26 | 'components', |
10 | 26 | 'arches', | 27 | 'arches', |
11 | 27 | 'key', | 28 | 'key', |
12 | @@ -70,7 +71,11 @@ | |||
13 | 70 | 71 | ||
14 | 71 | :param disabled_pockets: The list of pockets to disable. | 72 | :param disabled_pockets: The list of pockets to disable. |
15 | 72 | 73 | ||
17 | 73 | :param components: The list of components to enable. | 74 | :param disabled_components: The list of components to disable. Only |
18 | 75 | applicable to the default Ubuntu repositories. | ||
19 | 76 | |||
20 | 77 | :param components: The list of components to enable. Only applicable | ||
21 | 78 | to custom repositories. | ||
22 | 74 | 79 | ||
23 | 75 | :param arches: The list of supported architectures. | 80 | :param arches: The list of supported architectures. |
24 | 76 | 81 | ||
25 | @@ -129,7 +134,11 @@ | |||
26 | 129 | 134 | ||
27 | 130 | :param disabled_pockets: The list of pockets to disable. | 135 | :param disabled_pockets: The list of pockets to disable. |
28 | 131 | 136 | ||
30 | 132 | :param components: The list of components to enable. | 137 | :param disabled_components: The list of components to disable. Only |
31 | 138 | applicable to the default Ubuntu repositories. | ||
32 | 139 | |||
33 | 140 | :param components: The list of components to enable. Only applicable | ||
34 | 141 | to custom repositories. | ||
35 | 133 | 142 | ||
36 | 134 | :param arches: The list of supported architectures. | 143 | :param arches: The list of supported architectures. |
37 | 135 | 144 | ||
38 | 136 | 145 | ||
39 | === modified file 'src/maasserver/api/tests/test_packagerepositories.py' | |||
40 | --- src/maasserver/api/tests/test_packagerepositories.py 2017-01-28 00:51:47 +0000 | |||
41 | +++ src/maasserver/api/tests/test_packagerepositories.py 2017-03-16 22:02:44 +0000 | |||
42 | @@ -72,27 +72,142 @@ | |||
43 | 72 | self.assertEqual( | 72 | self.assertEqual( |
44 | 73 | http.client.NOT_FOUND, response.status_code, response.content) | 73 | http.client.NOT_FOUND, response.status_code, response.content) |
45 | 74 | 74 | ||
67 | 75 | def test_update(self): | 75 | def test_update_custom_repository(self): |
68 | 76 | self.become_admin() | 76 | """Updates a custom repository""" |
69 | 77 | package_repository = factory.make_PackageRepository() | 77 | self.become_admin() |
70 | 78 | new_values = { | 78 | # Creates a repository which is not 'default'. |
71 | 79 | 'url': factory.make_url(scheme='http'), | 79 | package_repository = factory.make_PackageRepository() |
72 | 80 | 'distributions': [ | 80 | new_values = { |
73 | 81 | factory.make_name("distribution%d" % i) for i in range(3)], | 81 | 'url': factory.make_url(scheme='http'), |
74 | 82 | 'disabled_pockets': [ | 82 | 'distributions': [ |
75 | 83 | factory.make_name("disabled_pocket%d" % i) for i in range(1)], | 83 | factory.make_name("distribution%d" % i) for i in range(3)], |
76 | 84 | 'components': [factory.make_name("comp%d" % i) for i in range(4)], | 84 | 'components': [factory.make_name("comp%d" % i) for i in range(4)], |
77 | 85 | 'arches': [ | 85 | 'arches': [ |
78 | 86 | random.choice(PackageRepository.KNOWN_ARCHES), | 86 | random.choice(PackageRepository.KNOWN_ARCHES), |
79 | 87 | random.choice(PackageRepository.KNOWN_ARCHES), | 87 | random.choice(PackageRepository.KNOWN_ARCHES), |
80 | 88 | ] | 88 | ] |
81 | 89 | } | 89 | } |
82 | 90 | response = self.client.put( | 90 | response = self.client.put( |
83 | 91 | self.get_package_repository_uri(package_repository), new_values) | 91 | self.get_package_repository_uri(package_repository), new_values) |
84 | 92 | self.assertEqual( | 92 | self.assertEqual( |
85 | 93 | http.client.OK, response.status_code, response.content) | 93 | http.client.OK, response.status_code, response.content) |
86 | 94 | package_repository = reload_object(package_repository) | 94 | package_repository = reload_object(package_repository) |
87 | 95 | self.assertAttributes(package_repository, new_values) | 95 | self.assertAttributes(package_repository, new_values) |
88 | 96 | |||
89 | 97 | def test_update_custom_repository_fails_if_disabled_components(self): | ||
90 | 98 | """Test that updating a custom repository fails if specifying | ||
91 | 99 | 'disabled_components'. This is only needed when the repository | ||
92 | 100 | is an Ubuntu repository""" | ||
93 | 101 | self.become_admin() | ||
94 | 102 | # Creates a repository which is not 'default'. | ||
95 | 103 | package_repository = factory.make_PackageRepository() | ||
96 | 104 | new_values = { | ||
97 | 105 | 'url': factory.make_url(scheme='http'), | ||
98 | 106 | 'distributions': [ | ||
99 | 107 | factory.make_name("distribution%d" % i) for i in range(3)], | ||
100 | 108 | 'components': [factory.make_name("comp%d" % i) for i in range(4)], | ||
101 | 109 | 'disabled_components': [ | ||
102 | 110 | factory.make_name("comp%d" % i) for i in range(4)], | ||
103 | 111 | 'arches': [ | ||
104 | 112 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
105 | 113 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
106 | 114 | ] | ||
107 | 115 | } | ||
108 | 116 | response = self.client.put( | ||
109 | 117 | self.get_package_repository_uri(package_repository), new_values) | ||
110 | 118 | self.assertEqual( | ||
111 | 119 | http.client.BAD_REQUEST, response.status_code, response.content) | ||
112 | 120 | |||
113 | 121 | def test_update_ubuntu_mirror(self): | ||
114 | 122 | """Updates a Ubuntu mirror""" | ||
115 | 123 | self.become_admin() | ||
116 | 124 | # Create an Ubuntu mirror without components | ||
117 | 125 | package_repository = factory.make_PackageRepository( | ||
118 | 126 | default=True, components=[]) | ||
119 | 127 | new_values = { | ||
120 | 128 | 'url': factory.make_url(scheme='http'), | ||
121 | 129 | 'distributions': [ | ||
122 | 130 | factory.make_name("distribution%d" % i) for i in range(3)], | ||
123 | 131 | 'disabled_pockets': ["updates", "security"], | ||
124 | 132 | 'disabled_components': ["universe", "multiverse"], | ||
125 | 133 | 'arches': [ | ||
126 | 134 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
127 | 135 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
128 | 136 | ] | ||
129 | 137 | } | ||
130 | 138 | response = self.client.put( | ||
131 | 139 | self.get_package_repository_uri(package_repository), new_values) | ||
132 | 140 | self.assertEqual( | ||
133 | 141 | http.client.OK, response.status_code, response.content) | ||
134 | 142 | package_repository = reload_object(package_repository) | ||
135 | 143 | self.assertAttributes(package_repository, new_values) | ||
136 | 144 | |||
137 | 145 | def test_update_ubuntu_mirror_fail_with_invalid_disabled_pockets(self): | ||
138 | 146 | """Test that updating an Ubuntu mirror with invalid pockets fails""" | ||
139 | 147 | self.become_admin() | ||
140 | 148 | # Create an Ubuntu mirror without components | ||
141 | 149 | package_repository = factory.make_PackageRepository( | ||
142 | 150 | default=True, components=[]) | ||
143 | 151 | new_values = { | ||
144 | 152 | 'url': factory.make_url(scheme='http'), | ||
145 | 153 | 'distributions': [ | ||
146 | 154 | factory.make_name("distribution%d" % i) for i in range(3)], | ||
147 | 155 | 'disabled_pockets': ["updateses"], | ||
148 | 156 | 'arches': [ | ||
149 | 157 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
150 | 158 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
151 | 159 | ] | ||
152 | 160 | } | ||
153 | 161 | response = self.client.put( | ||
154 | 162 | self.get_package_repository_uri(package_repository), new_values) | ||
155 | 163 | self.assertEqual( | ||
156 | 164 | http.client.BAD_REQUEST, response.status_code, response.content) | ||
157 | 165 | |||
158 | 166 | def test_update_ubuntu_mirror_fail_with_invalid_disabled_components(self): | ||
159 | 167 | """Test that updating an Ubuntu mirror with invalid components fails""" | ||
160 | 168 | self.become_admin() | ||
161 | 169 | # Create an Ubuntu mirror without components | ||
162 | 170 | package_repository = factory.make_PackageRepository( | ||
163 | 171 | default=True, components=[]) | ||
164 | 172 | new_values = { | ||
165 | 173 | 'url': factory.make_url(scheme='http'), | ||
166 | 174 | 'distributions': [ | ||
167 | 175 | factory.make_name("distribution%d" % i) for i in range(3)], | ||
168 | 176 | 'disabled_components': ['universes'], | ||
169 | 177 | 'arches': [ | ||
170 | 178 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
171 | 179 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
172 | 180 | ] | ||
173 | 181 | } | ||
174 | 182 | response = self.client.put( | ||
175 | 183 | self.get_package_repository_uri(package_repository), new_values) | ||
176 | 184 | self.assertEqual( | ||
177 | 185 | http.client.BAD_REQUEST, response.status_code, response.content) | ||
178 | 186 | |||
179 | 187 | def test_update_ubuntu_mirror_fails_if_components_are_passed(self): | ||
180 | 188 | """Test that updating a Ubuntu mirror fails if specifying | ||
181 | 189 | 'components'. This is only needed when the repository is not | ||
182 | 190 | an Ubuntu repository""" | ||
183 | 191 | self.become_admin() | ||
184 | 192 | # Create an Ubuntu mirror without components | ||
185 | 193 | package_repository = factory.make_PackageRepository( | ||
186 | 194 | default=True, components=[]) | ||
187 | 195 | new_values = { | ||
188 | 196 | 'url': factory.make_url(scheme='http'), | ||
189 | 197 | 'distributions': [ | ||
190 | 198 | factory.make_name("distribution%d" % i) for i in range(3)], | ||
191 | 199 | 'components': [factory.make_name("comp%d" % i) for i in range(4)], | ||
192 | 200 | 'disabled_components': [ | ||
193 | 201 | factory.make_name("comp%d" % i) for i in range(4)], | ||
194 | 202 | 'arches': [ | ||
195 | 203 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
196 | 204 | random.choice(PackageRepository.KNOWN_ARCHES), | ||
197 | 205 | ] | ||
198 | 206 | } | ||
199 | 207 | response = self.client.put( | ||
200 | 208 | self.get_package_repository_uri(package_repository), new_values) | ||
201 | 209 | self.assertEqual( | ||
202 | 210 | http.client.BAD_REQUEST, response.status_code, response.content) | ||
203 | 96 | 211 | ||
204 | 97 | def test_update_admin_only(self): | 212 | def test_update_admin_only(self): |
205 | 98 | package_repository = factory.make_PackageRepository() | 213 | package_repository = factory.make_PackageRepository() |
206 | 99 | 214 | ||
207 | === modified file 'src/maasserver/compose_preseed.py' | |||
208 | --- src/maasserver/compose_preseed.py 2017-02-17 14:23:04 +0000 | |||
209 | +++ src/maasserver/compose_preseed.py 2017-03-16 22:02:44 +0000 | |||
210 | @@ -61,25 +61,41 @@ | |||
211 | 61 | apt_proxy = get_apt_proxy_for_node(node) | 61 | apt_proxy = get_apt_proxy_for_node(node) |
212 | 62 | 62 | ||
213 | 63 | # Process the default Ubuntu Archives or Mirror. | 63 | # Process the default Ubuntu Archives or Mirror. |
233 | 64 | archives = { | 64 | archives = {} |
234 | 65 | 'apt': { | 65 | archives['apt'] = {} |
235 | 66 | 'preserve_sources_list': preserve_sources, | 66 | archives['apt']['preserve_sources_list'] = preserve_sources |
236 | 67 | 'primary': [ | 67 | # If disabled_components exist, build a custom list of repositories |
237 | 68 | { | 68 | if archive.disabled_components: |
238 | 69 | 'arches': ['default'], | 69 | urls = '' |
239 | 70 | 'uri': archive.url | 70 | components = archive.KNOWN_COMPONENTS[:] |
240 | 71 | }, | 71 | |
241 | 72 | ], | 72 | for comp in archive.COMPONENTS_TO_DISABLE: |
242 | 73 | 'security': [ | 73 | if comp in archive.disabled_components: |
243 | 74 | { | 74 | components.remove(comp) |
244 | 75 | 'arches': ['default'], | 75 | urls += 'deb %s $RELEASE %s\n' % ( |
245 | 76 | 'uri': archive.url | 76 | archive.url, ' '.join(components)) |
246 | 77 | }, | 77 | |
247 | 78 | ], | 78 | for pocket in archive.POCKETS_TO_DISABLE: |
248 | 79 | }, | 79 | if pocket not in archive.disabled_pockets: |
249 | 80 | } | 80 | urls += 'deb %s $RELEASE-%s %s\n' % ( |
250 | 81 | if archive.disabled_pockets: | 81 | archive.url, pocket, ' '.join(components)) |
251 | 82 | archives['apt']['disable_suites'] = archive.disabled_pockets | 82 | |
252 | 83 | archives['apt']['sources_list'] = urls | ||
253 | 84 | else: | ||
254 | 85 | archives['apt']['primary'] = [ | ||
255 | 86 | { | ||
256 | 87 | 'arches': ['default'], | ||
257 | 88 | 'uri': archive.url | ||
258 | 89 | } | ||
259 | 90 | ] | ||
260 | 91 | archives['apt']['security'] = [ | ||
261 | 92 | { | ||
262 | 93 | 'arches': ['default'], | ||
263 | 94 | 'uri': archive.url | ||
264 | 95 | } | ||
265 | 96 | ] | ||
266 | 97 | if archive.disabled_pockets: | ||
267 | 98 | archives['apt']['disable_suites'] = archive.disabled_pockets | ||
268 | 83 | if apt_proxy: | 99 | if apt_proxy: |
269 | 84 | archives['apt']['proxy'] = apt_proxy | 100 | archives['apt']['proxy'] = apt_proxy |
270 | 85 | if archive.key: | 101 | if archive.key: |
271 | @@ -94,7 +110,7 @@ | |||
272 | 94 | if repo.url.startswith('ppa:'): | 110 | if repo.url.startswith('ppa:'): |
273 | 95 | url = repo.url | 111 | url = repo.url |
274 | 96 | elif 'ppa.launchpad.net' in repo.url: | 112 | elif 'ppa.launchpad.net' in repo.url: |
276 | 97 | url = 'deb %s %s main' % (repo.url, node.distro_series) | 113 | url = 'deb %s $RELEASE main' % (repo.url) |
277 | 98 | else: | 114 | else: |
278 | 99 | components = '' | 115 | components = '' |
279 | 100 | if not repo.components: | 116 | if not repo.components: |
280 | @@ -105,8 +121,8 @@ | |||
281 | 105 | components = components.strip() | 121 | components = components.strip() |
282 | 106 | 122 | ||
283 | 107 | if not repo.distributions: | 123 | if not repo.distributions: |
286 | 108 | url = 'deb %s %s %s' % ( | 124 | url = 'deb %s $RELEASE %s' % ( |
287 | 109 | repo.url, node.distro_series, components) | 125 | repo.url, components) |
288 | 110 | else: | 126 | else: |
289 | 111 | url = '' | 127 | url = '' |
290 | 112 | for dist in repo.distributions: | 128 | for dist in repo.distributions: |
291 | @@ -120,11 +136,11 @@ | |||
292 | 120 | if repo.key: | 136 | if repo.key: |
293 | 121 | archives['apt']['sources'][repo_name] = { | 137 | archives['apt']['sources'][repo_name] = { |
294 | 122 | 'key': repo.key, | 138 | 'key': repo.key, |
296 | 123 | 'source': url | 139 | 'source': url.strip() |
297 | 124 | } | 140 | } |
298 | 125 | else: | 141 | else: |
299 | 126 | archives['apt']['sources'][repo_name] = { | 142 | archives['apt']['sources'][repo_name] = { |
301 | 127 | 'source': url | 143 | 'source': url.strip() |
302 | 128 | } | 144 | } |
303 | 129 | 145 | ||
304 | 130 | return archives | 146 | return archives |
305 | 131 | 147 | ||
306 | === modified file 'src/maasserver/forms/packagerepository.py' | |||
307 | --- src/maasserver/forms/packagerepository.py 2017-02-17 14:23:04 +0000 | |||
308 | +++ src/maasserver/forms/packagerepository.py 2017-03-16 22:02:44 +0000 | |||
309 | @@ -27,6 +27,7 @@ | |||
310 | 27 | 'url', | 27 | 'url', |
311 | 28 | 'distributions', | 28 | 'distributions', |
312 | 29 | 'disabled_pockets', | 29 | 'disabled_pockets', |
313 | 30 | 'disabled_components', | ||
314 | 30 | 'components', | 31 | 'components', |
315 | 31 | 'arches', | 32 | 'arches', |
316 | 32 | 'key', | 33 | 'key', |
317 | @@ -50,6 +51,9 @@ | |||
318 | 50 | disabled_pockets = UnconstrainedMultipleChoiceField( | 51 | disabled_pockets = UnconstrainedMultipleChoiceField( |
319 | 51 | label="Disabled Pocket list") | 52 | label="Disabled Pocket list") |
320 | 52 | 53 | ||
321 | 54 | disabled_components = UnconstrainedMultipleChoiceField( | ||
322 | 55 | label="Disabled Component list") | ||
323 | 56 | |||
324 | 53 | components = UnconstrainedMultipleChoiceField(label="Component list") | 57 | components = UnconstrainedMultipleChoiceField(label="Component list") |
325 | 54 | 58 | ||
326 | 55 | arches = UnconstrainedMultipleChoiceField(label="Architecture list") | 59 | arches = UnconstrainedMultipleChoiceField(label="Architecture list") |
327 | @@ -99,10 +103,54 @@ | |||
328 | 99 | values = [] | 103 | values = [] |
329 | 100 | for value in self.cleaned_data.get('disabled_pockets', []): | 104 | for value in self.cleaned_data.get('disabled_pockets', []): |
330 | 101 | values.extend([s.strip() for s in value.split(',')]) | 105 | values.extend([s.strip() for s in value.split(',')]) |
331 | 106 | # This allows to reset the values of disabled_pockets if one of the | ||
332 | 107 | # following is passed over the API: | ||
333 | 108 | # disabled_pockets= | ||
334 | 109 | # disabled_pockets='' | ||
335 | 110 | # disabled_pockets=None | ||
336 | 111 | # disabled_pockets=[] | ||
337 | 112 | if values == [''] or values == ['None'] or values == ['[]']: | ||
338 | 113 | return [] | ||
339 | 114 | # Check that a valid pocket is being disable. | ||
340 | 115 | for pocket in values: | ||
341 | 116 | if pocket not in PackageRepository.POCKETS_TO_DISABLE: | ||
342 | 117 | raise ValidationError( | ||
343 | 118 | "'%s' is not a valid Ubuntu archive pocket. You " | ||
344 | 119 | "can only disable %s." % ( | ||
345 | 120 | pocket, PackageRepository.POCKETS_TO_DISABLE)) | ||
346 | 121 | return values | ||
347 | 122 | |||
348 | 123 | def clean_disabled_components(self): | ||
349 | 124 | values = [] | ||
350 | 125 | for value in self.cleaned_data.get('disabled_components', []): | ||
351 | 126 | values.extend([s.strip() for s in value.split(',')]) | ||
352 | 127 | # This allows to reset the values of disabled_components if one of the | ||
353 | 128 | # following is passed over the API: | ||
354 | 129 | # disabled_components= | ||
355 | 130 | # disabled_components='' | ||
356 | 131 | # disabled_components=None | ||
357 | 132 | # disabled_components=[] | ||
358 | 133 | if values == [''] or values == ['None'] or values == ['[]']: | ||
359 | 134 | return [] | ||
360 | 135 | if self.instance is not None and not self.instance.default and values: | ||
361 | 136 | raise ValidationError( | ||
362 | 137 | "This is a custom repository. Please update 'components' " | ||
363 | 138 | "instead.") | ||
364 | 139 | # Check that a valid component is being passed. | ||
365 | 140 | for component in values: | ||
366 | 141 | if component not in PackageRepository.COMPONENTS_TO_DISABLE: | ||
367 | 142 | raise ValidationError( | ||
368 | 143 | "'%s' is not a valid Ubuntu archive component. You " | ||
369 | 144 | "can only disable %s." % ( | ||
370 | 145 | component, PackageRepository.COMPONENTS_TO_DISABLE)) | ||
371 | 102 | return values | 146 | return values |
372 | 103 | 147 | ||
373 | 104 | def clean_components(self): | 148 | def clean_components(self): |
374 | 105 | values = [] | 149 | values = [] |
375 | 106 | for value in self.cleaned_data.get('components', []): | 150 | for value in self.cleaned_data.get('components', []): |
376 | 107 | values.extend([s.strip() for s in value.split(',')]) | 151 | values.extend([s.strip() for s in value.split(',')]) |
377 | 152 | if self.instance is not None and self.instance.default and values: | ||
378 | 153 | raise ValidationError( | ||
379 | 154 | "This is a default Ubuntu repository. Please update " | ||
380 | 155 | "'disabled_components' instead.") | ||
381 | 108 | return values | 156 | return values |
382 | 109 | 157 | ||
383 | === modified file 'src/maasserver/forms/tests/test_packagerepository.py' | |||
384 | --- src/maasserver/forms/tests/test_packagerepository.py 2017-02-17 14:23:04 +0000 | |||
385 | +++ src/maasserver/forms/tests/test_packagerepository.py 2017-03-16 22:02:44 +0000 | |||
386 | @@ -27,10 +27,10 @@ | |||
387 | 27 | arch2 = random.choice(PackageRepository.KNOWN_ARCHES) | 27 | arch2 = random.choice(PackageRepository.KNOWN_ARCHES) |
388 | 28 | dist1 = factory.make_name('dist') | 28 | dist1 = factory.make_name('dist') |
389 | 29 | dist2 = factory.make_name('dist') | 29 | dist2 = factory.make_name('dist') |
394 | 30 | pock1 = factory.make_name('pock') | 30 | pock1 = 'updates' |
395 | 31 | pock2 = factory.make_name('pock') | 31 | pock2 = 'backports' |
396 | 32 | comp1 = factory.make_name('comp') | 32 | comp1 = 'universe' |
397 | 33 | comp2 = factory.make_name('comp') | 33 | comp2 = 'multiverse' |
398 | 34 | enabled = factory.pick_bool() | 34 | enabled = factory.pick_bool() |
399 | 35 | params = { | 35 | params = { |
400 | 36 | 'name': name, | 36 | 'name': name, |
401 | @@ -195,18 +195,40 @@ | |||
402 | 195 | package_repository = factory.make_PackageRepository() | 195 | package_repository = factory.make_PackageRepository() |
403 | 196 | form = PackageRepositoryForm( | 196 | form = PackageRepositoryForm( |
404 | 197 | instance=package_repository, | 197 | instance=package_repository, |
417 | 198 | data={'disabled_pockets': ['val1,val2']}) | 198 | data={'disabled_pockets': ['updates,backports']}) |
418 | 199 | repo = form.save() | 199 | repo = form.save() |
419 | 200 | self.assertItemsEqual(['val1', 'val2'], repo.disabled_pockets) | 200 | self.assertItemsEqual(['updates', 'backports'], repo.disabled_pockets) |
420 | 201 | form = PackageRepositoryForm( | 201 | form = PackageRepositoryForm( |
421 | 202 | instance=package_repository, | 202 | instance=package_repository, |
422 | 203 | data={'disabled_pockets': ['val1, val2']}) | 203 | data={'disabled_pockets': ['updates, backports']}) |
423 | 204 | repo = form.save() | 204 | repo = form.save() |
424 | 205 | self.assertItemsEqual(['val1', 'val2'], repo.disabled_pockets) | 205 | self.assertItemsEqual(['updates', 'backports'], repo.disabled_pockets) |
425 | 206 | form = PackageRepositoryForm( | 206 | form = PackageRepositoryForm( |
426 | 207 | instance=package_repository, data={'disabled_pockets': ['val1']}) | 207 | instance=package_repository, |
427 | 208 | repo = form.save() | 208 | data={'disabled_pockets': ['updates']}) |
428 | 209 | self.assertItemsEqual(['val1'], repo.disabled_pockets) | 209 | repo = form.save() |
429 | 210 | self.assertItemsEqual(['updates'], repo.disabled_pockets) | ||
430 | 211 | |||
431 | 212 | def test__disabled_component_comma_cleaning(self): | ||
432 | 213 | package_repository = factory.make_PackageRepository( | ||
433 | 214 | default=True, components=[]) | ||
434 | 215 | form = PackageRepositoryForm( | ||
435 | 216 | instance=package_repository, | ||
436 | 217 | data={'disabled_components': ['universe,multiverse']}) | ||
437 | 218 | repo = form.save() | ||
438 | 219 | self.assertItemsEqual( | ||
439 | 220 | ['universe', 'multiverse'], repo.disabled_components) | ||
440 | 221 | form = PackageRepositoryForm( | ||
441 | 222 | instance=package_repository, | ||
442 | 223 | data={'disabled_components': ['universe, multiverse']}) | ||
443 | 224 | repo = form.save() | ||
444 | 225 | self.assertItemsEqual( | ||
445 | 226 | ['universe', 'multiverse'], repo.disabled_components) | ||
446 | 227 | form = PackageRepositoryForm( | ||
447 | 228 | instance=package_repository, | ||
448 | 229 | data={'disabled_components': ['universe']}) | ||
449 | 230 | repo = form.save() | ||
450 | 231 | self.assertItemsEqual(['universe'], repo.disabled_components) | ||
451 | 210 | 232 | ||
452 | 211 | def test__component_comma_cleaning(self): | 233 | def test__component_comma_cleaning(self): |
453 | 212 | package_repository = factory.make_PackageRepository() | 234 | package_repository = factory.make_PackageRepository() |
454 | 213 | 235 | ||
455 | === added file 'src/maasserver/migrations/builtin/maasserver/0116_add_disabled_components_for_mirrors.py' | |||
456 | --- src/maasserver/migrations/builtin/maasserver/0116_add_disabled_components_for_mirrors.py 1970-01-01 00:00:00 +0000 | |||
457 | +++ src/maasserver/migrations/builtin/maasserver/0116_add_disabled_components_for_mirrors.py 2017-03-16 22:02:44 +0000 | |||
458 | @@ -0,0 +1,20 @@ | |||
459 | 1 | # -*- coding: utf-8 -*- | ||
460 | 2 | from __future__ import unicode_literals | ||
461 | 3 | |||
462 | 4 | from django.db import migrations, models | ||
463 | 5 | import django.contrib.postgres.fields | ||
464 | 6 | |||
465 | 7 | |||
466 | 8 | class Migration(migrations.Migration): | ||
467 | 9 | |||
468 | 10 | dependencies = [ | ||
469 | 11 | ('maasserver', '0115_additional_boot_resource_filetypes'), | ||
470 | 12 | ] | ||
471 | 13 | |||
472 | 14 | operations = [ | ||
473 | 15 | migrations.AddField( | ||
474 | 16 | model_name='packagerepository', | ||
475 | 17 | name='disabled_components', | ||
476 | 18 | field=django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), size=None, default=list, blank=True, null=True), | ||
477 | 19 | ), | ||
478 | 20 | ] | ||
479 | 0 | 21 | ||
480 | === modified file 'src/maasserver/models/packagerepository.py' | |||
481 | --- src/maasserver/models/packagerepository.py 2016-09-01 13:12:15 +0000 | |||
482 | +++ src/maasserver/models/packagerepository.py 2017-03-16 22:02:44 +0000 | |||
483 | @@ -74,6 +74,9 @@ | |||
484 | 74 | def get_pockets_to_disable(self): | 74 | def get_pockets_to_disable(self): |
485 | 75 | return PackageRepository.POCKETS_TO_DISABLE | 75 | return PackageRepository.POCKETS_TO_DISABLE |
486 | 76 | 76 | ||
487 | 77 | def get_components_to_disable(self): | ||
488 | 78 | return PackageRepository.COMPONENTS_TO_DISABLE | ||
489 | 79 | |||
490 | 77 | def get_default_archive(self, arch): | 80 | def get_default_archive(self, arch): |
491 | 78 | return PackageRepository.objects.filter( | 81 | return PackageRepository.objects.filter( |
492 | 79 | arches__contains=[arch], | 82 | arches__contains=[arch], |
493 | @@ -94,6 +97,8 @@ | |||
494 | 94 | PORTS_ARCHES = ['armhf', 'arm64', 'ppc64el'] | 97 | PORTS_ARCHES = ['armhf', 'arm64', 'ppc64el'] |
495 | 95 | KNOWN_ARCHES = MAIN_ARCHES + PORTS_ARCHES | 98 | KNOWN_ARCHES = MAIN_ARCHES + PORTS_ARCHES |
496 | 96 | POCKETS_TO_DISABLE = ['updates', 'security', 'backports'] | 99 | POCKETS_TO_DISABLE = ['updates', 'security', 'backports'] |
497 | 100 | COMPONENTS_TO_DISABLE = ['restricted', 'universe', 'multiverse'] | ||
498 | 101 | KNOWN_COMPONENTS = ['main', 'restricted', 'universe', 'multiverse'] | ||
499 | 97 | 102 | ||
500 | 98 | class Meta(DefaultMeta): | 103 | class Meta(DefaultMeta): |
501 | 99 | """Needed for South to recognize this model.""" | 104 | """Needed for South to recognize this model.""" |
502 | @@ -111,6 +116,9 @@ | |||
503 | 111 | disabled_pockets = ArrayField( | 116 | disabled_pockets = ArrayField( |
504 | 112 | TextField(), blank=True, null=True, default=list) | 117 | TextField(), blank=True, null=True, default=list) |
505 | 113 | 118 | ||
506 | 119 | disabled_components = ArrayField( | ||
507 | 120 | TextField(), blank=True, null=True, default=list) | ||
508 | 121 | |||
509 | 114 | components = ArrayField(TextField(), blank=True, null=True, default=list) | 122 | components = ArrayField(TextField(), blank=True, null=True, default=list) |
510 | 115 | 123 | ||
511 | 116 | arches = ArrayField(TextField(), blank=True, null=True, default=list) | 124 | arches = ArrayField(TextField(), blank=True, null=True, default=list) |
512 | 117 | 125 | ||
513 | === modified file 'src/maasserver/models/tests/test_packagerepository.py' | |||
514 | --- src/maasserver/models/tests/test_packagerepository.py 2016-08-25 19:31:20 +0000 | |||
515 | +++ src/maasserver/models/tests/test_packagerepository.py 2017-03-16 22:02:44 +0000 | |||
516 | @@ -61,3 +61,8 @@ | |||
517 | 61 | self.assertEqual( | 61 | self.assertEqual( |
518 | 62 | PackageRepository.objects.get_pockets_to_disable(), | 62 | PackageRepository.objects.get_pockets_to_disable(), |
519 | 63 | PackageRepository.POCKETS_TO_DISABLE) | 63 | PackageRepository.POCKETS_TO_DISABLE) |
520 | 64 | |||
521 | 65 | def test_get_components_to_disable(self): | ||
522 | 66 | self.assertEqual( | ||
523 | 67 | PackageRepository.objects.get_components_to_disable(), | ||
524 | 68 | PackageRepository.COMPONENTS_TO_DISABLE) | ||
525 | 64 | 69 | ||
526 | === modified file 'src/maasserver/static/js/angular/controllers/settings.js' | |||
527 | --- src/maasserver/static/js/angular/controllers/settings.js 2016-09-21 14:49:23 +0000 | |||
528 | +++ src/maasserver/static/js/angular/controllers/settings.js 2017-03-16 22:02:44 +0000 | |||
529 | @@ -30,6 +30,8 @@ | |||
530 | 30 | GeneralManager.getData("known_architectures"); | 30 | GeneralManager.getData("known_architectures"); |
531 | 31 | $scope.pockets_to_disable = | 31 | $scope.pockets_to_disable = |
532 | 32 | GeneralManager.getData("pockets_to_disable"); | 32 | GeneralManager.getData("pockets_to_disable"); |
533 | 33 | $scope.components_to_disable = | ||
534 | 34 | GeneralManager.getData("components_to_disable"); | ||
535 | 33 | $scope.packageRepositoriesManager = PackageRepositoriesManager; | 35 | $scope.packageRepositoriesManager = PackageRepositoriesManager; |
536 | 34 | $scope.repositories = | 36 | $scope.repositories = |
537 | 35 | PackageRepositoriesManager.getItems(); | 37 | PackageRepositoriesManager.getItems(); |
538 | 36 | 38 | ||
539 | === modified file 'src/maasserver/static/js/angular/controllers/tests/test_settings.js' | |||
540 | --- src/maasserver/static/js/angular/controllers/tests/test_settings.js 2016-09-22 15:05:38 +0000 | |||
541 | +++ src/maasserver/static/js/angular/controllers/tests/test_settings.js 2017-03-16 22:02:44 +0000 | |||
542 | @@ -116,6 +116,8 @@ | |||
543 | 116 | GeneralManager.getData("known_architectures")); | 116 | GeneralManager.getData("known_architectures")); |
544 | 117 | expect($scope.pockets_to_disable).toBe( | 117 | expect($scope.pockets_to_disable).toBe( |
545 | 118 | GeneralManager.getData("pockets_to_disable")); | 118 | GeneralManager.getData("pockets_to_disable")); |
546 | 119 | expect($scope.components_to_disable).toBe( | ||
547 | 120 | GeneralManager.getData("components_to_disable")); | ||
548 | 119 | expect($scope.packageRepositoriesManager).toBe( | 121 | expect($scope.packageRepositoriesManager).toBe( |
549 | 120 | PackageRepositoriesManager); | 122 | PackageRepositoriesManager); |
550 | 121 | expect($scope.repositories).toBe( | 123 | expect($scope.repositories).toBe( |
551 | 122 | 124 | ||
552 | === modified file 'src/maasserver/static/js/angular/factories/general.js' | |||
553 | --- src/maasserver/static/js/angular/factories/general.js 2016-09-22 15:05:38 +0000 | |||
554 | +++ src/maasserver/static/js/angular/factories/general.js 2017-03-16 22:02:44 +0000 | |||
555 | @@ -77,6 +77,13 @@ | |||
556 | 77 | polling: false, | 77 | polling: false, |
557 | 78 | nextPromise: null | 78 | nextPromise: null |
558 | 79 | }, | 79 | }, |
559 | 80 | components_to_disable: { | ||
560 | 81 | method: "general.components_to_disable", | ||
561 | 82 | data: [], | ||
562 | 83 | loaded: false, | ||
563 | 84 | polling: false, | ||
564 | 85 | nextPromise: null | ||
565 | 86 | }, | ||
566 | 80 | hwe_kernels: { | 87 | hwe_kernels: { |
567 | 81 | method: "general.hwe_kernels", | 88 | method: "general.hwe_kernels", |
568 | 82 | data: [], | 89 | data: [], |
569 | 83 | 90 | ||
570 | === modified file 'src/maasserver/static/js/angular/factories/tests/test_general.js' | |||
571 | --- src/maasserver/static/js/angular/factories/tests/test_general.js 2016-08-22 04:10:43 +0000 | |||
572 | +++ src/maasserver/static/js/angular/factories/tests/test_general.js 2017-03-16 22:02:44 +0000 | |||
573 | @@ -53,9 +53,9 @@ | |||
574 | 53 | ["machine_actions", "device_actions", "region_controller_actions", | 53 | ["machine_actions", "device_actions", "region_controller_actions", |
575 | 54 | "rack_controller_actions", "region_and_rack_controller_actions", | 54 | "rack_controller_actions", "region_and_rack_controller_actions", |
576 | 55 | "architectures", "known_architectures", "pockets_to_disable", | 55 | "architectures", "known_architectures", "pockets_to_disable", |
580 | 56 | "hwe_kernels", "min_hwe_kernels", "default_min_hwe_kernel", | 56 | "components_to_disable", "hwe_kernels", "min_hwe_kernels", |
581 | 57 | "osinfo", "bond_options", "version", "power_types", | 57 | "default_min_hwe_kernel", "osinfo", "bond_options", |
582 | 58 | "release_options"]); | 58 | "version", "power_types", "release_options"]); |
583 | 59 | }); | 59 | }); |
584 | 60 | 60 | ||
585 | 61 | it("_data.machine_actions has correct data", function() { | 61 | it("_data.machine_actions has correct data", function() { |
586 | @@ -136,6 +136,15 @@ | |||
587 | 136 | expect(ptd.nextPromise).toBeNull(); | 136 | expect(ptd.nextPromise).toBeNull(); |
588 | 137 | }); | 137 | }); |
589 | 138 | 138 | ||
590 | 139 | it("_data.components_to_disable has correct data", function() { | ||
591 | 140 | var ptd = GeneralManager._data.components_to_disable; | ||
592 | 141 | expect(ptd.method).toBe("general.components_to_disable"); | ||
593 | 142 | expect(ptd.data).toEqual([]); | ||
594 | 143 | expect(ptd.loaded).toBe(false); | ||
595 | 144 | expect(ptd.polling).toBe(false); | ||
596 | 145 | expect(ptd.nextPromise).toBeNull(); | ||
597 | 146 | }); | ||
598 | 147 | |||
599 | 139 | it("_data.hwe_kernels has correct data", function() { | 148 | it("_data.hwe_kernels has correct data", function() { |
600 | 140 | var hwe_kernels = GeneralManager._data.hwe_kernels; | 149 | var hwe_kernels = GeneralManager._data.hwe_kernels; |
601 | 141 | expect(hwe_kernels.method).toBe("general.hwe_kernels"); | 150 | expect(hwe_kernels.method).toBe("general.hwe_kernels"); |
602 | @@ -302,6 +311,7 @@ | |||
603 | 302 | GeneralManager._data.architectures.loaded = true; | 311 | GeneralManager._data.architectures.loaded = true; |
604 | 303 | GeneralManager._data.known_architectures.loaded = true; | 312 | GeneralManager._data.known_architectures.loaded = true; |
605 | 304 | GeneralManager._data.pockets_to_disable.loaded = true; | 313 | GeneralManager._data.pockets_to_disable.loaded = true; |
606 | 314 | GeneralManager._data.components_to_disable.loaded = true; | ||
607 | 305 | GeneralManager._data.hwe_kernels.loaded = true; | 315 | GeneralManager._data.hwe_kernels.loaded = true; |
608 | 306 | GeneralManager._data.osinfo.loaded = true; | 316 | GeneralManager._data.osinfo.loaded = true; |
609 | 307 | GeneralManager._data.bond_options.loaded = true; | 317 | GeneralManager._data.bond_options.loaded = true; |
610 | @@ -321,6 +331,7 @@ | |||
611 | 321 | GeneralManager._data.architectures.loaded = true; | 331 | GeneralManager._data.architectures.loaded = true; |
612 | 322 | GeneralManager._data.known_architectures.loaded = true; | 332 | GeneralManager._data.known_architectures.loaded = true; |
613 | 323 | GeneralManager._data.pockets_to_disable.loaded = true; | 333 | GeneralManager._data.pockets_to_disable.loaded = true; |
614 | 334 | GeneralManager._data.components_to_disable.loaded = true; | ||
615 | 324 | GeneralManager._data.hwe_kernels.loaded = true; | 335 | GeneralManager._data.hwe_kernels.loaded = true; |
616 | 325 | GeneralManager._data.min_hwe_kernels.loaded = true; | 336 | GeneralManager._data.min_hwe_kernels.loaded = true; |
617 | 326 | GeneralManager._data.default_min_hwe_kernel.loaded = true; | 337 | GeneralManager._data.default_min_hwe_kernel.loaded = true; |
618 | @@ -353,6 +364,7 @@ | |||
619 | 353 | GeneralManager._data.architectures.polling = false; | 364 | GeneralManager._data.architectures.polling = false; |
620 | 354 | GeneralManager._data.known_architectures.polling = false; | 365 | GeneralManager._data.known_architectures.polling = false; |
621 | 355 | GeneralManager._data.pockets_to_disable.polling = false; | 366 | GeneralManager._data.pockets_to_disable.polling = false; |
622 | 367 | GeneralManager._data.components_to_disable.polling = false; | ||
623 | 356 | GeneralManager._data.hwe_kernels.polling = false; | 368 | GeneralManager._data.hwe_kernels.polling = false; |
624 | 357 | GeneralManager._data.osinfo.polling = false; | 369 | GeneralManager._data.osinfo.polling = false; |
625 | 358 | expect(GeneralManager.isPolling()).toBe(true); | 370 | expect(GeneralManager.isPolling()).toBe(true); |
626 | @@ -363,6 +375,7 @@ | |||
627 | 363 | GeneralManager._data.architectures.polling = true; | 375 | GeneralManager._data.architectures.polling = true; |
628 | 364 | GeneralManager._data.known_architectures.polling = true; | 376 | GeneralManager._data.known_architectures.polling = true; |
629 | 365 | GeneralManager._data.pockets_to_disable.polling = true; | 377 | GeneralManager._data.pockets_to_disable.polling = true; |
630 | 378 | GeneralManager._data.components_to_disable.polling = true; | ||
631 | 366 | GeneralManager._data.hwe_kernels.polling = true; | 379 | GeneralManager._data.hwe_kernels.polling = true; |
632 | 367 | GeneralManager._data.osinfo.polling = true; | 380 | GeneralManager._data.osinfo.polling = true; |
633 | 368 | expect(GeneralManager.isPolling()).toBe(true); | 381 | expect(GeneralManager.isPolling()).toBe(true); |
634 | 369 | 382 | ||
635 | === modified file 'src/maasserver/static/partials/settings.html' | |||
636 | --- src/maasserver/static/partials/settings.html 2017-02-17 14:23:04 +0000 | |||
637 | +++ src/maasserver/static/partials/settings.html 2017-03-16 22:02:44 +0000 | |||
638 | @@ -488,6 +488,11 @@ | |||
639 | 488 | <maas-obj-field type="checkboxes" key="disabled_pockets" label="Disabled Pockets" | 488 | <maas-obj-field type="checkboxes" key="disabled_pockets" label="Disabled Pockets" |
640 | 489 | label-width="two" input-width="three" values="pockets_to_disable"></maas-obj-field> | 489 | label-width="two" input-width="three" values="pockets_to_disable"></maas-obj-field> |
641 | 490 | </div> | 490 | </div> |
642 | 491 | <div class="form__group u-align--left-mobile" | ||
643 | 492 | data-ng-if="isMirror(editRepository) && !isPPA(editRepository)"> | ||
644 | 493 | <maas-obj-field type="checkboxes" key="disabled_components" label="Disabled Components" | ||
645 | 494 | label-width="two" input-width="three" values="components_to_disable"></maas-obj-field> | ||
646 | 495 | </div> | ||
647 | 491 | </div> | 496 | </div> |
648 | 492 | </div> | 497 | </div> |
649 | 493 | <div class="table__row is-active"> | 498 | <div class="table__row is-active"> |
650 | 494 | 499 | ||
651 | === modified file 'src/maasserver/testing/factory.py' | |||
652 | --- src/maasserver/testing/factory.py 2017-03-15 16:40:59 +0000 | |||
653 | +++ src/maasserver/testing/factory.py 2017-03-16 22:02:44 +0000 | |||
654 | @@ -2037,7 +2037,8 @@ | |||
655 | 2037 | 2037 | ||
656 | 2038 | def make_PackageRepository( | 2038 | def make_PackageRepository( |
657 | 2039 | self, name=None, url=None, arches=None, default=False, key=None, | 2039 | self, name=None, url=None, arches=None, default=False, key=None, |
659 | 2040 | distributions=None, components=None, disabled_pockets=None): | 2040 | distributions=None, components=None, disabled_pockets=None, |
660 | 2041 | disabled_components=None): | ||
661 | 2041 | if name is None: | 2042 | if name is None: |
662 | 2042 | name = self.make_name("name") | 2043 | name = self.make_name("name") |
663 | 2043 | if url is None: | 2044 | if url is None: |
664 | @@ -2051,7 +2052,8 @@ | |||
665 | 2051 | return PackageRepository.objects.create( | 2052 | return PackageRepository.objects.create( |
666 | 2052 | name=name, url=url, | 2053 | name=name, url=url, |
667 | 2053 | distributions=distributions, disabled_pockets=disabled_pockets, | 2054 | distributions=distributions, disabled_pockets=disabled_pockets, |
669 | 2054 | components=components, arches=arches, key=key, default=default) | 2055 | components=components, arches=arches, key=key, default=default, |
670 | 2056 | disabled_components=disabled_components) | ||
671 | 2055 | 2057 | ||
672 | 2056 | def make_Notification( | 2058 | def make_Notification( |
673 | 2057 | self, message=None, *, ident=None, user=None, users=False, | 2059 | self, message=None, *, ident=None, user=None, users=False, |
674 | 2058 | 2060 | ||
675 | === modified file 'src/maasserver/tests/test_preseed.py' | |||
676 | --- src/maasserver/tests/test_preseed.py 2017-03-09 08:55:12 +0000 | |||
677 | +++ src/maasserver/tests/test_preseed.py 2017-03-16 22:02:44 +0000 | |||
678 | @@ -1230,6 +1230,31 @@ | |||
679 | 1230 | preseed['apt']['disable_suites'], | 1230 | preseed['apt']['disable_suites'], |
680 | 1231 | archive.disabled_pockets) | 1231 | archive.disabled_pockets) |
681 | 1232 | 1232 | ||
682 | 1233 | def test_compose_curtin_archive_config_with_disabled_pockets(self): | ||
683 | 1234 | """Test that main archive has a configuration that includes | ||
684 | 1235 | disabled_pockets. If so, MAAS will create its own sources_list | ||
685 | 1236 | instead of letting curtin/cloud-init create it based on its own | ||
686 | 1237 | template""" | ||
687 | 1238 | PackageRepository.objects.all().delete() | ||
688 | 1239 | node = self.make_fastpath_node('amd64') | ||
689 | 1240 | node.osystem = 'ubuntu' | ||
690 | 1241 | node.distro_series = 'xenial' | ||
691 | 1242 | main_url = 'http://us.archive.ubuntu.com/ubuntu' | ||
692 | 1243 | factory.make_PackageRepository( | ||
693 | 1244 | url=main_url, default=True, arches=['i386', 'amd64'], | ||
694 | 1245 | disabled_pockets=['updates', 'backports'], | ||
695 | 1246 | disabled_components=['universe', 'multiverse']) | ||
696 | 1247 | self.configure_get_boot_images_for_node(node, 'xinstall') | ||
697 | 1248 | # compose_curtin_archive_config returns a list. | ||
698 | 1249 | userdata = compose_curtin_archive_config(node) | ||
699 | 1250 | preseed = yaml.safe_load(userdata[0]) | ||
700 | 1251 | self.assertThat( | ||
701 | 1252 | preseed['apt']['sources_list'], | ||
702 | 1253 | Contains('$RELEASE main restricted')) | ||
703 | 1254 | self.assertThat( | ||
704 | 1255 | preseed['apt']['sources_list'], | ||
705 | 1256 | Contains('$RELEASE-security main restricted')) | ||
706 | 1257 | |||
707 | 1233 | def test_compose_curtin_archive_config_has_ppa(self): | 1258 | def test_compose_curtin_archive_config_has_ppa(self): |
708 | 1234 | node = self.make_fastpath_node('i386') | 1259 | node = self.make_fastpath_node('i386') |
709 | 1235 | node.osystem = 'ubuntu' | 1260 | node.osystem = 'ubuntu' |
710 | @@ -1283,7 +1308,7 @@ | |||
711 | 1283 | ) | 1308 | ) |
712 | 1284 | self.assertThat( | 1309 | self.assertThat( |
713 | 1285 | preseed['apt']['sources'][ppa_name]['source'], | 1310 | preseed['apt']['sources'][ppa_name]['source'], |
715 | 1286 | ContainsAll("deb %s %s main" % (ppa_first.url, node.distro_series)) | 1311 | ContainsAll("deb %s $RELEASE main" % ppa_first.url) |
716 | 1287 | ) | 1312 | ) |
717 | 1288 | # Clean up PPA name | 1313 | # Clean up PPA name |
718 | 1289 | ppa_name = make_clean_repo_name(ppa_second) | 1314 | ppa_name = make_clean_repo_name(ppa_second) |
719 | @@ -1293,8 +1318,7 @@ | |||
720 | 1293 | ) | 1318 | ) |
721 | 1294 | self.assertThat( | 1319 | self.assertThat( |
722 | 1295 | preseed['apt']['sources'][ppa_name]['source'], | 1320 | preseed['apt']['sources'][ppa_name]['source'], |
725 | 1296 | ContainsAll("deb %s %s main" % ( | 1321 | ContainsAll("deb %s $RELEASE main" % ppa_second.url)) |
724 | 1297 | ppa_second.url, node.distro_series))) | ||
726 | 1298 | 1322 | ||
727 | 1299 | def test_compose_curtin_archive_config_has_custom_repository(self): | 1323 | def test_compose_curtin_archive_config_has_custom_repository(self): |
728 | 1300 | node = self.make_fastpath_node('i386') | 1324 | node = self.make_fastpath_node('i386') |
729 | @@ -1318,8 +1342,7 @@ | |||
730 | 1318 | ) | 1342 | ) |
731 | 1319 | self.assertThat( | 1343 | self.assertThat( |
732 | 1320 | preseed['apt']['sources'][repo_name]['source'], | 1344 | preseed['apt']['sources'][repo_name]['source'], |
735 | 1321 | ContainsAll("deb %s %s main" % ( | 1345 | ContainsAll("deb %s $RELEASE main" % repository.url)) |
734 | 1322 | repository.url, node.distro_series))) | ||
736 | 1323 | 1346 | ||
737 | 1324 | def test_compose_curtin_archive_config_custom_repo_with_components(self): | 1347 | def test_compose_curtin_archive_config_custom_repo_with_components(self): |
738 | 1325 | node = self.make_fastpath_node('i386') | 1348 | node = self.make_fastpath_node('i386') |
739 | @@ -1348,8 +1371,8 @@ | |||
740 | 1348 | ) | 1371 | ) |
741 | 1349 | self.assertThat( | 1372 | self.assertThat( |
742 | 1350 | preseed['apt']['sources'][repo_name]['source'], | 1373 | preseed['apt']['sources'][repo_name]['source'], |
745 | 1351 | ContainsAll("deb %s %s %s" % ( | 1374 | ContainsAll("deb %s $RELEASE %s" % ( |
746 | 1352 | repository.url, node.distro_series, components))) | 1375 | repository.url, components))) |
747 | 1353 | 1376 | ||
748 | 1354 | def test_compose_curtin_archive_config_custom_repo_components_dists(self): | 1377 | def test_compose_curtin_archive_config_custom_repo_components_dists(self): |
749 | 1355 | node = self.make_fastpath_node('i386') | 1378 | node = self.make_fastpath_node('i386') |
750 | 1356 | 1379 | ||
751 | === modified file 'src/maasserver/websockets/handlers/general.py' | |||
752 | --- src/maasserver/websockets/handlers/general.py 2017-01-28 00:51:47 +0000 | |||
753 | +++ src/maasserver/websockets/handlers/general.py 2017-03-16 22:02:44 +0000 | |||
754 | @@ -46,6 +46,7 @@ | |||
755 | 46 | 'architectures', | 46 | 'architectures', |
756 | 47 | 'known_architectures', | 47 | 'known_architectures', |
757 | 48 | 'pockets_to_disable', | 48 | 'pockets_to_disable', |
758 | 49 | 'components_to_disable', | ||
759 | 49 | 'hwe_kernels', | 50 | 'hwe_kernels', |
760 | 50 | 'min_hwe_kernels', | 51 | 'min_hwe_kernels', |
761 | 51 | 'default_min_hwe_kernel', | 52 | 'default_min_hwe_kernel', |
762 | @@ -74,6 +75,10 @@ | |||
763 | 74 | """Return pockets that can be disabled.""" | 75 | """Return pockets that can be disabled.""" |
764 | 75 | return PackageRepository.objects.get_pockets_to_disable() | 76 | return PackageRepository.objects.get_pockets_to_disable() |
765 | 76 | 77 | ||
766 | 78 | def components_to_disable(self, params): | ||
767 | 79 | "Return compoennts that can be disable for default Ubuntu archives" | ||
768 | 80 | return PackageRepository.objects.get_components_to_disable() | ||
769 | 81 | |||
770 | 77 | def hwe_kernels(self, params): | 82 | def hwe_kernels(self, params): |
771 | 78 | """Return all supported hwe_kernels.""" | 83 | """Return all supported hwe_kernels.""" |
772 | 79 | return list_hwe_kernel_choices( | 84 | return list_hwe_kernel_choices( |
773 | 80 | 85 | ||
774 | === modified file 'src/maasserver/websockets/handlers/tests/test_general.py' | |||
775 | --- src/maasserver/websockets/handlers/tests/test_general.py 2017-03-02 09:41:37 +0000 | |||
776 | +++ src/maasserver/websockets/handlers/tests/test_general.py 2017-03-16 22:02:44 +0000 | |||
777 | @@ -103,6 +103,12 @@ | |||
778 | 103 | PackageRepository.objects.get_pockets_to_disable(), | 103 | PackageRepository.objects.get_pockets_to_disable(), |
779 | 104 | handler.pockets_to_disable({})) | 104 | handler.pockets_to_disable({})) |
780 | 105 | 105 | ||
781 | 106 | def test_components_to_disable(self): | ||
782 | 107 | handler = GeneralHandler(factory.make_User(), {}) | ||
783 | 108 | self.assertEqual( | ||
784 | 109 | PackageRepository.objects.get_components_to_disable(), | ||
785 | 110 | handler.components_to_disable({})) | ||
786 | 111 | |||
787 | 106 | def test_hwe_kernels(self): | 112 | def test_hwe_kernels(self): |
788 | 107 | expected_output = self.make_boot_sources() | 113 | expected_output = self.make_boot_sources() |
789 | 108 | handler = GeneralHandler(factory.make_User(), {}) | 114 | handler = GeneralHandler(factory.make_User(), {}) |
790 | 109 | 115 | ||
791 | === modified file 'src/maasserver/websockets/handlers/tests/test_packagerepository.py' | |||
792 | --- src/maasserver/websockets/handlers/tests/test_packagerepository.py 2017-02-17 14:23:04 +0000 | |||
793 | +++ src/maasserver/websockets/handlers/tests/test_packagerepository.py 2017-03-16 22:02:44 +0000 | |||
794 | @@ -34,6 +34,7 @@ | |||
795 | 34 | 'url': package_repository.url, | 34 | 'url': package_repository.url, |
796 | 35 | 'distributions': package_repository.distributions, | 35 | 'distributions': package_repository.distributions, |
797 | 36 | 'disabled_pockets': package_repository.disabled_pockets, | 36 | 'disabled_pockets': package_repository.disabled_pockets, |
798 | 37 | 'disabled_components': package_repository.disabled_components, | ||
799 | 37 | 'components': package_repository.components, | 38 | 'components': package_repository.components, |
800 | 38 | 'arches': package_repository.arches, | 39 | 'arches': package_repository.arches, |
801 | 39 | 'key': package_repository.key, | 40 | 'key': package_repository.key, |