Merge lp:~rvb/maas/comm-templ-bug-1410367 into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 3477
Proposed branch: lp:~rvb/maas/comm-templ-bug-1410367
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 257 lines (+119/-34)
8 files modified
etc/maas/templates/pxe/config.commissioning.template (+5/-16)
etc/maas/templates/pxe/config.enlist.template (+19/-0)
etc/maas/templates/pxe/config.xinstall.template (+5/-16)
etc/maas/templates/uefi/config.enlist.template (+8/-0)
src/maasserver/api/pxeconfig.py (+10/-1)
src/maasserver/api/tests/test_pxeconfig.py (+6/-0)
src/provisioningserver/boot/tests/test_pxe.py (+29/-1)
src/provisioningserver/boot/tests/test_uefi.py (+37/-0)
To merge this branch: bzr merge lp:~rvb/maas/comm-templ-bug-1410367
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+246569@code.launchpad.net

Commit message

In the commissioning and the xinstall templates, ditch the architecture auto-detection and use what's provided in the boot parameters.

Description of the change

It's not entirely clear to me why we were using ifcpu64.c32 in the first place (it's been like that since inception) so I'm putting this up for review to get feedback.
I've tested this on my NUCs but I'm planning to do some additional testing once the CI is green again.

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

Looks good.

The ifcpu64 should only exists in the enlist template so the correct architecture is loaded for the kernel and initramfs. I guess it just happened to get copied into the commissioning script, its amazing it has been like this for this long.

review: Approve
Revision history for this message
Raphaël Badin (rvb) wrote :

> The ifcpu64 should only exists in the enlist template so the correct architecture is loaded for
> the kernel and initramfs. I guess it just happened to get copied into the commissioning
> script, its amazing it has been like this for this long.

Turns out the commissioning and the enlistment templates were the same… hence the bug. I've added an enlistment template for the case where arch-detection needs to happen.

Revision history for this message
Blake Rouse (blake-rouse) wrote :

You need you to add a uefi/config.enlist.template as well. The UEFIBootMethod will expect having that template as well since the pxeconfig call was changed to return enlist.

review: Needs Fixing
Revision history for this message
Raphaël Badin (rvb) wrote :

> You need you to add a uefi/config.enlist.template as well. The UEFIBootMethod
> will expect having that template as well since the pxeconfig call was changed
> to return enlist.

Well spotted! I added the template along with a couple of missing tests.

Revision history for this message
Blake Rouse (blake-rouse) wrote :

Awesome! Thanks for fixing it up.

A CI run would be good to make sure this is correct, but I don't know if that is fully working yet with the transaction issues.

review: Approve
Revision history for this message
Raphaël Badin (rvb) wrote :

> Awesome! Thanks for fixing it up.
>
> A CI run would be good to make sure this is correct, but I don't know if that
> is fully working yet with the transaction issues.

Already done, and it's working fine (http://162.213.35.104:8080/job/maas-utopic-trunk-manual/25/). And I also tested on my NUCs.

Don't forget you're talking to the CI police here :).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/maas/templates/pxe/config.commissioning.template'
2--- etc/maas/templates/pxe/config.commissioning.template 2013-06-05 06:19:05 +0000
3+++ etc/maas/templates/pxe/config.commissioning.template 2015-01-19 13:41:25 +0000
4@@ -1,20 +1,9 @@
5 DEFAULT execute
6
7-SAY Booting under MAAS direction...
8-SAY {{kernel_params() | kernel_command}}
9-
10 LABEL execute
11- KERNEL ifcpu64.c32
12- APPEND amd64 -- i386
13-
14-LABEL amd64
15- KERNEL {{kernel_params(arch="amd64") | kernel_path }}
16- INITRD {{kernel_params(arch="amd64") | initrd_path }}
17- APPEND {{kernel_params(arch="amd64") | kernel_command}}
18- IPAPPEND 2
19-
20-LABEL i386
21- KERNEL {{kernel_params(arch="i386") | kernel_path }}
22- INITRD {{kernel_params(arch="i386") | initrd_path }}
23- APPEND {{kernel_params(arch="i386") | kernel_command}}
24+ SAY Booting under MAAS direction...
25+ SAY {{kernel_params() | kernel_command}}
26+ KERNEL {{kernel_params | kernel_path }}
27+ INITRD {{kernel_params | initrd_path }}
28+ APPEND {{kernel_params | kernel_command}}
29 IPAPPEND 2
30
31=== added file 'etc/maas/templates/pxe/config.enlist.template'
32--- etc/maas/templates/pxe/config.enlist.template 1970-01-01 00:00:00 +0000
33+++ etc/maas/templates/pxe/config.enlist.template 2015-01-19 13:41:25 +0000
34@@ -0,0 +1,19 @@
35+DEFAULT execute
36+
37+SAY Booting under MAAS direction...
38+SAY {{kernel_params() | kernel_command}}
39+
40+LABEL execute
41+ KERNEL ifcpu64.c32
42+ APPEND amd64 -- i386
43+
44+LABEL amd64
45+ KERNEL {{kernel_params(arch="amd64") | kernel_path }}
46+ INITRD {{kernel_params(arch="amd64") | initrd_path }}
47+ APPEND {{kernel_params(arch="amd64") | kernel_command}}
48+ IPAPPEND 2
49+
50+LABEL i386
51+ KERNEL {{kernel_params(arch="i386") | kernel_path }}
52+ INITRD {{kernel_params(arch="i386") | initrd_path }}
53+ APPEND {{kernel_params(arch="i386") | kernel_command}}
54
55=== modified file 'etc/maas/templates/pxe/config.xinstall.template'
56--- etc/maas/templates/pxe/config.xinstall.template 2013-06-03 11:32:28 +0000
57+++ etc/maas/templates/pxe/config.xinstall.template 2015-01-19 13:41:25 +0000
58@@ -1,20 +1,9 @@
59 DEFAULT execute
60
61-SAY Booting under MAAS direction...
62-SAY {{kernel_params() | kernel_command}}
63-
64 LABEL execute
65- KERNEL ifcpu64.c32
66- APPEND amd64 -- i386
67-
68-LABEL amd64
69- KERNEL {{kernel_params(arch="amd64") | kernel_path }}
70- INITRD {{kernel_params(arch="amd64") | initrd_path }}
71- APPEND {{kernel_params(arch="amd64") | kernel_command}}
72- IPAPPEND 2
73-
74-LABEL i386
75- KERNEL {{kernel_params(arch="i386") | kernel_path }}
76- INITRD {{kernel_params(arch="i386") | initrd_path }}
77- APPEND {{kernel_params(arch="i386") | kernel_command}}
78+ SAY Booting under MAAS direction...
79+ SAY {{kernel_params() | kernel_command}}
80+ KERNEL {{kernel_params | kernel_path }}
81+ INITRD {{kernel_params | initrd_path }}
82+ APPEND {{kernel_params | kernel_command}}
83 IPAPPEND 2
84
85=== added file 'etc/maas/templates/uefi/config.enlist.template'
86--- etc/maas/templates/uefi/config.enlist.template 1970-01-01 00:00:00 +0000
87+++ etc/maas/templates/uefi/config.enlist.template 2015-01-19 13:41:25 +0000
88@@ -0,0 +1,8 @@
89+set default="0"
90+set timeout=0
91+
92+menuentry 'Enlist' {
93+ echo 'Booting under MAAS direction...'
94+ linux {{kernel_params | kernel_path }} {{kernel_params | kernel_command}} BOOTIF=01-${net_default_mac}
95+ initrd {{kernel_params | initrd_path }}
96+}
97
98=== modified file 'src/maasserver/api/pxeconfig.py'
99--- src/maasserver/api/pxeconfig.py 2014-12-12 19:21:25 +0000
100+++ src/maasserver/api/pxeconfig.py 2015-01-19 13:41:25 +0000
101@@ -135,6 +135,9 @@
102 event_description=options[purpose])
103
104
105+DEFAULT_ARCH = 'i386'
106+
107+
108 def pxeconfig(request):
109 """Get the PXE configuration given a node's details.
110
111@@ -214,7 +217,7 @@
112 BootResource.objects.get_default_commissioning_resource(
113 osystem, series))
114 if resource is None:
115- arch = 'i386'
116+ arch = DEFAULT_ARCH
117 else:
118 arch, _ = resource.split_arch()
119
120@@ -293,6 +296,12 @@
121 server_address = get_maas_facing_server_address(nodegroup=nodegroup)
122 cluster_address = get_mandatory_param(request.GET, "local")
123
124+ # If the node is enlisting and the arch is the default arch (i386),
125+ # use the dedicated enlistment template which performs architecture
126+ # detection.
127+ if node is None and arch == DEFAULT_ARCH:
128+ boot_purpose = "enlist"
129+
130 params = KernelParameters(
131 osystem=osystem, arch=arch, subarch=subarch, release=series,
132 label=label, purpose=boot_purpose, hostname=hostname, domain=domain,
133
134=== modified file 'src/maasserver/api/tests/test_pxeconfig.py'
135--- src/maasserver/api/tests/test_pxeconfig.py 2014-12-12 19:21:25 +0000
136+++ src/maasserver/api/tests/test_pxeconfig.py 2015-01-19 13:41:25 +0000
137@@ -396,11 +396,17 @@
138 # test that purpose is set to "commissioning" for
139 # enlistment (when node is None).
140 params = self.get_default_params()
141+ params['arch'] = 'armhf'
142 response = self.client.get(reverse('pxeconfig'), params)
143 self.assertEqual(
144 "commissioning",
145 json.loads(response.content)["purpose"])
146
147+ def test_pxeconfig_returns_enlist_config_if_no_architecture_provided(self):
148+ params = self.get_default_params()
149+ pxe_config = self.get_pxeconfig(params)
150+ self.assertEqual('enlist', pxe_config['purpose'])
151+
152 def test_pxeconfig_returns_fs_host_as_cluster_controller(self):
153 # The kernel parameter `fs_host` points to the cluster controller
154 # address, which is passed over within the `local` parameter.
155
156=== modified file 'src/provisioningserver/boot/tests/test_pxe.py'
157--- src/provisioningserver/boot/tests/test_pxe.py 2014-09-18 12:44:38 +0000
158+++ src/provisioningserver/boot/tests/test_pxe.py 2015-01-19 13:41:25 +0000
159@@ -324,6 +324,34 @@
160 ]
161
162 def test_get_reader_scenarios(self):
163+ method = PXEBootMethod()
164+ get_ephemeral_name = self.patch(kernel_opts, "get_ephemeral_name")
165+ get_ephemeral_name.return_value = factory.make_name("ephemeral")
166+ osystem = factory.make_name('osystem')
167+ arch = factory.make_name('arch')
168+ subarch = factory.make_name('subarch')
169+ options = {
170+ "backend": None,
171+ "kernel_params": make_kernel_parameters(
172+ testcase=self, osystem=osystem, subarch=subarch,
173+ arch=arch, purpose=self.purpose),
174+ }
175+ output = method.get_reader(**options).read(10000)
176+ config = parse_pxe_config(output)
177+ # The default section is defined.
178+ default_section_label = config.header["DEFAULT"]
179+ self.assertThat(config, Contains(default_section_label))
180+ default_section = dict(config[default_section_label])
181+
182+ contains_arch_path = StartsWith("%s/%s/%s" % (osystem, arch, subarch))
183+ self.assertThat(default_section["KERNEL"], contains_arch_path)
184+ self.assertThat(default_section["INITRD"], contains_arch_path)
185+ self.assertEquals("2", default_section["IPAPPEND"])
186+
187+
188+class TestPXEBootMethodRenderConfigScenariosEnlist(MAASTestCase):
189+
190+ def test_get_reader_scenarios(self):
191 # The commissioning config uses an extra PXELINUX module to auto
192 # select between i386 and amd64.
193 method = PXEBootMethod()
194@@ -334,7 +362,7 @@
195 "backend": None,
196 "kernel_params": make_kernel_parameters(
197 testcase=self, osystem=osystem, subarch="generic",
198- purpose=self.purpose),
199+ purpose='enlist'),
200 }
201 output = method.get_reader(**options).read(10000)
202 config = parse_pxe_config(output)
203
204=== modified file 'src/provisioningserver/boot/tests/test_uefi.py'
205--- src/provisioningserver/boot/tests/test_uefi.py 2014-09-18 12:44:38 +0000
206+++ src/provisioningserver/boot/tests/test_uefi.py 2015-01-19 13:41:25 +0000
207@@ -33,6 +33,7 @@
208 from provisioningserver.rpc.testing import MockLiveClusterToRegionRPCFixture
209 from provisioningserver.tests.test_kernel_opts import make_kernel_parameters
210 from testtools.matchers import (
211+ ContainsAll,
212 IsInstance,
213 MatchesAll,
214 MatchesRegex,
215@@ -152,6 +153,42 @@
216 output = method.get_reader(**options).read(10000)
217 self.assertIn("configfile /efi/ubuntu/grub.cfg", output)
218
219+ def test_get_reader_with_enlist_purpose(self):
220+ # If purpose is "enlist", the config.enlist.template should be
221+ # used.
222+ method = UEFIBootMethod()
223+ params = make_kernel_parameters(
224+ purpose="enlist", arch="amd64")
225+ options = {
226+ "backend": None,
227+ "kernel_params": params,
228+ }
229+ output = method.get_reader(**options).read(10000)
230+ self.assertThat(output, ContainsAll(
231+ [
232+ "menuentry 'Enlist'",
233+ "%s/%s/%s" % (params.osystem, params.arch, params.subarch),
234+ "boot-kernel",
235+ ]))
236+
237+ def test_get_reader_with_commissioning_purpose(self):
238+ # If purpose is "commissioning", the config.commissioning.template
239+ # should be used.
240+ method = UEFIBootMethod()
241+ params = make_kernel_parameters(
242+ purpose="commissioning", arch="amd64")
243+ options = {
244+ "backend": None,
245+ "kernel_params": params,
246+ }
247+ output = method.get_reader(**options).read(10000)
248+ self.assertThat(output, ContainsAll(
249+ [
250+ "menuentry 'Commission'",
251+ "%s/%s/%s" % (params.osystem, params.arch, params.subarch),
252+ "boot-kernel",
253+ ]))
254+
255
256 class TestUEFIBootMethodRegex(MAASTestCase):
257 """Tests `provisioningserver.boot.uefi.UEFIBootMethod.re_config_file`."""