Merge ~ltrager/maas:lp1701694 into maas:master

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: 25239e803f86997e504f0b8f76395cbb1c117a41
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ltrager/maas:lp1701694
Merge into: maas:master
Diff against target: 645 lines (+142/-135)
24 files modified
src/maasserver/bootresources.py (+3/-3)
src/maasserver/forms/__init__.py (+11/-13)
src/maasserver/forms/tests/test_bootresource.py (+45/-2)
src/maasserver/models/bootresource.py (+12/-3)
src/maasserver/models/tests/test_bootresource.py (+21/-0)
src/maasserver/tests/test_bootresources.py (+3/-3)
src/maasserver/utils/osystems.py (+3/-4)
src/maasserver/utils/tests/test_osystems.py (+16/-0)
src/provisioningserver/drivers/osystem/__init__.py (+5/-4)
src/provisioningserver/drivers/osystem/bootloader.py (+0/-4)
src/provisioningserver/drivers/osystem/centos.py (+0/-4)
src/provisioningserver/drivers/osystem/custom.py (+0/-5)
src/provisioningserver/drivers/osystem/rhel.py (+0/-4)
src/provisioningserver/drivers/osystem/tests/test_base.py (+10/-1)
src/provisioningserver/drivers/osystem/tests/test_bootloader.py (+0/-5)
src/provisioningserver/drivers/osystem/tests/test_centos.py (+0/-17)
src/provisioningserver/drivers/osystem/tests/test_custom.py (+0/-9)
src/provisioningserver/drivers/osystem/tests/test_rhel.py (+0/-17)
src/provisioningserver/drivers/osystem/tests/test_ubuntu.py (+11/-6)
src/provisioningserver/drivers/osystem/tests/test_ubuntucore.py (+0/-9)
src/provisioningserver/drivers/osystem/ubuntu.py (+1/-9)
src/provisioningserver/drivers/osystem/ubuntucore.py (+0/-5)
src/provisioningserver/drivers/osystem/windows.py (+1/-5)
src/provisioningserver/testing/os.py (+0/-3)
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+327482@code.launchpad.net

Commit message

Allow uploading images with the format osystem/release.

All images uploaded are now of rtype UPLOADED. Users can upload using the format osystem/release where osystem is a supported OS.

Fixes: LP: #1701694, #1361370

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

Looks good, thanks for the fix.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
~ltrager/maas:lp1701694 updated
25239e8... by Lee Trager

Merge branch 'lp1701694' of git+ssh://git.launchpad.net/~ltrager/maas into lp1701694

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/bootresources.py b/src/maasserver/bootresources.py
index fd7ede4..514d460 100644
--- a/src/maasserver/bootresources.py
+++ b/src/maasserver/bootresources.py
@@ -224,11 +224,11 @@ class SimpleStreamsHandler:
224 def get_boot_resource_identifiers(self, resource):224 def get_boot_resource_identifiers(self, resource):
225 """Return tuple (os, arch, subarch, series) for the given resource."""225 """Return tuple (os, arch, subarch, series) for the given resource."""
226 arch, subarch = resource.split_arch()226 arch, subarch = resource.split_arch()
227 if resource.rtype == BOOT_RESOURCE_TYPE.UPLOADED:227 if '/' in resource.name:
228 os, series = resource.name.split('/')
229 else:
228 os = 'custom'230 os = 'custom'
229 series = resource.name231 series = resource.name
230 else:
231 os, series = resource.name.split('/')
232 return (os, arch, subarch, series)232 return (os, arch, subarch, series)
233233
234 def get_product_name(self, resource):234 def get_product_name(self, resource):
diff --git a/src/maasserver/forms/__init__.py b/src/maasserver/forms/__init__.py
index b58b65a..a7314d0 100644
--- a/src/maasserver/forms/__init__.py
+++ b/src/maasserver/forms/__init__.py
@@ -2283,11 +2283,19 @@ class BootResourceForm(MAASModelForm):
2283 If the passed resource already has a match in the database then that2283 If the passed resource already has a match in the database then that
2284 resource is returned. If not then the passed resource is returned.2284 resource is returned. If not then the passed resource is returned.
2285 """2285 """
2286 if resource.rtype == BOOT_RESOURCE_TYPE.UPLOADED:
2287 # Uploaded BootResources were previously generated, now they're
2288 # uploaded. Search for both to convert.
2289 rtypes = [
2290 BOOT_RESOURCE_TYPE.UPLOADED, BOOT_RESOURCE_TYPE.GENERATED]
2291 else:
2292 rtypes = [resource.type]
2286 existing_resource = get_one(2293 existing_resource = get_one(
2287 BootResource.objects.filter(2294 BootResource.objects.filter(
2288 rtype=resource.rtype,2295 rtype__in=rtypes,
2289 name=resource.name, architecture=resource.architecture))2296 name=resource.name, architecture=resource.architecture))
2290 if existing_resource is not None:2297 if existing_resource is not None:
2298 existing_resource.rtype = resource.rtype
2291 return existing_resource2299 return existing_resource
2292 return resource2300 return resource
22932301
@@ -2335,24 +2343,14 @@ class BootResourceForm(MAASModelForm):
2335 This implementation of `save` does not support the `commit` argument.2343 This implementation of `save` does not support the `commit` argument.
2336 """2344 """
2337 resource = super(BootResourceForm, self).save(commit=False)2345 resource = super(BootResourceForm, self).save(commit=False)
23382346 resource.rtype = BOOT_RESOURCE_TYPE.UPLOADED
2339 # XXX blake_r 2014-09-22 bug=1361370: Temporarily support the ability
2340 # to upload a generated image. This should only exist while CentOS and
2341 # Windows images need to be uploaded, rather than synced or generated.
2342 if '/' not in resource.name:
2343 label = 'uploaded'
2344 resource.rtype = BOOT_RESOURCE_TYPE.UPLOADED
2345 else:
2346 label = 'generated'
2347 resource.rtype = BOOT_RESOURCE_TYPE.GENERATED
2348
2349 resource = self.get_existing_resource(resource)2347 resource = self.get_existing_resource(resource)
2350 resource.extra = {'subarches': resource.architecture.split('/')[1]}2348 resource.extra = {'subarches': resource.architecture.split('/')[1]}
2351 if 'title' in self.cleaned_data:2349 if 'title' in self.cleaned_data:
2352 resource.extra['title'] = self.cleaned_data['title']2350 resource.extra['title'] = self.cleaned_data['title']
23532351
2354 resource.save()2352 resource.save()
2355 resource_set = self.create_resource_set(resource, label)2353 resource_set = self.create_resource_set(resource, 'uploaded')
2356 self.create_resource_file(2354 self.create_resource_file(
2357 resource_set, self.cleaned_data)2355 resource_set, self.cleaned_data)
2358 return resource2356 return resource
diff --git a/src/maasserver/forms/tests/test_bootresource.py b/src/maasserver/forms/tests/test_bootresource.py
index d9f3c5d..c03792b 100644
--- a/src/maasserver/forms/tests/test_bootresource.py
+++ b/src/maasserver/forms/tests/test_bootresource.py
@@ -9,6 +9,7 @@ import random
99
10from django.core.files.uploadedfile import SimpleUploadedFile10from django.core.files.uploadedfile import SimpleUploadedFile
11from maasserver import forms as forms_module11from maasserver import forms as forms_module
12from maasserver.clusterrpc import osystems
12from maasserver.enum import (13from maasserver.enum import (
13 BOOT_RESOURCE_FILE_TYPE,14 BOOT_RESOURCE_FILE_TYPE,
14 BOOT_RESOURCE_TYPE,15 BOOT_RESOURCE_TYPE,
@@ -189,8 +190,11 @@ class TestBootResourceForm(MAASServerTestCase):
189 written_content = stream.read()190 written_content = stream.read()
190 self.assertEqual(content, written_content)191 self.assertEqual(content, written_content)
191192
192 def test_creates_boot_resoures_with_generated_rtype(self):193 def test_creates_boot_resoures_with_uploaded_rtype(self):
193 os = factory.make_name('os')194 os = factory.make_name('os')
195 self.patch(
196 osystems, 'gen_all_known_operating_systems').return_value = [
197 {'name': os}]
194 series = factory.make_name('series')198 series = factory.make_name('series')
195 name = '%s/%s' % (os, series)199 name = '%s/%s' % (os, series)
196 architecture = make_usable_architecture(self)200 architecture = make_usable_architecture(self)
@@ -208,7 +212,7 @@ class TestBootResourceForm(MAASServerTestCase):
208 self.assertTrue(form.is_valid(), form._errors)212 self.assertTrue(form.is_valid(), form._errors)
209 form.save()213 form.save()
210 resource = BootResource.objects.get(214 resource = BootResource.objects.get(
211 rtype=BOOT_RESOURCE_TYPE.GENERATED,215 rtype=BOOT_RESOURCE_TYPE.UPLOADED,
212 name=name, architecture=architecture)216 name=name, architecture=architecture)
213 resource_set = resource.sets.first()217 resource_set = resource.sets.first()
214 rfile = resource_set.files.first()218 rfile = resource_set.files.first()
@@ -221,6 +225,9 @@ class TestBootResourceForm(MAASServerTestCase):
221225
222 def test_adds_boot_resource_set_to_existing_generated_boot_resource(self):226 def test_adds_boot_resource_set_to_existing_generated_boot_resource(self):
223 os = factory.make_name('os')227 os = factory.make_name('os')
228 self.patch(
229 osystems, 'gen_all_known_operating_systems').return_value = [
230 {'name': os}]
224 series = factory.make_name('series')231 series = factory.make_name('series')
225 name = '%s/%s' % (os, series)232 name = '%s/%s' % (os, series)
226 architecture = make_usable_architecture(self)233 architecture = make_usable_architecture(self)
@@ -249,6 +256,42 @@ class TestBootResourceForm(MAASServerTestCase):
249 with rfile.largefile.content.open('rb') as stream:256 with rfile.largefile.content.open('rb') as stream:
250 written_content = stream.read()257 written_content = stream.read()
251 self.assertEqual(content, written_content)258 self.assertEqual(content, written_content)
259 self.assertEqual(resource.rtype, BOOT_RESOURCE_TYPE.UPLOADED)
260
261 def test_adds_boot_resource_set_to_existing_uploaded_boot_resource(self):
262 os = factory.make_name('os')
263 self.patch(
264 osystems, 'gen_all_known_operating_systems').return_value = [
265 {'name': os}]
266 series = factory.make_name('series')
267 name = '%s/%s' % (os, series)
268 architecture = make_usable_architecture(self)
269 resource = factory.make_usable_boot_resource(
270 rtype=BOOT_RESOURCE_TYPE.UPLOADED,
271 name=name, architecture=architecture)
272 upload_type, filetype = self.pick_filetype()
273 size = random.randint(1024, 2048)
274 content = factory.make_string(size).encode('utf-8')
275 upload_name = factory.make_name('filename')
276 uploaded_file = SimpleUploadedFile(content=content, name=upload_name)
277 data = {
278 'name': name,
279 'architecture': architecture,
280 'filetype': upload_type,
281 }
282 form = BootResourceForm(data=data, files={'content': uploaded_file})
283 self.assertTrue(form.is_valid(), form._errors)
284 form.save()
285 resource = reload_object(resource)
286 resource_set = resource.sets.order_by('id').last()
287 rfile = resource_set.files.first()
288 self.assertTrue(filetype, rfile.filetype)
289 self.assertTrue(filetype, rfile.filename)
290 self.assertTrue(size, rfile.largefile.total_size)
291 with rfile.largefile.content.open('rb') as stream:
292 written_content = stream.read()
293 self.assertEqual(content, written_content)
294 self.assertEqual(resource.rtype, BOOT_RESOURCE_TYPE.UPLOADED)
252295
253 def test_requires_fields(self):296 def test_requires_fields(self):
254 form = BootResourceForm(data={})297 form = BootResourceForm(data={})
diff --git a/src/maasserver/models/bootresource.py b/src/maasserver/models/bootresource.py
index 905e675..5af3eee 100644
--- a/src/maasserver/models/bootresource.py
+++ b/src/maasserver/models/bootresource.py
@@ -187,6 +187,7 @@ class BootResourceManager(Manager):
187 rtypes = [187 rtypes = [
188 BOOT_RESOURCE_TYPE.SYNCED,188 BOOT_RESOURCE_TYPE.SYNCED,
189 BOOT_RESOURCE_TYPE.GENERATED,189 BOOT_RESOURCE_TYPE.GENERATED,
190 BOOT_RESOURCE_TYPE.UPLOADED,
190 ]191 ]
191 name = '%s/%s' % (image['osystem'], image['release'])192 name = '%s/%s' % (image['osystem'], image['release'])
192 else:193 else:
@@ -442,9 +443,17 @@ class BootResource(CleanSave, TimestampedModel):
442 """443 """
443 if self.rtype == BOOT_RESOURCE_TYPE.UPLOADED:444 if self.rtype == BOOT_RESOURCE_TYPE.UPLOADED:
444 if '/' in self.name:445 if '/' in self.name:
445 raise ValidationError(446 # Avoid circular dependency
446 "%s boot resource cannot contain a '/' in it's name." % (447 from maasserver.clusterrpc.osystems import (
447 self.display_rtype))448 gen_all_known_operating_systems,
449 )
450 osystem = self.name.split('/')[0]
451 if osystem not in {
452 i['name'] for i in gen_all_known_operating_systems()}:
453 raise ValidationError(
454 "%s boot resource cannot contain a '/' in it's name "
455 "unless it starts with a supported operating system."
456 % (self.display_rtype))
448 elif self.rtype in RTYPE_REQUIRING_OS_SERIES_NAME:457 elif self.rtype in RTYPE_REQUIRING_OS_SERIES_NAME:
449 if '/' not in self.name:458 if '/' not in self.name:
450 raise ValidationError(459 raise ValidationError(
diff --git a/src/maasserver/models/tests/test_bootresource.py b/src/maasserver/models/tests/test_bootresource.py
index 2efb4fc..59c3ac2 100644
--- a/src/maasserver/models/tests/test_bootresource.py
+++ b/src/maasserver/models/tests/test_bootresource.py
@@ -10,6 +10,7 @@ from datetime import datetime
10import random10import random
1111
12from django.core.exceptions import ValidationError12from django.core.exceptions import ValidationError
13from maasserver.clusterrpc import osystems
13from maasserver.clusterrpc.testing.boot_images import make_rpc_boot_image14from maasserver.clusterrpc.testing.boot_images import make_rpc_boot_image
14from maasserver.enum import (15from maasserver.enum import (
15 BOOT_RESOURCE_FILE_TYPE,16 BOOT_RESOURCE_FILE_TYPE,
@@ -771,6 +772,26 @@ class TestBootResource(MAASServerTestCase):
771 self.assertRaises(772 self.assertRaises(
772 ValidationError, resource.save)773 ValidationError, resource.save)
773774
775 def test_validation_allows_any_uploaded_name_slash_with_supported_os(self):
776 osystem = factory.make_name('osystem')
777 self.patch(
778 osystems, 'gen_all_known_operating_systems').return_value = [
779 {'name': osystem}]
780 name = '%s/%s' % (osystem, factory.make_name('release'))
781 arch = '%s/%s' % (
782 factory.make_name('arch'), factory.make_name('subarch'))
783 resource = BootResource(
784 rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=arch)
785 resource.save()
786
787 def test_validation_allows_any_uploaded_name_without_slash(self):
788 name = factory.make_name('name')
789 arch = '%s/%s' % (
790 factory.make_name('arch'), factory.make_name('subarch'))
791 resource = BootResource(
792 rtype=BOOT_RESOURCE_TYPE.UPLOADED, name=name, architecture=arch)
793 resource.save()
794
774 def test_create_raises_error_on_not_unique(self):795 def test_create_raises_error_on_not_unique(self):
775 name = '%s/%s' % (796 name = '%s/%s' % (
776 factory.make_name('os'), factory.make_name('series'))797 factory.make_name('os'), factory.make_name('series'))
diff --git a/src/maasserver/tests/test_bootresources.py b/src/maasserver/tests/test_bootresources.py
index b3fd049..5047e03 100644
--- a/src/maasserver/tests/test_bootresources.py
+++ b/src/maasserver/tests/test_bootresources.py
@@ -200,11 +200,11 @@ class TestSimpleStreamsHandler(MAASServerTestCase):
200200
201 def get_product_name_for_resource(self, resource):201 def get_product_name_for_resource(self, resource):
202 arch, subarch = resource.architecture.split('/')202 arch, subarch = resource.architecture.split('/')
203 if resource.rtype == BOOT_RESOURCE_TYPE.UPLOADED:203 if '/' in resource.name:
204 os, series = resource.name.split('/')
205 else:
204 os = 'custom'206 os = 'custom'
205 series = resource.name207 series = resource.name
206 else:
207 os, series = resource.name.split('/')
208 return 'maas:boot:%s:%s:%s:%s' % (os, arch, subarch, series)208 return 'maas:boot:%s:%s:%s:%s' % (os, arch, subarch, series)
209209
210 def make_usable_product_boot_resource(210 def make_usable_product_boot_resource(
diff --git a/src/maasserver/utils/osystems.py b/src/maasserver/utils/osystems.py
index 4a624f5..2746d46 100644
--- a/src/maasserver/utils/osystems.py
+++ b/src/maasserver/utils/osystems.py
@@ -25,7 +25,6 @@ from distro_info import UbuntuDistroInfo
25from django.core.exceptions import ValidationError25from django.core.exceptions import ValidationError
26from django.db.models import Q26from django.db.models import Q
27from maasserver.clusterrpc.osystems import gen_all_known_operating_systems27from maasserver.clusterrpc.osystems import gen_all_known_operating_systems
28from maasserver.enum import BOOT_RESOURCE_TYPE
29from maasserver.models import (28from maasserver.models import (
30 BootResource,29 BootResource,
31 BootSourceCache,30 BootSourceCache,
@@ -75,11 +74,11 @@ def list_all_usable_releases(osystems):
75 # When custom images are returned by list_all_usable_osystems74 # When custom images are returned by list_all_usable_osystems
76 # the osystem name is 'custom' and the release name to whatever75 # the osystem name is 'custom' and the release name to whatever
77 # the user specified.76 # the user specified.
78 if resource.rtype == BOOT_RESOURCE_TYPE.UPLOADED:77 if '/' in resource.name:
78 osystem, release = resource.name.split('/')
79 else:
79 osystem = 'custom'80 osystem = 'custom'
80 release = resource.name81 release = resource.name
81 else:
82 osystem, release = resource.name.split('/')
83 if osystem not in titles:82 if osystem not in titles:
84 titles[osystem] = {}83 titles[osystem] = {}
85 titles[osystem][release] = resource.extra['title']84 titles[osystem][release] = resource.extra['title']
diff --git a/src/maasserver/utils/tests/test_osystems.py b/src/maasserver/utils/tests/test_osystems.py
index bf8c2d5..8ee6b92 100644
--- a/src/maasserver/utils/tests/test_osystems.py
+++ b/src/maasserver/utils/tests/test_osystems.py
@@ -10,6 +10,7 @@ import random
1010
11from distro_info import UbuntuDistroInfo11from distro_info import UbuntuDistroInfo
12from django.core.exceptions import ValidationError12from django.core.exceptions import ValidationError
13from maasserver.clusterrpc import osystems
13from maasserver.clusterrpc.testing.osystems import (14from maasserver.clusterrpc.testing.osystems import (
14 make_rpc_osystem,15 make_rpc_osystem,
15 make_rpc_release,16 make_rpc_release,
@@ -154,6 +155,21 @@ class TestReleases(MAASServerTestCase):
154 title,155 title,
155 list_all_usable_releases([osystem])[osystem['name']][0]['title'])156 list_all_usable_releases([osystem])[osystem['name']][0]['title'])
156157
158 def test_list_all_usable_releases_finds_uploaded_with_osystem(self):
159 release = make_rpc_release()
160 osystem = make_rpc_osystem(releases=[release])
161 title = factory.make_name('title')
162 self.patch(
163 osystems, 'gen_all_known_operating_systems').return_value = [
164 {'name': osystem['name']}]
165 factory.make_BootResource(
166 rtype=BOOT_RESOURCE_TYPE.UPLOADED,
167 name='%s/%s' % (osystem['name'], release['name']),
168 extra={'title': title})
169 self.assertEquals(
170 title,
171 list_all_usable_releases([osystem])[osystem['name']][0]['title'])
172
157 def test_list_all_releases_requiring_keys(self):173 def test_list_all_releases_requiring_keys(self):
158 releases = [174 releases = [
159 make_rpc_release(requires_license_key=True) for _ in range(3)]175 make_rpc_release(requires_license_key=True) for _ in range(3)]
diff --git a/src/provisioningserver/drivers/osystem/__init__.py b/src/provisioningserver/drivers/osystem/__init__.py
index 2b049ff..ef754d8 100644
--- a/src/provisioningserver/drivers/osystem/__init__.py
+++ b/src/provisioningserver/drivers/osystem/__init__.py
@@ -67,10 +67,6 @@ class OperatingSystem(metaclass=ABCMeta):
67 """Title of the operating system."""67 """Title of the operating system."""
6868
69 @abstractmethod69 @abstractmethod
70 def is_release_supported(self, release):
71 """Return True when the release is supported, False otherwise."""
72
73 @abstractmethod
74 def get_default_release(self):70 def get_default_release(self):
75 """Return the default release to use when none is specified.71 """Return the default release to use when none is specified.
7672
@@ -96,6 +92,11 @@ class OperatingSystem(metaclass=ABCMeta):
96 :return: list of supported purposes92 :return: list of supported purposes
97 """93 """
9894
95 def is_release_supported(self, release):
96 """Return True when the release is supported, False otherwise."""
97 # If the osystem matches assume all releases are supported.
98 return True
99
99 def format_release_choices(self, releases):100 def format_release_choices(self, releases):
100 """Format the release choices that are presented to the user.101 """Format the release choices that are presented to the user.
101102
diff --git a/src/provisioningserver/drivers/osystem/bootloader.py b/src/provisioningserver/drivers/osystem/bootloader.py
index 6ada008..2811a82 100644
--- a/src/provisioningserver/drivers/osystem/bootloader.py
+++ b/src/provisioningserver/drivers/osystem/bootloader.py
@@ -18,10 +18,6 @@ class BootLoaderOS(OperatingSystem):
18 name = 'bootloader'18 name = 'bootloader'
19 title = 'Bootloader'19 title = 'Bootloader'
2020
21 def is_release_supported(self, release):
22 # All releases are supported, they're pulled from the Ubuntu archive.
23 return True
24
25 def get_default_release(self):21 def get_default_release(self):
26 # No Default bootloader as it depends on the arch.22 # No Default bootloader as it depends on the arch.
27 return ''23 return ''
diff --git a/src/provisioningserver/drivers/osystem/centos.py b/src/provisioningserver/drivers/osystem/centos.py
index 179fa0c..b9f2290 100644
--- a/src/provisioningserver/drivers/osystem/centos.py
+++ b/src/provisioningserver/drivers/osystem/centos.py
@@ -35,10 +35,6 @@ class CentOS(OperatingSystem):
35 BOOT_IMAGE_PURPOSE.XINSTALL35 BOOT_IMAGE_PURPOSE.XINSTALL
36 ]36 ]
3737
38 def is_release_supported(self, release):
39 matched = DISTRO_MATCHER.match(release)
40 return matched is not None
41
42 def get_default_release(self):38 def get_default_release(self):
43 """Gets the default release to use when a release is not39 """Gets the default release to use when a release is not
44 explicit."""40 explicit."""
diff --git a/src/provisioningserver/drivers/osystem/custom.py b/src/provisioningserver/drivers/osystem/custom.py
index 6e817e1..845c132 100644
--- a/src/provisioningserver/drivers/osystem/custom.py
+++ b/src/provisioningserver/drivers/osystem/custom.py
@@ -27,11 +27,6 @@ class CustomOS(OperatingSystem):
27 # Custom images can only be used with XINSTALL.27 # Custom images can only be used with XINSTALL.
28 return [BOOT_IMAGE_PURPOSE.XINSTALL]28 return [BOOT_IMAGE_PURPOSE.XINSTALL]
2929
30 def is_release_supported(self, release):
31 """Return True when the release is supported, False otherwise."""
32 # All release are supported, since the user uploaded it.
33 return True
34
35 def get_default_release(self):30 def get_default_release(self):
36 """Gets the default release to use when a release is not31 """Gets the default release to use when a release is not
37 explicit."""32 explicit."""
diff --git a/src/provisioningserver/drivers/osystem/rhel.py b/src/provisioningserver/drivers/osystem/rhel.py
index 553c880..5e63364 100644
--- a/src/provisioningserver/drivers/osystem/rhel.py
+++ b/src/provisioningserver/drivers/osystem/rhel.py
@@ -35,10 +35,6 @@ class RHELOS(OperatingSystem):
35 BOOT_IMAGE_PURPOSE.XINSTALL35 BOOT_IMAGE_PURPOSE.XINSTALL
36 ]36 ]
3737
38 def is_release_supported(self, release):
39 matched = DISTRO_MATCHER.match(release)
40 return matched is not None
41
42 def get_default_release(self):38 def get_default_release(self):
43 """Gets the default release to use when a release is not39 """Gets the default release to use when a release is not
44 explicit."""40 explicit."""
diff --git a/src/provisioningserver/drivers/osystem/tests/test_base.py b/src/provisioningserver/drivers/osystem/tests/test_base.py
index 9c41dc4..1fa9ca1 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_base.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_base.py
@@ -1,4 +1,4 @@
1# Copyright 2014-2016 Canonical Ltd. This software is licensed under the1# Copyright 2014-2017 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Tests for `provisioningserver.drivers.osystem`."""4"""Tests for `provisioningserver.drivers.osystem`."""
@@ -42,6 +42,15 @@ class TestOperatingSystem(MAASTestCase):
42 osystem_module, 'list_boot_images_for').return_value = images42 osystem_module, 'list_boot_images_for').return_value = images
43 return images43 return images
4444
45 def test_is_release_supported(self):
46 osystem = self.make_usable_osystem()
47 releases = [factory.make_name('release') for _ in range(3)]
48 supported = [
49 osystem.is_release_supported(release)
50 for release in releases
51 ]
52 self.assertEqual([True, True, True], supported)
53
45 def test_format_release_choices(self):54 def test_format_release_choices(self):
46 osystem = self.make_usable_osystem()55 osystem = self.make_usable_osystem()
47 releases = osystem.get_supported_releases()56 releases = osystem.get_supported_releases()
diff --git a/src/provisioningserver/drivers/osystem/tests/test_bootloader.py b/src/provisioningserver/drivers/osystem/tests/test_bootloader.py
index da0766e..9d89480 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_bootloader.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_bootloader.py
@@ -13,11 +13,6 @@ from provisioningserver.drivers.osystem.bootloader import BootLoaderOS
1313
14class TestCustomOS(MAASTestCase):14class TestCustomOS(MAASTestCase):
1515
16 def test_is_release_supported(self):
17 osystem = BootLoaderOS()
18 self.assertTrue(
19 osystem.is_release_supported(factory.make_name('release')))
20
21 def test_get_default_release(self):16 def test_get_default_release(self):
22 osystem = BootLoaderOS()17 osystem = BootLoaderOS()
23 self.assertEquals("", osystem.get_default_release())18 self.assertEquals("", osystem.get_default_release())
diff --git a/src/provisioningserver/drivers/osystem/tests/test_centos.py b/src/provisioningserver/drivers/osystem/tests/test_centos.py
index 207ea48..92f8be7 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_centos.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_centos.py
@@ -34,23 +34,6 @@ class TestCentOS(MAASTestCase):
34 BOOT_IMAGE_PURPOSE.XINSTALL,34 BOOT_IMAGE_PURPOSE.XINSTALL,
35 ])35 ])
3636
37 def test_is_release_supported(self):
38 name_supported = {
39 "centos6": True,
40 "centos65": True,
41 "centos7": True,
42 "centos71": True,
43 "cent65": False,
44 "centos711": True,
45 "centos-title": True,
46 "centos71.custom": True,
47 factory.make_name("name"): False,
48 }
49 osystem = CentOS()
50 for name, supported in name_supported.items():
51 self.expectThat(
52 osystem.is_release_supported(name), Equals(supported))
53
54 def test_get_default_release(self):37 def test_get_default_release(self):
55 osystem = CentOS()38 osystem = CentOS()
56 expected = osystem.get_default_release()39 expected = osystem.get_default_release()
diff --git a/src/provisioningserver/drivers/osystem/tests/test_custom.py b/src/provisioningserver/drivers/osystem/tests/test_custom.py
index 1b7ff8e..80a6cce 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_custom.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_custom.py
@@ -51,15 +51,6 @@ class TestCustomOS(MAASTestCase):
51 BOOT_IMAGE_PURPOSE.XINSTALL,51 BOOT_IMAGE_PURPOSE.XINSTALL,
52 ])52 ])
5353
54 def test_is_release_supported(self):
55 osystem = CustomOS()
56 releases = [factory.make_name('release') for _ in range(3)]
57 supported = [
58 osystem.is_release_supported(release)
59 for release in releases
60 ]
61 self.assertEqual([True, True, True], supported)
62
63 def test_get_default_release(self):54 def test_get_default_release(self):
64 osystem = CustomOS()55 osystem = CustomOS()
65 self.assertEqual("", osystem.get_default_release())56 self.assertEqual("", osystem.get_default_release())
diff --git a/src/provisioningserver/drivers/osystem/tests/test_rhel.py b/src/provisioningserver/drivers/osystem/tests/test_rhel.py
index 5c74417..4d85356 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_rhel.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_rhel.py
@@ -34,23 +34,6 @@ class TestRHEL(MAASTestCase):
34 BOOT_IMAGE_PURPOSE.XINSTALL,34 BOOT_IMAGE_PURPOSE.XINSTALL,
35 ])35 ])
3636
37 def test_is_release_supported(self):
38 name_supported = {
39 "rhel6": True,
40 "rhel65": True,
41 "rhel7": True,
42 "rhel71": True,
43 "cent65": False,
44 "rhel711": True,
45 "rhel-title": True,
46 "rhel71.custom": True,
47 factory.make_name("name"): False,
48 }
49 osystem = RHELOS()
50 for name, supported in name_supported.items():
51 self.expectThat(
52 osystem.is_release_supported(name), Equals(supported))
53
54 def test_get_default_release(self):37 def test_get_default_release(self):
55 osystem = RHELOS()38 osystem = RHELOS()
56 expected = osystem.get_default_release()39 expected = osystem.get_default_release()
diff --git a/src/provisioningserver/drivers/osystem/tests/test_ubuntu.py b/src/provisioningserver/drivers/osystem/tests/test_ubuntu.py
index d64faa9..f68f493 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_ubuntu.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_ubuntu.py
@@ -19,12 +19,7 @@ from provisioningserver.drivers.osystem.ubuntu import UbuntuOS
19class TestUbuntuOS(MAASTestCase):19class TestUbuntuOS(MAASTestCase):
2020
21 def get_lts_release(self):21 def get_lts_release(self):
22 # XXX ltrager 2016-04-06 - python3-distro-info won't set the latest lts22 return UbuntuDistroInfo().lts()
23 # to Xenial until its been released. So we can start testing MAAS 2.0
24 # with Xenial by default override it here. Once Xenial is released this
25 # can be removed
26 # return UbuntuDistroInfo().lts()
27 return "xenial"
2823
29 def get_release_title(self, release):24 def get_release_title(self, release):
30 info = UbuntuDistroInfo()25 info = UbuntuDistroInfo()
@@ -51,6 +46,16 @@ class TestUbuntuOS(MAASTestCase):
51 BOOT_IMAGE_PURPOSE.DISKLESS,46 BOOT_IMAGE_PURPOSE.DISKLESS,
52 ])47 ])
5348
49 def test_is_release_supported(self):
50 osystem = UbuntuOS()
51 info = UbuntuDistroInfo()
52 self.assertTrue(osystem.is_release_supported(random.choice(info.all)))
53
54 def test_get_lts_release(self):
55 # Canary so we know when the lts changes
56 osystem = UbuntuOS()
57 self.assertEquals('xenial', osystem.get_lts_release())
58
54 def test_get_default_release(self):59 def test_get_default_release(self):
55 osystem = UbuntuOS()60 osystem = UbuntuOS()
56 expected = osystem.get_default_release()61 expected = osystem.get_default_release()
diff --git a/src/provisioningserver/drivers/osystem/tests/test_ubuntucore.py b/src/provisioningserver/drivers/osystem/tests/test_ubuntucore.py
index 591a7bf..c01ee28 100644
--- a/src/provisioningserver/drivers/osystem/tests/test_ubuntucore.py
+++ b/src/provisioningserver/drivers/osystem/tests/test_ubuntucore.py
@@ -51,15 +51,6 @@ class TestUbuntuCoreOS(MAASTestCase):
51 BOOT_IMAGE_PURPOSE.XINSTALL,51 BOOT_IMAGE_PURPOSE.XINSTALL,
52 ])52 ])
5353
54 def test_is_release_supported(self):
55 osystem = UbuntuCoreOS()
56 releases = [factory.make_name('release') for _ in range(3)]
57 supported = [
58 osystem.is_release_supported(release)
59 for release in releases
60 ]
61 self.assertEqual([True, True, True], supported)
62
63 def test_get_default_release(self):54 def test_get_default_release(self):
64 osystem = UbuntuCoreOS()55 osystem = UbuntuCoreOS()
65 self.assertEqual("16", osystem.get_default_release())56 self.assertEqual("16", osystem.get_default_release())
diff --git a/src/provisioningserver/drivers/osystem/ubuntu.py b/src/provisioningserver/drivers/osystem/ubuntu.py
index 7490465..dd8d243 100644
--- a/src/provisioningserver/drivers/osystem/ubuntu.py
+++ b/src/provisioningserver/drivers/osystem/ubuntu.py
@@ -42,15 +42,7 @@ class UbuntuOS(OperatingSystem):
4242
43 def get_lts_release(self):43 def get_lts_release(self):
44 """Return the latest Ubuntu LTS release."""44 """Return the latest Ubuntu LTS release."""
45 lts_release = self.ubuntu_distro_info.lts()45 return self.ubuntu_distro_info.lts()
46 # XXX ltrager 2016-04-06 - python3-distro-info won't set the latest lts
47 # to Xenial until its been released. So we can start testing MAAS 2.0
48 # with Xenial by default override it here. Once Xenial is released this
49 # can be removed
50 if lts_release == "trusty":
51 return "xenial"
52 else:
53 return lts_release
5446
55 def get_default_release(self):47 def get_default_release(self):
56 """Gets the default release to use when a release is not48 """Gets the default release to use when a release is not
diff --git a/src/provisioningserver/drivers/osystem/ubuntucore.py b/src/provisioningserver/drivers/osystem/ubuntucore.py
index 0a1ea45..1830da6 100644
--- a/src/provisioningserver/drivers/osystem/ubuntucore.py
+++ b/src/provisioningserver/drivers/osystem/ubuntucore.py
@@ -27,11 +27,6 @@ class UbuntuCoreOS(OperatingSystem):
27 # Custom images can only be used with XINSTALL.27 # Custom images can only be used with XINSTALL.
28 return [BOOT_IMAGE_PURPOSE.XINSTALL]28 return [BOOT_IMAGE_PURPOSE.XINSTALL]
2929
30 def is_release_supported(self, release):
31 """Return True when the release is supported, False otherwise."""
32 # All release are supported, since the user uploaded it.
33 return True
34
35 def get_default_release(self):30 def get_default_release(self):
36 """Gets the default release to use when a release is not31 """Gets the default release to use when a release is not
37 explicit."""32 explicit."""
diff --git a/src/provisioningserver/drivers/osystem/windows.py b/src/provisioningserver/drivers/osystem/windows.py
index a3bc514..ad7391d 100644
--- a/src/provisioningserver/drivers/osystem/windows.py
+++ b/src/provisioningserver/drivers/osystem/windows.py
@@ -55,10 +55,6 @@ class WindowsOS(OperatingSystem):
55 purposes.append(BOOT_IMAGE_PURPOSE.INSTALL)55 purposes.append(BOOT_IMAGE_PURPOSE.INSTALL)
56 return purposes56 return purposes
5757
58 def is_release_supported(self, release):
59 """Return True when the release is supported, False otherwise."""
60 return release in WINDOWS_CHOICES
61
62 def get_default_release(self):58 def get_default_release(self):
63 """Gets the default release to use when a release is not59 """Gets the default release to use when a release is not
64 explicit."""60 explicit."""
@@ -66,7 +62,7 @@ class WindowsOS(OperatingSystem):
6662
67 def get_release_title(self, release):63 def get_release_title(self, release):
68 """Return the title for the given release."""64 """Return the title for the given release."""
69 return WINDOWS_CHOICES.get(release)65 return WINDOWS_CHOICES.get(release, release)
7066
71 def requires_license_key(self, release):67 def requires_license_key(self, release):
72 return release in REQUIRE_LICENSE_KEY68 return release in REQUIRE_LICENSE_KEY
diff --git a/src/provisioningserver/testing/os.py b/src/provisioningserver/testing/os.py
index 5dd7538..9bc5626 100644
--- a/src/provisioningserver/testing/os.py
+++ b/src/provisioningserver/testing/os.py
@@ -34,9 +34,6 @@ class FakeOS(OperatingSystem):
34 def get_boot_image_purposes(self, *args):34 def get_boot_image_purposes(self, *args):
35 return self.purpose35 return self.purpose
3636
37 def is_release_supported(self, release):
38 return release in self.fake_list
39
40 def get_supported_releases(self):37 def get_supported_releases(self):
41 return self.fake_list38 return self.fake_list
4239

Subscribers

People subscribed via source and target branches