Merge lp:~blake-rouse/maas/ppc64el-grub-1.5 into lp:maas/1.5

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 2271
Proposed branch: lp:~blake-rouse/maas/ppc64el-grub-1.5
Merge into: lp:maas/1.5
Diff against target: 320 lines (+216/-8)
10 files modified
etc/maas/templates/commissioning-user-data/snippets/maas_enlist.sh (+1/-1)
etc/maas/templates/uefi/config.commissioning.template (+2/-4)
etc/maas/templates/uefi/config.install.template (+0/-1)
etc/maas/templates/uefi/config.local.amd64.template (+1/-1)
etc/maas/templates/uefi/config.local.ppc64el.template (+8/-0)
src/provisioningserver/boot/__init__.py (+2/-0)
src/provisioningserver/boot/ppc64el.py (+107/-0)
src/provisioningserver/boot/tests/test_ppc64el.py (+92/-0)
src/provisioningserver/boot/tests/test_uefi.py (+2/-1)
src/provisioningserver/driver/__init__.py (+1/-0)
To merge this branch: bzr merge lp:~blake-rouse/maas/ppc64el-grub-1.5
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+219739@code.launchpad.net

Commit message

Hardware enablement support for PowerKVM

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

Self approving backport.

review: Approve
Revision history for this message
Julian Edwards (julian-edwards) wrote :

I recently wrote in an email to maas-devel that all branches landing on 1.5 *must* have a bug attached. Can you please link a bug to this branch.

(This is to make life easier when I do releases)

Also if you ensure that the bug is linked with bzr commit --fixes lp:NNNNN then tarmac auto-closes the bug for you, and LP auto-links the bug to the branch for you.

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

Sorry forgot to add the bug. I did see your email on then list, just
forgot. Bug has been added.
On May 15, 2014 7:27 PM, "Julian Edwards" <email address hidden>
wrote:

> I recently wrote in an email to maas-devel that all branches landing on
> 1.5 *must* have a bug attached. Can you please link a bug to this branch.
>
> (This is to make life easier when I do releases)
>
> Also if you ensure that the bug is linked with bzr commit --fixes lp:NNNNN
> then tarmac auto-closes the bug for you, and LP auto-links the bug to the
> branch for you.
> --
> https://code.launchpad.net/~blake-rouse/maas/ppc64el-grub-1.5/+merge/219739
> You are the owner of lp:~blake-rouse/maas/ppc64el-grub-1.5.
>

Revision history for this message
Julian Edwards (julian-edwards) wrote :

On 16/05/14 11:36, Blake Rouse wrote:
> Sorry forgot to add the bug. I did see your email on then list, just
> forgot. Bug has been added.

Awesome, thanks.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/maas/templates/commissioning-user-data/snippets/maas_enlist.sh'
2--- etc/maas/templates/commissioning-user-data/snippets/maas_enlist.sh 2014-02-25 15:53:10 +0000
3+++ etc/maas/templates/commissioning-user-data/snippets/maas_enlist.sh 2014-05-15 17:43:21 +0000
4@@ -61,7 +61,7 @@
5 get_host_subarchitecture() {
6 local arch=$1
7 case $arch in
8- i386|amd64)
9+ i386|amd64|ppc64el)
10 # Skip the call to archdetect as that's what
11 # get_host_architecture does
12 echo generic
13
14=== modified file 'etc/maas/templates/uefi/config.commissioning.template'
15--- etc/maas/templates/uefi/config.commissioning.template 2014-03-18 17:41:14 +0000
16+++ etc/maas/templates/uefi/config.commissioning.template 2014-05-15 17:43:21 +0000
17@@ -1,10 +1,8 @@
18 set default="0"
19 set timeout=0
20
21-# Force AMD64 for commissioning as UEFI only supports AMD64 currently.
22 menuentry 'Commission' {
23 echo 'Booting under MAAS direction...'
24- echo '{{kernel_params() | kernel_command}} BOOTIF=01-'${net_default_mac}
25- linux {{kernel_params(arch="amd64") | kernel_path }} {{kernel_params(arch="amd64") | kernel_command}} BOOTIF=01-${net_default_mac}
26- initrd {{kernel_params(arch="amd64") | initrd_path }}
27+ linux {{kernel_params | kernel_path }} {{kernel_params | kernel_command}} BOOTIF=01-${net_default_mac}
28+ initrd {{kernel_params | initrd_path }}
29 }
30
31=== modified file 'etc/maas/templates/uefi/config.install.template'
32--- etc/maas/templates/uefi/config.install.template 2014-03-04 16:59:37 +0000
33+++ etc/maas/templates/uefi/config.install.template 2014-05-15 17:43:21 +0000
34@@ -3,7 +3,6 @@
35
36 menuentry 'Install' {
37 echo 'Booting under MAAS direction...'
38- echo '{{kernel_params | kernel_command}} BOOTIF=01-'${net_default_mac}
39 linux {{kernel_params | kernel_path }} {{kernel_params | kernel_command}} BOOTIF=01-${net_default_mac}
40 initrd {{kernel_params | initrd_path }}
41 }
42
43=== renamed file 'etc/maas/templates/uefi/config.local.template' => 'etc/maas/templates/uefi/config.local.amd64.template'
44--- etc/maas/templates/uefi/config.local.template 2014-03-28 19:03:46 +0000
45+++ etc/maas/templates/uefi/config.local.amd64.template 2014-05-15 17:43:21 +0000
46@@ -2,7 +2,7 @@
47 set timeout=0
48
49 menuentry 'Local' {
50- echo 'Booting local disk ...'
51+ echo 'Booting local disk...'
52 search --set=root --file /efi/ubuntu/grub.cfg
53 configfile /efi/ubuntu/grub.cfg
54 }
55
56=== added file 'etc/maas/templates/uefi/config.local.ppc64el.template'
57--- etc/maas/templates/uefi/config.local.ppc64el.template 1970-01-01 00:00:00 +0000
58+++ etc/maas/templates/uefi/config.local.ppc64el.template 2014-05-15 17:43:21 +0000
59@@ -0,0 +1,8 @@
60+set default="0"
61+set timeout=0
62+
63+menuentry 'Local' {
64+ echo 'Booting local disk...'
65+ search --set=root --file /boot/grub/grub.cfg
66+ configfile /boot/grub/grub.cfg
67+}
68
69=== modified file 'src/provisioningserver/boot/__init__.py'
70--- src/provisioningserver/boot/__init__.py 2014-03-28 16:46:55 +0000
71+++ src/provisioningserver/boot/__init__.py 2014-05-15 17:43:21 +0000
72@@ -202,11 +202,13 @@
73 # Import the supported boot methods after defining BootMethod.
74 from provisioningserver.boot.pxe import PXEBootMethod
75 from provisioningserver.boot.uefi import UEFIBootMethod
76+from provisioningserver.boot.ppc64el import PPC64ELBootMethod
77
78
79 builtin_boot_methods = [
80 PXEBootMethod(),
81 UEFIBootMethod(),
82+ PPC64ELBootMethod(),
83 ]
84 for method in builtin_boot_methods:
85 BootMethodRegistry.register_item(method.name, method)
86
87=== added file 'src/provisioningserver/boot/ppc64el.py'
88--- src/provisioningserver/boot/ppc64el.py 1970-01-01 00:00:00 +0000
89+++ src/provisioningserver/boot/ppc64el.py 2014-05-15 17:43:21 +0000
90@@ -0,0 +1,107 @@
91+# Copyright 2014 Canonical Ltd. This software is licensed under the
92+# GNU Affero General Public License version 3 (see the file LICENSE).
93+
94+"""PPC64EL Boot Method"""
95+
96+from __future__ import (
97+ absolute_import,
98+ print_function,
99+ unicode_literals,
100+ )
101+
102+str = None
103+
104+__metaclass__ = type
105+__all__ = [
106+ 'PPC64ELBootMethod',
107+ ]
108+
109+import glob
110+import os.path
111+from textwrap import dedent
112+
113+from provisioningserver.boot import (
114+ BootMethod,
115+ BootMethodInstallError,
116+ utils,
117+ )
118+from provisioningserver.boot.install_bootloader import install_bootloader
119+from provisioningserver.utils import (
120+ call_and_check,
121+ tempdir,
122+ )
123+
124+
125+GRUB_CONFIG = dedent("""\
126+ configfile (pxe)/grub/grub.cfg-${net_default_mac}
127+ configfile (pxe)/grub/grub.cfg-default-ppc64el
128+ """)
129+
130+
131+class PPC64ELBootMethod(BootMethod):
132+
133+ name = "ppc64el"
134+ template_subdir = "ppc64el"
135+ bootloader_path = "bootppc64.bin"
136+ arch_octet = "00:0C"
137+
138+ def match_config_path(self, path):
139+ """Doesn't need to do anything, as the UEFIBootMethod provides
140+ the grub implementation needed.
141+ """
142+ return None
143+
144+ def render_config(self, kernel_params, **extra):
145+ """Doesn't need to do anything, as the UEFIBootMethod provides
146+ the grub implementation needed.
147+ """
148+ return ""
149+
150+ def install_bootloader(self, destination):
151+ """Installs the required files for PPC64EL booting into the
152+ tftproot.
153+ """
154+ with tempdir() as tmp:
155+ # Download the grub-ieee1275-bin package
156+ data, filename = utils.get_updates_package(
157+ 'grub-ieee1275-bin', 'http://ports.ubuntu.com',
158+ 'main', 'ppc64el')
159+ if data is None:
160+ raise BootMethodInstallError(
161+ 'Failed to download grub-ieee1275-bin package from '
162+ 'the archive.')
163+ grub_output = os.path.join(tmp, filename)
164+ with open(grub_output, 'wb') as stream:
165+ stream.write(data)
166+
167+ # Extract the package with dpkg, and install the shim
168+ call_and_check(["dpkg", "-x", grub_output, tmp])
169+
170+ # Output the embedded config, so grub-mkimage can use it
171+ config_output = os.path.join(tmp, 'grub.cfg')
172+ with open(config_output, 'wb') as stream:
173+ stream.write(GRUB_CONFIG.encode('utf-8'))
174+
175+ # Get list of grub modules
176+ module_dir = os.path.join(
177+ tmp, 'usr', 'lib', 'grub', 'powerpc-ieee1275')
178+ modules = []
179+ for module_path in glob.glob(os.path.join(module_dir, '*.mod')):
180+ module_filename = os.path.basename(module_path)
181+ module_name, _ = os.path.splitext(module_filename)
182+ modules.append(module_name)
183+
184+ # Generate the grub bootloader
185+ mkimage_output = os.path.join(tmp, self.bootloader_path)
186+ args = [
187+ 'grub-mkimage',
188+ '-o', mkimage_output,
189+ '-O', 'powerpc-ieee1275',
190+ '-d', module_dir,
191+ '-c', config_output,
192+ ]
193+ call_and_check(args + modules)
194+
195+ install_bootloader(
196+ mkimage_output,
197+ os.path.join(destination, self.bootloader_path))
198
199=== added file 'src/provisioningserver/boot/tests/test_ppc64el.py'
200--- src/provisioningserver/boot/tests/test_ppc64el.py 1970-01-01 00:00:00 +0000
201+++ src/provisioningserver/boot/tests/test_ppc64el.py 2014-05-15 17:43:21 +0000
202@@ -0,0 +1,92 @@
203+# Copyright 2014 Canonical Ltd. This software is licensed under the
204+# GNU Affero General Public License version 3 (see the file LICENSE).
205+
206+"""Tests for `provisioningserver.boot.ppc64el`."""
207+
208+from __future__ import (
209+ absolute_import,
210+ print_function,
211+ unicode_literals,
212+ )
213+
214+str = None
215+
216+__metaclass__ = type
217+__all__ = []
218+
219+from contextlib import contextmanager
220+import os
221+
222+from maastesting.factory import factory
223+from maastesting.matchers import MockCalledOnceWith
224+from maastesting.testcase import MAASTestCase
225+from provisioningserver.boot import (
226+ BootMethodInstallError,
227+ ppc64el as ppc64el_module,
228+ utils,
229+ )
230+from provisioningserver.boot.ppc64el import (
231+ GRUB_CONFIG,
232+ PPC64ELBootMethod,
233+ )
234+from provisioningserver.tests.test_kernel_opts import make_kernel_parameters
235+
236+
237+class TestPPC64ELBootMethod(MAASTestCase):
238+ """Tests `provisioningserver.boot.ppc64el.PPC64ELBootMethod`."""
239+
240+ def test_match_config_path_returns_none(self):
241+ method = PPC64ELBootMethod()
242+ paths = [factory.getRandomString() for _ in range(3)]
243+ for path in paths:
244+ self.assertEqual(None, method.match_config_path(path))
245+
246+ def test_render_config_returns_empty_string(self):
247+ method = PPC64ELBootMethod()
248+ params = [make_kernel_parameters() for _ in range(3)]
249+ for param in params:
250+ self.assertEqual("", method.render_config(params))
251+
252+ def test_install_bootloader_get_package_raises_error(self):
253+ method = PPC64ELBootMethod()
254+ self.patch(utils, 'get_updates_package').return_value = (None, None)
255+ self.assertRaises(
256+ BootMethodInstallError, method.install_bootloader, None)
257+
258+ def test_install_bootloader(self):
259+ method = PPC64ELBootMethod()
260+ filename = factory.make_name('dpkg')
261+ data = factory.getRandomString()
262+ tmp = self.make_dir()
263+ dest = self.make_dir()
264+
265+ @contextmanager
266+ def tempdir():
267+ try:
268+ yield tmp
269+ finally:
270+ pass
271+
272+ mock_get_updates_package = self.patch(utils, 'get_updates_package')
273+ mock_get_updates_package.return_value = (data, filename)
274+ self.patch(ppc64el_module, 'call_and_check')
275+ self.patch(ppc64el_module, 'tempdir').side_effect = tempdir
276+
277+ mock_install_bootloader = self.patch(
278+ ppc64el_module, 'install_bootloader')
279+
280+ method.install_bootloader(dest)
281+
282+ with open(os.path.join(tmp, filename), 'rb') as stream:
283+ saved_data = stream.read()
284+ self.assertEqual(data, saved_data)
285+
286+ with open(os.path.join(tmp, 'grub.cfg'), 'rb') as stream:
287+ saved_config = stream.read().decode('utf-8')
288+ self.assertEqual(GRUB_CONFIG, saved_config)
289+
290+ mkimage_expected = os.path.join(tmp, method.bootloader_path)
291+ dest_expected = os.path.join(dest, method.bootloader_path)
292+ self.assertThat(
293+ mock_install_bootloader,
294+ MockCalledOnceWith(mkimage_expected, dest_expected))
295
296=== modified file 'src/provisioningserver/boot/tests/test_uefi.py'
297--- src/provisioningserver/boot/tests/test_uefi.py 2014-03-28 19:03:46 +0000
298+++ src/provisioningserver/boot/tests/test_uefi.py 2014-05-15 17:43:21 +0000
299@@ -107,7 +107,8 @@
300 # used.
301 method = UEFIBootMethod()
302 options = {
303- "kernel_params": make_kernel_parameters(purpose="local"),
304+ "kernel_params": make_kernel_parameters(
305+ purpose="local", arch="amd64"),
306 }
307 output = method.render_config(**options)
308 self.assertIn("configfile /efi/ubuntu/grub.cfg", output)
309
310=== modified file 'src/provisioningserver/driver/__init__.py'
311--- src/provisioningserver/driver/__init__.py 2014-03-28 16:46:55 +0000
312+++ src/provisioningserver/driver/__init__.py 2014-05-15 17:43:21 +0000
313@@ -139,6 +139,7 @@
314 Architecture(
315 name="armhf/generic", description="armhf/generic",
316 pxealiases=["arm"], kernel_options=["console=ttyAMA0"]),
317+ Architecture(name="ppc64el/generic", description="ppc64el"),
318 ]
319 for arch in builtin_architectures:
320 ArchitectureRegistry.register_item(arch.name, arch)

Subscribers

People subscribed via source and target branches

to all changes: