Merge ~cgrabowski/maas:bootresource_form_validation_fix into maas:master

Proposed by Christian Grabowski
Status: Merged
Approved by: Christian Grabowski
Approved revision: 3512836c56ca532bdb6e73fc157b33f8fbadc232
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~cgrabowski/maas:bootresource_form_validation_fix
Merge into: maas:master
Diff against target: 178 lines (+80/-9)
4 files modified
src/maasserver/forms/__init__.py (+17/-4)
src/maasserver/forms/tests/test_bootresource.py (+40/-5)
src/maasserver/models/bootresource.py (+11/-0)
src/maasserver/models/tests/test_bootresource.py (+12/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Alexsander de Souza Approve
Review via email: mp+417702@code.launchpad.net

Commit message

allow arbitrary custom images default to using the commissioning OS for base_image

return commissioning OS as base image for older images without one

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bootresource_form_validation_fix lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/12203/console
COMMIT: 841263a5e802d4ceb2e64f99c2d1ed33d7d04cae

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bootresource_form_validation_fix lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/12204/console
COMMIT: c20bdadfdae3d100252f6f8d13a50044a58cc2a4

review: Needs Fixing
Revision history for this message
Alexsander de Souza (alexsander-souza) wrote :

+1

review: Approve
Revision history for this message
Christian Grabowski (cgrabowski) wrote :

jenkins: !tests

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bootresource_form_validation_fix lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/12207/console
COMMIT: c20bdadfdae3d100252f6f8d13a50044a58cc2a4

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bootresource_form_validation_fix lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/12209/console
COMMIT: a6f5f73ee484ac88b724068663898ee4890f97ea

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bootresource_form_validation_fix lp:~cgrabowski/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 3512836c56ca532bdb6e73fc157b33f8fbadc232

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/forms/__init__.py b/src/maasserver/forms/__init__.py
2index 8bb1aa3..fa8983d 100644
3--- a/src/maasserver/forms/__init__.py
4+++ b/src/maasserver/forms/__init__.py
5@@ -2511,7 +2511,7 @@ class BootResourceForm(MAASModelForm):
6 return name
7
8 def _get_base_image_info(self):
9- base_image = self.cleaned_data["base_image"]
10+ base_image = self.cleaned_data.get("base_image")
11 if not base_image:
12 existing_resource = super().save(commit=False)
13 existing_resource.name = self.cleaned_data["name"]
14@@ -2540,9 +2540,22 @@ class BootResourceForm(MAASModelForm):
15 try:
16 base_osystem, base_version = self._get_base_image_info()
17 except ValueError:
18- raise ValidationError(
19- "custom images require a valid base image name"
20- )
21+ if not self.data.get("base_image"):
22+ return "/".join(
23+ [
24+ val
25+ for val in Config.objects.get_configs(
26+ [
27+ "commissioning_osystem",
28+ "commissioning_distro_series",
29+ ]
30+ ).values()
31+ ]
32+ )
33+ else:
34+ raise ValidationError(
35+ "a base image must follow the format: <osystem>/<series>"
36+ )
37 else:
38 if base_osystem not in LINUX_OSYSTEMS:
39 raise ValidationError(
40diff --git a/src/maasserver/forms/tests/test_bootresource.py b/src/maasserver/forms/tests/test_bootresource.py
41index d43592a..4a3c51e 100644
42--- a/src/maasserver/forms/tests/test_bootresource.py
43+++ b/src/maasserver/forms/tests/test_bootresource.py
44@@ -10,7 +10,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
45
46 from maasserver.enum import BOOT_RESOURCE_FILE_TYPE, BOOT_RESOURCE_TYPE
47 from maasserver.forms import BootResourceForm
48-from maasserver.models import BootResource, BootResourceFile
49+from maasserver.models import BootResource, BootResourceFile, Config
50 from maasserver.models.signals import bootresourcefiles, bootsources
51 from maasserver.testing.architecture import make_usable_architecture
52 from maasserver.testing.factory import factory
53@@ -303,7 +303,7 @@ class TestBootResourceForm(MAASServerTestCase):
54 image = form.save()
55 self.assertEqual(image.base_image, data["base_image"])
56
57- def test_invalidates_nonexistent_custom_image_base_os(self):
58+ def test_uses_commissioning_os_for_nonexistent_custom_image_base_os(self):
59 name = "custom/%s" % factory.make_name("name")
60 upload_type, filetype = self.pick_filetype()
61 size = random.randint(1024, 2048)
62@@ -315,10 +315,17 @@ class TestBootResourceForm(MAASServerTestCase):
63 "title": factory.make_name("title"),
64 "architecture": make_usable_architecture(self),
65 "filetype": upload_type,
66- "base_image": factory.make_name("invalid"),
67+ "base_image": "",
68 }
69 form = BootResourceForm(data=data, files={"content": uploaded_file})
70- self.assertFalse(form.is_valid())
71+ form.save()
72+ cfg = Config.objects.get_configs(
73+ ["commissioning_osystem", "commissioning_distro_series"]
74+ )
75+ self.assertEqual(
76+ f"{cfg['commissioning_osystem']}/{cfg['commissioning_distro_series']}",
77+ form.instance.base_image,
78+ )
79
80 def test_invalidates_nonexistent_custom_image_base_os_no_prefix(self):
81 name = factory.make_name("name")
82@@ -485,7 +492,7 @@ class TestBootResourceForm(MAASServerTestCase):
83 form = BootResourceForm(data={})
84 self.assertFalse(form.is_valid(), form.errors)
85 self.assertEqual(
86- {"name", "architecture", "filetype", "content", "base_image"},
87+ {"name", "architecture", "filetype", "content"},
88 form.errors.keys(),
89 )
90
91@@ -522,3 +529,31 @@ class TestBootResourceForm(MAASServerTestCase):
92 resource_set__resource=resource
93 ).count(),
94 )
95+
96+ def test_clean_base_image_sets_commissioning_osystem_and_distro_series_where_none_is_given(
97+ self,
98+ ):
99+ architecture = make_usable_architecture(self)
100+ upload_type, filetype = self.pick_filetype()
101+ content = factory.make_string(1024).encode("utf-8")
102+ upload_name = factory.make_name("filename")
103+ uploaded_file = SimpleUploadedFile(content=content, name=upload_name)
104+ data = {
105+ "name": f"custom/{factory.make_name()}",
106+ "architecture": architecture,
107+ "filetype": upload_type,
108+ }
109+ form = BootResourceForm(data=data, files={"content": uploaded_file})
110+ form.save()
111+ cfg = Config.objects.get_configs(
112+ ["commissioning_osystem", "commissioning_distro_series"]
113+ )
114+ self.assertEqual(
115+ "/".join(
116+ [
117+ cfg["commissioning_osystem"],
118+ cfg["commissioning_distro_series"],
119+ ]
120+ ),
121+ form.instance.base_image,
122+ )
123diff --git a/src/maasserver/models/bootresource.py b/src/maasserver/models/bootresource.py
124index ee0479b..9389830 100644
125--- a/src/maasserver/models/bootresource.py
126+++ b/src/maasserver/models/bootresource.py
127@@ -27,6 +27,7 @@ from maasserver.fields import JSONObjectField
128 from maasserver.models.bootresourceset import BootResourceSet
129 from maasserver.models.bootsourcecache import BootSourceCache
130 from maasserver.models.cleansave import CleanSave
131+from maasserver.models.config import Config
132 from maasserver.models.timestampedmodel import now, TimestampedModel
133 from maasserver.utils.orm import get_first, get_one
134 from provisioningserver.drivers.osystem import OperatingSystemRegistry
135@@ -583,6 +584,16 @@ class BootResource(CleanSave, TimestampedModel):
136 return self.architecture.split("/")
137
138 def split_base_image(self):
139+ # handle older custom images that may not have a base image
140+ if not self.base_image:
141+ cfg = Config.objects.get_configs(
142+ ["commissioning_osystem", "commissioning_distro_series"]
143+ )
144+ return (
145+ cfg["commissioning_osystem"],
146+ cfg["commissioning_distro_series"],
147+ )
148+
149 return self.base_image.split("/")
150
151 def get_next_version_name(self):
152diff --git a/src/maasserver/models/tests/test_bootresource.py b/src/maasserver/models/tests/test_bootresource.py
153index 62f0145..d2a0b9e 100644
154--- a/src/maasserver/models/tests/test_bootresource.py
155+++ b/src/maasserver/models/tests/test_bootresource.py
156@@ -21,6 +21,7 @@ from maasserver.models.bootresource import (
157 BootResource,
158 RTYPE_REQUIRING_OS_SERIES_NAME,
159 )
160+from maasserver.models.config import Config
161 from maasserver.models.signals import bootsources
162 from maasserver.testing.factory import factory
163 from maasserver.testing.testcase import MAASServerTestCase
164@@ -1161,3 +1162,14 @@ class TestBootResource(MAASServerTestCase):
165 self.assertFalse(
166 resource.supports_subarch(factory.make_name("subarch"))
167 )
168+
169+ def test_split_base_image_handles_no_base_image(self):
170+ resource = factory.make_BootResource()
171+ resource.base_image = None
172+ cfg = Config.objects.get_configs(
173+ ["commissioning_osystem", "commissioning_distro_series"]
174+ )
175+ self.assertCountEqual(
176+ (cfg["commissioning_osystem"], cfg["commissioning_distro_series"]),
177+ resource.split_base_image(),
178+ )

Subscribers

People subscribed via source and target branches