Merge ~alexsander-souza/maas:lp1914812_add_centos_quirks into maas:master

Proposed by Alexsander de Souza
Status: Merged
Approved by: Alexsander de Souza
Approved revision: 2e07343225f6028d20d53628d94d4475280c190c
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~alexsander-souza/maas:lp1914812_add_centos_quirks
Merge into: maas:master
Diff against target: 340 lines (+129/-10)
6 files modified
src/maasserver/rpc/boot.py (+26/-4)
src/maasserver/rpc/tests/test_boot.py (+81/-6)
src/maasserver/rpc/tests/test_regionservice_calls.py (+1/-0)
src/provisioningserver/kernel_opts.py (+3/-0)
src/provisioningserver/rpc/region.py (+1/-0)
src/provisioningserver/tests/test_kernel_opts.py (+17/-0)
Reviewer Review Type Date Requested Status
Christian Grabowski Approve
MAAS Lander Approve
Review via email: mp+446339@code.launchpad.net

Commit message

add support to quirks in the ephemeral kernel during xinstall

Some older OSes (like Centos/7) require that we tune the ephemeral OS kernel to match the capabilities of the one being deployed.

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

UNIT TESTS
-b lp1914812_add_centos_quirks lp:~alexsander-souza/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 2e07343225f6028d20d53628d94d4475280c190c

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

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/rpc/boot.py b/src/maasserver/rpc/boot.py
2index c850aa7..931a7e0 100644
3--- a/src/maasserver/rpc/boot.py
4+++ b/src/maasserver/rpc/boot.py
5@@ -223,11 +223,13 @@ def get_boot_config_for_machine(machine, configs, purpose):
6 # LP:2013529, machine HWE kernel might not exist for
7 # commissioning osystem/series
8 use_machine_hwe_kernel = False
9+ final_osystem, final_series = osystem, series
10 else:
11 osystem = machine.get_osystem(default=configs["default_osystem"])
12 series = machine.get_distro_series(
13 default=configs["default_distro_series"]
14 )
15+ final_osystem, final_series = osystem, series
16 # XXX: roaksoax LP: #1739761 - Since the switch to squashfs (and
17 # drop of iscsi), precise is no longer deployable. To address a
18 # squashfs image is made available allowing it to be deployed in
19@@ -317,7 +319,7 @@ def get_boot_config_for_machine(machine, configs, purpose):
20 else:
21 subarch = "no-such-kernel"
22
23- return osystem, series, subarch
24+ return osystem, series, subarch, final_osystem, final_series
25
26
27 def get_base_url_for_local_ip(local_ip, internal_domain):
28@@ -352,6 +354,15 @@ def get_final_boot_purpose(machine, arch, purpose):
29 return purpose
30
31
32+def get_quirks_kernel_opts(
33+ final_osystem: str, final_series: str
34+) -> str | None:
35+ if final_osystem == "centos":
36+ return "nvme-core.multipath=0"
37+
38+ return None
39+
40+
41 @synchronous
42 @transactional
43 def get_config(
44@@ -418,6 +429,7 @@ def get_config(
45 if log_port is None:
46 log_port = 514 # Fallback to default UDP syslog port.
47
48+ ephemeral_opts: str | None = None
49 # XXX: Instead of updating the machine directly, we should store the
50 # information and update the machine later. The current code doesn't
51 # work when you first boot a machine that has IPMI configured, since
52@@ -542,6 +554,7 @@ def get_config(
53 "log_port": log_port,
54 "extra_opts": "",
55 "http_boot": True,
56+ "ephemeral_opts": ephemeral_opts or "",
57 }
58
59 # Log the request into the event log for that machine.
60@@ -554,9 +567,13 @@ def get_config(
61 else:
62 event_log_pxe_request(machine, purpose)
63
64- osystem, series, subarch = get_boot_config_for_machine(
65- machine, configs, purpose
66- )
67+ (
68+ osystem,
69+ series,
70+ subarch,
71+ final_osystem,
72+ final_series,
73+ ) = get_boot_config_for_machine(machine, configs, purpose)
74
75 extra_kernel_opts = machine.get_effective_kernel_options(
76 default_kernel_opts=configs["kernel_opts"]
77@@ -580,6 +597,10 @@ def get_config(
78 extra_kernel_opts = merge_kparams_with_extra(
79 kparams, extra_kernel_opts
80 )
81+ if final_osystem != "ubuntu":
82+ ephemeral_opts = get_quirks_kernel_opts(
83+ final_osystem, final_series
84+ )
85 else:
86 purpose = "commissioning" # enlistment
87 if configs["use_rack_proxy"]:
88@@ -665,6 +686,7 @@ def get_config(
89 # As of MAAS 2.4 only HTTP boot is supported. This ensures MAAS 2.3
90 # rack controllers use HTTP boot as well.
91 "http_boot": True,
92+ "ephemeral_opts": ephemeral_opts or "",
93 }
94 if machine is not None:
95 params["system_id"] = machine.system_id
96diff --git a/src/maasserver/rpc/tests/test_boot.py b/src/maasserver/rpc/tests/test_boot.py
97index 9e1f972..6928a67 100644
98--- a/src/maasserver/rpc/tests/test_boot.py
99+++ b/src/maasserver/rpc/tests/test_boot.py
100@@ -235,6 +235,7 @@ class TestGetConfig(MAASServerTestCase):
101 "log_port": 5247,
102 "extra_opts": "",
103 "http_boot": True,
104+ "ephemeral_opts": "",
105 },
106 config,
107 )
108@@ -280,6 +281,7 @@ class TestGetConfig(MAASServerTestCase):
109 "log_port": syslog_port,
110 "extra_opts": "",
111 "http_boot": True,
112+ "ephemeral_opts": "",
113 },
114 config,
115 )
116@@ -324,6 +326,7 @@ class TestGetConfig(MAASServerTestCase):
117 "log_port": 5247,
118 "extra_opts": "",
119 "http_boot": True,
120+ "ephemeral_opts": "",
121 },
122 config,
123 )
124@@ -1356,6 +1359,7 @@ class TestGetConfig(MAASServerTestCase):
125 rack_controller.system_id, local_ip, remote_ip, mac=mac
126 )
127 self.assertEqual(distro_series, observed_config["release"])
128+ self.assertEqual("", observed_config["ephemeral_opts"])
129
130 def test_returns_base_image_for_custom_ubuntu_image_xinstall(self):
131 self.patch(boot_module, "get_boot_filenames").return_value = (
132@@ -1390,6 +1394,32 @@ class TestGetConfig(MAASServerTestCase):
133 expected_osystem, expected_series = custom_image.base_image.split("/")
134 self.assertEqual(expected_osystem, observed_config["osystem"])
135 self.assertEqual(expected_series, observed_config["release"])
136+ self.assertEqual("", observed_config["ephemeral_opts"])
137+
138+ def test_returns_quirks_for_centos_image_xinstall(self):
139+ osystem = Config.objects.get_config("default_osystem")
140+ release = Config.objects.get_config("default_distro_series")
141+ rack_controller = factory.make_RackController()
142+ local_ip = factory.make_ip_address()
143+ remote_ip = factory.make_ip_address()
144+ self.make_node(arch_name="amd64")
145+ node = factory.make_Node_with_Interface_on_Subnet(
146+ status=NODE_STATUS.DEPLOYING,
147+ osystem="centos",
148+ distro_series="centos71",
149+ architecture="amd64/generic",
150+ primary_rack=rack_controller,
151+ )
152+ mac = node.get_boot_interface().mac_address
153+ self.patch_autospec(boot_module, "event_log_pxe_request")
154+ observed_config = get_config(
155+ rack_controller.system_id, local_ip, remote_ip, mac=mac
156+ )
157+ self.assertEqual(osystem, observed_config["osystem"])
158+ self.assertEqual(release, observed_config["release"])
159+ self.assertEqual(
160+ "nvme-core.multipath=0", observed_config["ephemeral_opts"]
161+ )
162
163 # XXX: roaksoax LP: #1739761 - Deploying precise is now done using
164 # the commissioning ephemeral environment.
165@@ -1593,7 +1623,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
166 ]
167 )
168
169- osystem, series, config_arch = get_boot_config_for_machine(
170+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
171 machine, configs, "xinstall"
172 )
173
174@@ -1634,7 +1664,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
175 ]
176 )
177
178- osystem, series, config_arch = get_boot_config_for_machine(
179+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
180 machine, configs, "xinstall"
181 )
182
183@@ -1672,7 +1702,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
184 ]
185 )
186
187- osystem, series, config_arch = get_boot_config_for_machine(
188+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
189 machine, configs, "xinstall"
190 )
191
192@@ -1737,7 +1767,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
193 architecture=f"amd64/{legacy_subarch}",
194 )
195
196- osystem, series, config_arch = get_boot_config_for_machine(
197+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
198 modern_machine, configs, "xinstall"
199 )
200 self.assertEqual("ubuntu", osystem)
201@@ -1745,7 +1775,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
202 self.assertEqual(subarch, config_arch)
203 self.assertNotEqual(machine_hwe_kernel, config_arch)
204
205- osystem, series, config_arch = get_boot_config_for_machine(
206+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
207 legacy_machine, configs, "xinstall"
208 )
209 self.assertEqual("ubuntu", osystem)
210@@ -1796,7 +1826,7 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
211 architecture=f"amd64/{legacy_subarch}",
212 )
213
214- osystem, series, config_arch = get_boot_config_for_machine(
215+ osystem, series, config_arch, _, _ = get_boot_config_for_machine(
216 machine, configs, "commissioning"
217 )
218 self.assertEqual(configs["commissioning_osystem"], osystem)
219@@ -1804,6 +1834,51 @@ class TestGetBootConfigForMachine(MAASServerTestCase):
220 self.assertEqual(legacy_subarch, config_arch)
221 self.assertNotEqual(machine_hwe_kernel, config_arch)
222
223+ def test_get_boot_config_for_machine_centos(self):
224+ subarch = "ga-20.04"
225+ # We need a base image to be present. In fact, we always
226+ # needed that for the new image to boot.
227+ factory.make_default_ubuntu_release_bootable(arch=f"amd64/{subarch}")
228+ factory.make_usable_boot_resource(
229+ name="centos/7",
230+ architecture="amd64/generic",
231+ )
232+ machine = factory.make_Machine(
233+ architecture="amd64/generic",
234+ status=NODE_STATUS.DEPLOYING,
235+ osystem="centos",
236+ distro_series="7",
237+ )
238+ configs = Config.objects.get_configs(
239+ [
240+ "commissioning_osystem",
241+ "commissioning_distro_series",
242+ "enable_third_party_drivers",
243+ "default_min_hwe_kernel",
244+ "default_osystem",
245+ "default_distro_series",
246+ "kernel_opts",
247+ "use_rack_proxy",
248+ "maas_internal_domain",
249+ "remote_syslog",
250+ "maas_syslog_port",
251+ ]
252+ )
253+
254+ (
255+ osystem,
256+ series,
257+ config_arch,
258+ final_osystem,
259+ final_series,
260+ ) = get_boot_config_for_machine(machine, configs, "xinstall")
261+
262+ self.assertEqual(configs["commissioning_osystem"], osystem)
263+ self.assertEqual(configs["commissioning_distro_series"], series)
264+ self.assertEqual(subarch, config_arch)
265+ self.assertEqual("centos", final_osystem)
266+ self.assertEqual("7", final_series)
267+
268
269 class TestGetNodeFromMacOrHardwareUUID(MAASServerTestCase):
270 def test_get_node_from_mac_or_hardware_uuid_with_regular_mac(self):
271diff --git a/src/maasserver/rpc/tests/test_regionservice_calls.py b/src/maasserver/rpc/tests/test_regionservice_calls.py
272index dbc756a..5a22f1b 100644
273--- a/src/maasserver/rpc/tests/test_regionservice_calls.py
274+++ b/src/maasserver/rpc/tests/test_regionservice_calls.py
275@@ -371,6 +371,7 @@ class TestRegionProtocol_GetBootConfig(MAASTransactionServerTestCase):
276 "fs_host",
277 "log_host",
278 "extra_opts",
279+ "ephemeral_opts",
280 ]
281 ),
282 )
283diff --git a/src/provisioningserver/kernel_opts.py b/src/provisioningserver/kernel_opts.py
284index b0da4a0..56f3add 100644
285--- a/src/provisioningserver/kernel_opts.py
286+++ b/src/provisioningserver/kernel_opts.py
287@@ -44,6 +44,7 @@ KernelParametersBase = namedtuple(
288 # verbatim to the kernel command line
289 "http_boot", # Used to make sure a MAAS 2.3 rack controller uses
290 # http_boot.
291+ "ephemeral_opts", # Same as 'extra_opts' but used only in the ephemeral OS
292 ),
293 )
294
295@@ -162,6 +163,8 @@ def compose_kernel_command_line(params):
296 # as it would be nice to have.
297 options += compose_logging_opts(params)
298 options += compose_arch_opts(params)
299+ if params.ephemeral_opts:
300+ options.append(params.ephemeral_opts)
301 cmdline_sep = get_curtin_kernel_cmdline_sep()
302 if params.extra_opts:
303 # Using --- before extra opts makes both d-i and Curtin install
304diff --git a/src/provisioningserver/rpc/region.py b/src/provisioningserver/rpc/region.py
305index 6c8ba93..779949b 100644
306--- a/src/provisioningserver/rpc/region.py
307+++ b/src/provisioningserver/rpc/region.py
308@@ -154,6 +154,7 @@ class GetBootConfig(amp.Command):
309 # will try to use TGT as Twisted sets optional parameters to False when
310 # not defined.
311 (b"http_boot", amp.Boolean(optional=True)),
312+ (b"ephemeral_opts", amp.Unicode(optional=True)),
313 ]
314 errors = {BootConfigNoResponse: b"BootConfigNoResponse"}
315
316diff --git a/src/provisioningserver/tests/test_kernel_opts.py b/src/provisioningserver/tests/test_kernel_opts.py
317index 396aa4e..7e62449 100644
318--- a/src/provisioningserver/tests/test_kernel_opts.py
319+++ b/src/provisioningserver/tests/test_kernel_opts.py
320@@ -467,3 +467,20 @@ class TestKernelOpts(MAASTestCase):
321 ]
322 ),
323 )
324+
325+ def test_xinstall_compose_kernel_command_line_ephemeral_opts(self):
326+ # ephemeral opts MUST appear before the separator
327+ mock_get_curtin_sep = self.patch(
328+ kernel_opts, "get_curtin_kernel_cmdline_sep"
329+ )
330+ sep = factory.make_name("sep")
331+ mock_get_curtin_sep.return_value = sep
332+
333+ ephem_opt = "EPHEMERAL_OPT=1"
334+ params = self.make_kernel_parameters(
335+ purpose="xinstall",
336+ ephemeral_opts=ephem_opt,
337+ )
338+ cmdline = compose_kernel_command_line(params)
339+ self.assertIn(ephem_opt, cmdline)
340+ self.assertTrue(cmdline.find(sep) > cmdline.find(ephem_opt))

Subscribers

People subscribed via source and target branches