Merge lp:~blake-rouse/maas/fix-power8-1.9 into lp:maas/1.9

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 4540
Proposed branch: lp:~blake-rouse/maas/fix-power8-1.9
Merge into: lp:maas/1.9
Diff against target: 917 lines (+553/-28)
15 files modified
docs/changelog.rst (+8/-5)
src/maasserver/models/node.py (+3/-3)
src/maasserver/models/partition.py (+11/-1)
src/maasserver/models/partitiontable.py (+20/-4)
src/maasserver/models/tests/test_node.py (+8/-0)
src/maasserver/models/tests/test_partition.py (+25/-1)
src/maasserver/models/tests/test_partitiontable.py (+49/-1)
src/maasserver/preseed_storage.py (+66/-8)
src/maasserver/static/js/angular/controllers/node_details_storage.js (+11/-0)
src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js (+51/-0)
src/maasserver/storage_layouts.py (+6/-1)
src/maasserver/tests/test_preseed_storage.py (+215/-1)
src/maasserver/tests/test_storage_layouts.py (+78/-1)
src/provisioningserver/boot/powerkvm.py (+1/-1)
src/provisioningserver/boot/powernv.py (+1/-1)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-power8-1.9
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+287034@code.launchpad.net

Commit message

Fix storage configuration so it adds a prep partition at the beginning of the disk for deploying PowerNV. Fix PowerNV and PowerKVM to not create the EFI partition when the storage layout is generated.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :
review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.0 MiB)

The attempt to merge lp:~blake-rouse/maas/fix-power8-1.9 into lp:maas/1.9 failed. Below is the output from the failed tests.

Ign http://prodstack-zone-1.clouds.archive.ubuntu.com trusty InRelease
Get:1 http://security.ubuntu.com trusty-security InRelease [65.9 kB]
Get:2 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates InRelease [65.9 kB]
Get:3 http://security.ubuntu.com trusty-security/main Sources [105 kB]
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports InRelease
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty Release.gpg
Get:4 http://security.ubuntu.com trusty-security/universe Sources [33.0 kB]
Get:5 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/main Sources [260 kB]
Get:6 http://security.ubuntu.com trusty-security/main amd64 Packages [427 kB]
Get:7 http://security.ubuntu.com trusty-security/universe amd64 Packages [123 kB]
Hit http://security.ubuntu.com trusty-security/main Translation-en
Hit http://security.ubuntu.com trusty-security/universe Translation-en
Get:8 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/restricted Sources [5,352 B]
Get:9 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/universe Sources [150 kB]
Get:10 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/multiverse Sources [5,547 B]
Get:11 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/main amd64 Packages [709 kB]
Get:12 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/restricted amd64 Packages [15.9 kB]
Get:13 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/universe amd64 Packages [338 kB]
Get:14 http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/multiverse amd64 Packages [13.2 kB]
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/main Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/multiverse Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/restricted Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-updates/universe Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/main Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/restricted Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/universe Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/multiverse Sources
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/main amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/restricted amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/universe amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/multiverse amd64 Packages
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/main Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/multiverse Translation-en
Hit http://prodstack-zone-1.clouds.archive.ubuntu.com trusty-backports/restricted Translation-en
Hit http://prodstack-zone-1.clouds.archive...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'docs/changelog.rst'
--- docs/changelog.rst 2016-01-26 00:26:34 +0000
+++ docs/changelog.rst 2016-02-24 16:23:03 +0000
@@ -8,14 +8,17 @@
88
9See https://launchpad.net/maas/+milestone/1.9.1 for full details.9See https://launchpad.net/maas/+milestone/1.9.1 for full details.
1010
11Minor bugs fixed in this release
12--------------------------------
13
14LP: #1536754 Upgrade from 1.8 to 1.9 lost connected macs in all but one network
15
16Bug Fix Update11Bug Fix Update
17--------------12--------------
1813
14#1523779 Fix grub-install error on deploying power8 machines.
15
16#1526542 Skip block devices with duplicate serial numbers to fix multipath issue.
17
18#1536754 Upgrade from 1.8 to 1.9 lost connected macs in all but one network.
19
20#1532262 Fix failure to power query requests for SM15K servers.
21
19#1484696 Fix bug in apache2 maas config where it will reuse websocket connections22#1484696 Fix bug in apache2 maas config where it will reuse websocket connections
20 to work around a bug in apache2 itself.23 to work around a bug in apache2 itself.
2124
2225
=== modified file 'src/maasserver/models/node.py'
--- src/maasserver/models/node.py 2015-11-30 07:50:50 +0000
+++ src/maasserver/models/node.py 2016-02-24 16:23:03 +0000
@@ -155,7 +155,7 @@
155155
156# Holds the known `bios_boot_methods`. If `bios_boot_method` is not in this156# Holds the known `bios_boot_methods`. If `bios_boot_method` is not in this
157# list then it will fallback to `DEFAULT_BIOS_BOOT_METHOD`.157# list then it will fallback to `DEFAULT_BIOS_BOOT_METHOD`.
158KNOWN_BIOS_BOOT_METHODS = ["pxe", "uefi"]158KNOWN_BIOS_BOOT_METHODS = ["pxe", "uefi", "powernv", "powerkvm"]
159159
160# Default `bios_boot_method`. See `KNOWN_BIOS_BOOT_METHOD` above for usage.160# Default `bios_boot_method`. See `KNOWN_BIOS_BOOT_METHOD` above for usage.
161DEFAULT_BIOS_BOOT_METHOD = "pxe"161DEFAULT_BIOS_BOOT_METHOD = "pxe"
@@ -837,8 +837,8 @@
837 """Return true if the node is connected to a managed network."""837 """Return true if the node is connected to a managed network."""
838 for interface in self.interface_set.all():838 for interface in self.interface_set.all():
839 for link in interface.get_links():839 for link in interface.get_links():
840 if (link['mode'] != INTERFACE_LINK_TYPE.LINK_UP840 if (link['mode'] != INTERFACE_LINK_TYPE.LINK_UP and
841 and 'subnet' in link):841 'subnet' in link):
842 return True842 return True
843 return False843 return False
844844
845845
=== modified file 'src/maasserver/models/partition.py'
--- src/maasserver/models/partition.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/models/partition.py 2016-02-24 16:23:03 +0000
@@ -189,7 +189,17 @@
189 partitions_in_table = sorted(partitions_in_table, key=attrgetter('id'))189 partitions_in_table = sorted(partitions_in_table, key=attrgetter('id'))
190 idx = partitions_in_table.index(self)190 idx = partitions_in_table.index(self)
191 if self.partition_table.table_type == PARTITION_TABLE_TYPE.GPT:191 if self.partition_table.table_type == PARTITION_TABLE_TYPE.GPT:
192 return idx + 1192 # ppc64el machines get part1 skipped when this partition is on
193 # the boot disk. This is because the prep partition is part1 and
194 # is added when the preseed for storage is generated.
195 node = self.get_node()
196 arch, _ = node.split_arch()
197 boot_disk = node.get_boot_disk()
198 if (arch == "ppc64el" and
199 self.partition_table.block_device.id == boot_disk.id):
200 return idx + 2
201 else:
202 return idx + 1
193 elif self.partition_table.table_type == PARTITION_TABLE_TYPE.MBR:203 elif self.partition_table.table_type == PARTITION_TABLE_TYPE.MBR:
194 # If more than 4 partitions then the 4th partition number is204 # If more than 4 partitions then the 4th partition number is
195 # skipped because that is used for the extended partition.205 # skipped because that is used for the extended partition.
196206
=== modified file 'src/maasserver/models/partitiontable.py'
--- src/maasserver/models/partitiontable.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/models/partitiontable.py 2016-02-24 16:23:03 +0000
@@ -49,6 +49,13 @@
49PARTITION_TABLE_EXTRA_SPACE = (49PARTITION_TABLE_EXTRA_SPACE = (
50 INITIAL_PARTITION_OFFSET + END_OF_PARTITION_TABLE_SPACE)50 INITIAL_PARTITION_OFFSET + END_OF_PARTITION_TABLE_SPACE)
5151
52# The amount of space required to be reserved for the prep partition. Prep
53# partition is required by all ppc64el architectures. Because of the way the
54# system boots it requires that a 8MiB prep partition exist with grub installed
55# on that partition. Without this partition the installation of grub will fail
56# on ppc64el and will fail to boot.
57PREP_PARTITION_SIZE = 8 * 1024 * 1024 # 8MiB
58
5259
53class PartitionTable(CleanSave, TimestampedModel):60class PartitionTable(CleanSave, TimestampedModel):
54 """A partition table on a block device.61 """A partition table on a block device.
@@ -73,7 +80,7 @@
73 def get_size(self):80 def get_size(self):
74 """Total usable size of partition table."""81 """Total usable size of partition table."""
75 return round_size_to_nearest_block(82 return round_size_to_nearest_block(
76 self.block_device.size - PARTITION_TABLE_EXTRA_SPACE,83 self.block_device.size - self.get_overhead_size(),
77 PARTITION_ALIGNMENT_SIZE,84 PARTITION_ALIGNMENT_SIZE,
78 False)85 False)
7986
@@ -81,6 +88,15 @@
81 """Block size of partition table."""88 """Block size of partition table."""
82 return self.block_device.block_size89 return self.block_device.block_size
8390
91 def get_overhead_size(self):
92 """Return the total amount of extra space this partition table
93 requires."""
94 extra_space = PARTITION_TABLE_EXTRA_SPACE
95 node_arch, _ = self.block_device.node.split_arch()
96 if node_arch == "ppc64el":
97 extra_space += PREP_PARTITION_SIZE
98 return extra_space
99
84 def get_used_size(self, ignore_partitions=[]):100 def get_used_size(self, ignore_partitions=[]):
85 """Return the used size of partitions on the table."""101 """Return the used size of partitions on the table."""
86 ignore_ids = [102 ignore_ids = [
@@ -93,7 +109,7 @@
93 if used_size is None:109 if used_size is None:
94 used_size = 0110 used_size = 0
95 # The extra space taken by the partition table header is used space.111 # The extra space taken by the partition table header is used space.
96 return used_size + PARTITION_TABLE_EXTRA_SPACE112 return used_size + self.get_overhead_size()
97113
98 def get_available_size(self, ignore_partitions=[]):114 def get_available_size(self, ignore_partitions=[]):
99 """Return the remaining size available for partitions."""115 """Return the remaining size available for partitions."""
@@ -143,8 +159,8 @@
143 # placed on the boot disk.159 # placed on the boot disk.
144 if boot_disk is not None and self.block_device.id == boot_disk.id:160 if boot_disk is not None and self.block_device.id == boot_disk.id:
145 bios_boot_method = node.get_bios_boot_method()161 bios_boot_method = node.get_bios_boot_method()
146 if bios_boot_method == "uefi":162 if bios_boot_method in ["uefi", "powernv", "powerkvm"]:
147 # UEFI must always use a GPT table.163 # UEFI, PowerNV, or PowerKVM must always use a GPT table.
148 if not self.table_type:164 if not self.table_type:
149 self.table_type = PARTITION_TABLE_TYPE.GPT165 self.table_type = PARTITION_TABLE_TYPE.GPT
150 elif self.table_type != PARTITION_TABLE_TYPE.GPT:166 elif self.table_type != PARTITION_TABLE_TYPE.GPT:
151167
=== modified file 'src/maasserver/models/tests/test_node.py'
--- src/maasserver/models/tests/test_node.py 2015-11-21 02:16:17 +0000
+++ src/maasserver/models/tests/test_node.py 2016-02-24 16:23:03 +0000
@@ -242,6 +242,14 @@
242 node = factory.make_Node(bios_boot_method="uefi")242 node = factory.make_Node(bios_boot_method="uefi")
243 self.assertEquals("uefi", node.get_bios_boot_method())243 self.assertEquals("uefi", node.get_bios_boot_method())
244244
245 def test_get_bios_boot_method_returns_powernv(self):
246 node = factory.make_Node(bios_boot_method="powernv")
247 self.assertEqual("powernv", node.get_bios_boot_method())
248
249 def test_get_bios_boot_method_returns_powerkvm(self):
250 node = factory.make_Node(bios_boot_method="powerkvm")
251 self.assertEqual("powerkvm", node.get_bios_boot_method())
252
245 def test_get_bios_boot_method_fallback_to_pxe(self):253 def test_get_bios_boot_method_fallback_to_pxe(self):
246 node = factory.make_Node(bios_boot_method=factory.make_name("boot"))254 node = factory.make_Node(bios_boot_method=factory.make_name("boot"))
247 self.assertEquals("pxe", node.get_bios_boot_method())255 self.assertEquals("pxe", node.get_bios_boot_method())
248256
=== modified file 'src/maasserver/models/tests/test_partition.py'
--- src/maasserver/models/tests/test_partition.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/models/tests/test_partition.py 2016-02-24 16:23:03 +0000
@@ -31,7 +31,10 @@
31 Partition,31 Partition,
32 PARTITION_ALIGNMENT_SIZE,32 PARTITION_ALIGNMENT_SIZE,
33)33)
34from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE34from maasserver.models.partitiontable import (
35 PARTITION_TABLE_EXTRA_SPACE,
36 PREP_PARTITION_SIZE,
37)
35from maasserver.testing.factory import factory38from maasserver.testing.factory import factory
36from maasserver.testing.orm import reload_object39from maasserver.testing.orm import reload_object
37from maasserver.testing.testcase import MAASServerTestCase40from maasserver.testing.testcase import MAASServerTestCase
@@ -311,6 +314,27 @@
311 self.expectThat(idx, Equals(partition.get_partition_number()))314 self.expectThat(idx, Equals(partition.get_partition_number()))
312 idx += 1315 idx += 1
313316
317 def test_get_partition_number_returns_starting_at_2_for_ppc64el(self):
318 node = factory.make_Node(
319 architecture="ppc64el/generic", bios_boot_method="uefi")
320 block_device = factory.make_PhysicalBlockDevice(
321 node=node,
322 size=(
323 (MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE +
324 PREP_PARTITION_SIZE))
325 node.boot_disk = block_device
326 node.save()
327 partition_table = factory.make_PartitionTable(
328 block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT)
329 partitions = [
330 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)
331 for _ in range(4)
332 ]
333 idx = 2
334 for partition in partitions:
335 self.expectThat(idx, Equals(partition.get_partition_number()))
336 idx += 1
337
314 def test_get_partition_number_returns_correct_numbering_for_mbr(self):338 def test_get_partition_number_returns_correct_numbering_for_mbr(self):
315 block_device = factory.make_PhysicalBlockDevice(339 block_device = factory.make_PhysicalBlockDevice(
316 size=(MIN_BLOCK_DEVICE_SIZE * 6) + PARTITION_TABLE_EXTRA_SPACE)340 size=(MIN_BLOCK_DEVICE_SIZE * 6) + PARTITION_TABLE_EXTRA_SPACE)
317341
=== modified file 'src/maasserver/models/tests/test_partitiontable.py'
--- src/maasserver/models/tests/test_partitiontable.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/models/tests/test_partitiontable.py 2016-02-24 16:23:03 +0000
@@ -28,7 +28,10 @@
28 MIN_PARTITION_SIZE,28 MIN_PARTITION_SIZE,
29 PARTITION_ALIGNMENT_SIZE,29 PARTITION_ALIGNMENT_SIZE,
30)30)
31from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE31from maasserver.models.partitiontable import (
32 PARTITION_TABLE_EXTRA_SPACE,
33 PREP_PARTITION_SIZE,
34)
32from maasserver.testing.factory import factory35from maasserver.testing.factory import factory
33from maasserver.testing.testcase import MAASServerTestCase36from maasserver.testing.testcase import MAASServerTestCase
34from maasserver.utils.converters import round_size_to_nearest_block37from maasserver.utils.converters import round_size_to_nearest_block
@@ -52,6 +55,19 @@
52 False),55 False),
53 partition_table.get_size())56 partition_table.get_size())
5457
58 def test_get_size_returns_block_device_size_minus_ppc64el(self):
59 node = factory.make_Node(architecture="ppc64el/generic")
60 block_device = factory.make_PhysicalBlockDevice(node=node)
61 partition_table = factory.make_PartitionTable(
62 block_device=block_device)
63 self.assertEqual(
64 round_size_to_nearest_block(
65 partition_table.block_device.size -
66 PARTITION_TABLE_EXTRA_SPACE - PREP_PARTITION_SIZE,
67 PARTITION_ALIGNMENT_SIZE,
68 False),
69 partition_table.get_size())
70
55 def test_get_block_size_returns_block_device_block_size(self):71 def test_get_block_size_returns_block_device_block_size(self):
56 partition_table = factory.make_PartitionTable()72 partition_table = factory.make_PartitionTable()
57 self.assertEquals(73 self.assertEquals(
@@ -123,6 +139,24 @@
123 self.assertRaises(139 self.assertRaises(
124 ValidationError, partition_table.add_partition)140 ValidationError, partition_table.add_partition)
125141
142 def test_get_overhead_size(self):
143 node = factory.make_Node(bios_boot_method="pxe")
144 block_device = factory.make_PhysicalBlockDevice(node=node)
145 partition_table = factory.make_PartitionTable(
146 block_device=block_device)
147 self.assertEquals(
148 PARTITION_TABLE_EXTRA_SPACE,
149 partition_table.get_overhead_size())
150
151 def test_get_overhead_size_for_ppc64el(self):
152 node = factory.make_Node(architecture="ppc64el/generic")
153 block_device = factory.make_PhysicalBlockDevice(node=node)
154 partition_table = factory.make_PartitionTable(
155 block_device=block_device)
156 self.assertEquals(
157 PARTITION_TABLE_EXTRA_SPACE + PREP_PARTITION_SIZE,
158 partition_table.get_overhead_size())
159
126 def test_get_available_size(self):160 def test_get_available_size(self):
127 block_size = 4096161 block_size = 4096
128 device = factory.make_BlockDevice(162 device = factory.make_BlockDevice(
@@ -162,6 +196,20 @@
162 partition_table = factory.make_PartitionTable(block_device=boot_disk)196 partition_table = factory.make_PartitionTable(block_device=boot_disk)
163 self.assertEquals(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)197 self.assertEquals(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
164198
199 def test_save_sets_table_type_to_gpt_for_powernv_boot(self):
200 node = factory.make_Node(
201 with_boot_disk=False, bios_boot_method="powernv")
202 boot_disk = factory.make_PhysicalBlockDevice(node=node)
203 partition_table = factory.make_PartitionTable(block_device=boot_disk)
204 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
205
206 def test_save_sets_table_type_to_gpt_for_powerkvm_boot(self):
207 node = factory.make_Node(
208 with_boot_disk=False, bios_boot_method="powerkvm")
209 boot_disk = factory.make_PhysicalBlockDevice(node=node)
210 partition_table = factory.make_PartitionTable(block_device=boot_disk)
211 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
212
165 def test_save_sets_table_type_to_gpt_for_none_boot_disk(self):213 def test_save_sets_table_type_to_gpt_for_none_boot_disk(self):
166 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")214 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")
167 factory.make_PhysicalBlockDevice(node=node)215 factory.make_PhysicalBlockDevice(node=node)
168216
=== modified file 'src/maasserver/preseed_storage.py'
--- src/maasserver/preseed_storage.py 2015-10-29 16:39:49 +0000
+++ src/maasserver/preseed_storage.py 2016-02-24 16:23:03 +0000
@@ -22,7 +22,10 @@
22 FILESYSTEM_TYPE,22 FILESYSTEM_TYPE,
23 PARTITION_TABLE_TYPE,23 PARTITION_TABLE_TYPE,
24)24)
25from maasserver.models.partitiontable import INITIAL_PARTITION_OFFSET25from maasserver.models.partitiontable import (
26 INITIAL_PARTITION_OFFSET,
27 PREP_PARTITION_SIZE,
28)
26from maasserver.models.physicalblockdevice import PhysicalBlockDevice29from maasserver.models.physicalblockdevice import PhysicalBlockDevice
27from maasserver.models.virtualblockdevice import VirtualBlockDevice30from maasserver.models.virtualblockdevice import VirtualBlockDevice
28import yaml31import yaml
@@ -34,6 +37,7 @@
34 def __init__(self, node):37 def __init__(self, node):
35 self.node = node38 self.node = node
36 self.boot_disk = node.get_boot_disk()39 self.boot_disk = node.get_boot_disk()
40 self.boot_disk_first_partition = None
37 self.operations = {41 self.operations = {
38 "disk": [],42 "disk": [],
39 "partition": [],43 "partition": [],
@@ -111,6 +115,13 @@
111 raise ValueError("Unknown block device instance: %s" % (115 raise ValueError("Unknown block device instance: %s" % (
112 block_device.__class__.__name__))116 block_device.__class__.__name__))
113117
118 def _requires_prep_partition(self, block_device):
119 """Return True if block device requires the prep partition."""
120 arch, _ = self.node.split_arch()
121 return (
122 self.boot_disk.id == block_device.id and
123 arch == "ppc64el")
124
114 def _add_partition_operations(self):125 def _add_partition_operations(self):
115 """Add all the partition operations.126 """Add all the partition operations.
116127
@@ -118,9 +129,16 @@
118 attached to the node.129 attached to the node.
119 """130 """
120 for block_device in self.node.blockdevice_set.order_by('id'):131 for block_device in self.node.blockdevice_set.order_by('id'):
132 requires_prep = self._requires_prep_partition(block_device)
121 partition_table = block_device.get_partitiontable()133 partition_table = block_device.get_partitiontable()
122 if partition_table is not None:134 if partition_table is not None:
123 for partition in partition_table.partitions.order_by('id'):135 partitions = list(partition_table.partitions.order_by('id'))
136 for idx, partition in enumerate(partitions):
137 # If this is the last partition and prep partition is
138 # required then set boot_disk_first_partition so extra
139 # space can be removed.
140 if requires_prep and idx == 0:
141 self.boot_disk_first_partition = partition
124 self.operations["partition"].append(partition)142 self.operations["partition"].append(partition)
125143
126 def _add_format_and_mount_operations(self):144 def _add_format_and_mount_operations(self):
@@ -180,21 +198,35 @@
180198
181 # Set the partition table type if a partition table exists or if this199 # Set the partition table type if a partition table exists or if this
182 # is the boot disk.200 # is the boot disk.
201 add_prep_partition = False
183 partition_table = block_device.get_partitiontable()202 partition_table = block_device.get_partitiontable()
184 if partition_table is not None:203 if partition_table is not None:
185 disk_operation["ptable"] = self._get_ptable_type(204 disk_operation["ptable"] = self._get_ptable_type(
186 partition_table)205 partition_table)
187 elif block_device.id == self.boot_disk.id:206 elif block_device.id == self.boot_disk.id:
188 if self.node.get_bios_boot_method() == "uefi":207 bios_boot_method = self.node.get_bios_boot_method()
208 node_arch, _ = self.node.split_arch()
209 if bios_boot_method in [
210 "uefi", "powernv", "powerkvm"]:
189 disk_operation["ptable"] = "gpt"211 disk_operation["ptable"] = "gpt"
212 if node_arch == "ppc64el":
213 add_prep_partition = True
190 else:214 else:
191 disk_operation["ptable"] = "msdos"215 disk_operation["ptable"] = "msdos"
192216
193 # Set this disk to be the grub device if its the boot disk.217 # Set this disk to be the grub device if it's the boot disk and doesn't
194 if self.boot_disk == block_device:218 # require a prep partition. When a prep partition is required grub
219 # must be installed on that partition and not in the partition header
220 # of that disk.
221 requires_prep = self._requires_prep_partition(block_device)
222 if self.boot_disk.id == block_device.id and not requires_prep:
195 disk_operation["grub_device"] = True223 disk_operation["grub_device"] = True
196 self.storage_config.append(disk_operation)224 self.storage_config.append(disk_operation)
197225
226 # Add the prep partition at the end of the disk when it is required.
227 if add_prep_partition:
228 self._generate_prep_partition(block_device.get_name())
229
198 def _get_ptable_type(self, partition_table):230 def _get_ptable_type(self, partition_table):
199 """Return the value for the "ptable" entry in the physical operation.231 """Return the value for the "ptable" entry in the physical operation.
200 """232 """
@@ -207,12 +239,38 @@
207 "Unknown partition table type: %s" % (239 "Unknown partition table type: %s" % (
208 partition_table.table_type))240 partition_table.table_type))
209241
242 def _generate_prep_partition(self, device_name):
243 """Generate the prep partition at the beginning of the block device."""
244 prep_part_name = "%s-part1" % (device_name)
245 partition_operation = {
246 "id": prep_part_name,
247 "name": prep_part_name,
248 "type": "partition",
249 "number": 1,
250 "offset": "%dB" % INITIAL_PARTITION_OFFSET,
251 "size": "%dB" % PREP_PARTITION_SIZE,
252 "device": device_name,
253 "wipe": "zero",
254 "flag": "prep",
255 "grub_device": True,
256 }
257 self.storage_config.append(partition_operation)
258
210 def _generate_partition_operations(self):259 def _generate_partition_operations(self):
211 """Generate all partition operations."""260 """Generate all partition operations."""
212 for partition in self.operations["partition"]:261 for partition in self.operations["partition"]:
213 self._generate_partition_operation(partition)262 if partition == self.boot_disk_first_partition:
263 # This is the first partition in the boot disk and add prep
264 # partition at the beginning of the partition table.
265 device_name = partition.partition_table.block_device.get_name()
266 self._generate_prep_partition(device_name)
267 self._generate_partition_operation(
268 partition, include_initial=False)
269 else:
270 self._generate_partition_operation(
271 partition, include_initial=True)
214272
215 def _generate_partition_operation(self, partition):273 def _generate_partition_operation(self, partition, include_initial):
216 """Generate partition operation for `partition` and place in274 """Generate partition operation for `partition` and place in
217 `storage_config`."""275 `storage_config`."""
218 partition_table = partition.partition_table276 partition_table = partition.partition_table
@@ -229,7 +287,7 @@
229 "wipe": "superblock",287 "wipe": "superblock",
230 }288 }
231 # First partition always sets the initial offset.289 # First partition always sets the initial offset.
232 if partition_number == 1:290 if partition_number == 1 and include_initial:
233 partition_operation["offset"] = "%sB" % INITIAL_PARTITION_OFFSET291 partition_operation["offset"] = "%sB" % INITIAL_PARTITION_OFFSET
234 if partition.bootable:292 if partition.bootable:
235 partition_operation["flag"] = "boot"293 partition_operation["flag"] = "boot"
236294
=== modified file 'src/maasserver/static/js/angular/controllers/node_details_storage.js'
--- src/maasserver/static/js/angular/controllers/node_details_storage.js 2015-11-20 17:36:10 +0000
+++ src/maasserver/static/js/angular/controllers/node_details_storage.js 2016-02-24 16:23:03 +0000
@@ -51,6 +51,7 @@
51 var END_OF_PARTITION_TABLE_SPACE = 1024 * 1024;51 var END_OF_PARTITION_TABLE_SPACE = 1024 * 1024;
52 var PARTITION_TABLE_EXTRA_SPACE = INITIAL_PARTITION_OFFSET +52 var PARTITION_TABLE_EXTRA_SPACE = INITIAL_PARTITION_OFFSET +
53 END_OF_PARTITION_TABLE_SPACE;53 END_OF_PARTITION_TABLE_SPACE;
54 var PREP_PARTITION_SIZE = 8 * 1024 * 1024;
5455
55 // From models/partition.py - must be kept in sync.56 // From models/partition.py - must be kept in sync.
56 var PARTITION_ALIGNMENT_SIZE = 4 * 1024 * 1024;57 var PARTITION_ALIGNMENT_SIZE = 4 * 1024 * 1024;
@@ -855,6 +856,11 @@
855 || disk.original.partition_table_type === "") {856 || disk.original.partition_table_type === "") {
856 // Disk has no partition table, so reserve space for it.857 // Disk has no partition table, so reserve space for it.
857 space_to_reserve = PARTITION_TABLE_EXTRA_SPACE;858 space_to_reserve = PARTITION_TABLE_EXTRA_SPACE;
859 // ppc64el node requires that space be saved for the prep
860 // partition.
861 if($scope.node.architecture.indexOf("ppc64el") === 0) {
862 space_to_reserve += PREP_PARTITION_SIZE;
863 }
858 }864 }
859 return ConverterService.roundByBlockSize(865 return ConverterService.roundByBlockSize(
860 disk.original.available_size - space_to_reserve,866 disk.original.available_size - space_to_reserve,
@@ -1130,6 +1136,11 @@
1130 if(disk.original.partition_table_type === "mbr" &&1136 if(disk.original.partition_table_type === "mbr" &&
1131 length > 2) {1137 length > 2) {
1132 return disk.name + "-part" + (length + 2);1138 return disk.name + "-part" + (length + 2);
1139 } else if($scope.node.architecture.indexOf("ppc64el") === 0 &&
1140 disk.original.is_boot) {
1141 // Boot disk on ppc64el machines skip the first partition as
1142 // its reserved for the prep partition.
1143 return disk.name + "-part" + (length + 2);
1133 } else {1144 } else {
1134 return disk.name + "-part" + (length + 1);1145 return disk.name + "-part" + (length + 1);
1135 }1146 }
11361147
=== modified file 'src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js'
--- src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js 2015-11-20 17:36:10 +0000
+++ src/maasserver/static/js/angular/controllers/tests/test_node_details_storage.js 2016-02-24 16:23:03 +0000
@@ -101,6 +101,7 @@
101 var node, updateNodeSpy, canEditSpy;101 var node, updateNodeSpy, canEditSpy;
102 beforeEach(function() {102 beforeEach(function() {
103 node = {103 node = {
104 architecture: "amd64/generic",
104 disks: []105 disks: []
105 };106 };
106 updateNodeSpy = jasmine.createSpy("updateNode");107 updateNodeSpy = jasmine.createSpy("updateNode");
@@ -1455,6 +1456,25 @@
1455 expect($scope.canAddPartition(disk)).toBe(false);1456 expect($scope.canAddPartition(disk)).toBe(false);
1456 });1457 });
14571458
1459 it("returns false if available_size is less than partition size " +
1460 "when node is ppc64el architecture",
1461 function() {
1462 var controller = makeController();
1463 var disk = {
1464 type: "physical",
1465 fstype: "",
1466 original: {
1467 partition_table_type: null,
1468 available_size: (2.5 * 1024 * 1024) + (8 * 1024 * 1024),
1469 block_size: 1024
1470 }
1471 };
1472 node.architecture = "ppc64el/generic";
1473 spyOn($scope, "isAllStorageDisabled").and.returnValue(false);
1474 $scope.isSuperUser = function() { return true; };
1475 expect($scope.canAddPartition(disk)).toBe(false);
1476 });
1477
1458 it("returns false if not super user", function() {1478 it("returns false if not super user", function() {
1459 var controller = makeController();1479 var controller = makeController();
1460 var disk = {1480 var disk = {
@@ -2350,6 +2370,37 @@
2350 expect($scope.getAddPartitionName(disk)).toBe(name + "-part3");2370 expect($scope.getAddPartitionName(disk)).toBe(name + "-part3");
2351 });2371 });
23522372
2373 it("returns disk.name with -part2 for ppc64el", function() {
2374 node.architecture = "ppc64el/generic";
2375 var controller = makeController();
2376 var name = makeName("sda");
2377 var disk = {
2378 name: name,
2379 original: {
2380 is_boot: true,
2381 partition_table_type: "gpt"
2382 }
2383 };
2384
2385 expect($scope.getAddPartitionName(disk)).toBe(name + "-part2");
2386 });
2387
2388 it("returns disk.name with -part4 for ppc64el", function() {
2389 node.architecture = "ppc64el/generic";
2390 var controller = makeController();
2391 var name = makeName("sda");
2392 var disk = {
2393 name: name,
2394 original: {
2395 is_boot: true,
2396 partition_table_type: "gpt",
2397 partitions: [{}, {}]
2398 }
2399 };
2400
2401 expect($scope.getAddPartitionName(disk)).toBe(name + "-part4");
2402 });
2403
2353 it("returns disk.name with -part3 for MBR", function() {2404 it("returns disk.name with -part3 for MBR", function() {
2354 var controller = makeController();2405 var controller = makeController();
2355 var name = makeName("sda");2406 var name = makeName("sda");
23562407
=== modified file 'src/maasserver/storage_layouts.py'
--- src/maasserver/storage_layouts.py 2015-10-07 23:07:32 +0000
+++ src/maasserver/storage_layouts.py 2016-02-24 16:23:03 +0000
@@ -178,7 +178,12 @@
178 from maasserver.models.partitiontable import PartitionTable178 from maasserver.models.partitiontable import PartitionTable
179 boot_partition_table = PartitionTable.objects.create(179 boot_partition_table = PartitionTable.objects.create(
180 block_device=self.boot_disk)180 block_device=self.boot_disk)
181 if boot_partition_table.table_type == PARTITION_TABLE_TYPE.GPT:181 bios_boot_method = self.node.get_bios_boot_method()
182 node_arch, _ = self.node.split_arch()
183 if (boot_partition_table.table_type == PARTITION_TABLE_TYPE.GPT and
184 bios_boot_method == "uefi" and node_arch != "ppc64el"):
185 # Add EFI partition only if booting UEFI and not a ppc64el
186 # architecture.
182 efi_partition = boot_partition_table.add_partition(187 efi_partition = boot_partition_table.add_partition(
183 size=EFI_PARTITION_SIZE, bootable=True)188 size=EFI_PARTITION_SIZE, bootable=True)
184 Filesystem.objects.create(189 Filesystem.objects.create(
185190
=== modified file 'src/maasserver/tests/test_preseed_storage.py'
--- src/maasserver/tests/test_preseed_storage.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/tests/test_preseed_storage.py 2016-02-24 16:23:03 +0000
@@ -28,7 +28,10 @@
28 RAID,28 RAID,
29 VolumeGroup,29 VolumeGroup,
30)30)
31from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE31from maasserver.models.partitiontable import (
32 PARTITION_TABLE_EXTRA_SPACE,
33 PREP_PARTITION_SIZE,
34)
32from maasserver.preseed_storage import compose_curtin_storage_config35from maasserver.preseed_storage import compose_curtin_storage_config
33from maasserver.testing.factory import factory36from maasserver.testing.factory import factory
34from maasserver.testing.testcase import MAASServerTestCase37from maasserver.testing.testcase import MAASServerTestCase
@@ -757,3 +760,214 @@
757 node._create_acquired_filesystems()760 node._create_acquired_filesystems()
758 config = compose_curtin_storage_config(node)761 config = compose_curtin_storage_config(node)
759 self.assertStorageConfig(self.STORAGE_CONFIG, config)762 self.assertStorageConfig(self.STORAGE_CONFIG, config)
763
764
765class TestSimplePower8Layout(MAASServerTestCase, AssertStorageConfigMixin):
766
767 STORAGE_CONFIG = dedent("""\
768 config:
769 - id: sda
770 name: sda
771 type: disk
772 wipe: superblock
773 ptable: gpt
774 model: QEMU HARDDISK
775 serial: QM00001
776 - id: sda-part1
777 name: sda-part1
778 type: partition
779 number: 1
780 offset: 4194304B
781 size: 8388608B
782 device: sda
783 wipe: zero
784 flag: prep
785 grub_device: True
786 - id: sda-part2
787 name: sda-part2
788 type: partition
789 number: 2
790 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf
791 size: 8573157376B
792 wipe: superblock
793 device: sda
794 - id: sda-part2_format
795 type: format
796 fstype: ext4
797 label: root
798 uuid: 90a69b22-e281-4c5b-8df9-b09514f27ba1
799 volume: sda-part2
800 - id: sda-part2_mount
801 type: mount
802 path: /
803 device: sda-part2_format
804 """)
805
806 def test__renders_expected_output(self):
807 node = factory.make_Node(
808 status=NODE_STATUS.ALLOCATED, architecture="ppc64el/generic",
809 bios_boot_method="uefi", with_boot_disk=False)
810 boot_disk = factory.make_PhysicalBlockDevice(
811 node=node, size=8 * 1024 ** 3, name="sda",
812 model="QEMU HARDDISK", serial="QM00001") # 8 GiB
813 partition_table = factory.make_PartitionTable(
814 table_type=PARTITION_TABLE_TYPE.GPT, block_device=boot_disk)
815 root_partition = factory.make_Partition(
816 partition_table=partition_table,
817 uuid="f74ff260-2a5b-4a36-b1b8-37f746b946bf",
818 size=(
819 (8 * 1024 ** 3) - PARTITION_TABLE_EXTRA_SPACE -
820 PREP_PARTITION_SIZE),
821 bootable=False)
822 factory.make_Filesystem(
823 partition=root_partition, fstype=FILESYSTEM_TYPE.EXT4,
824 uuid="90a69b22-e281-4c5b-8df9-b09514f27ba1", label="root",
825 mount_point="/")
826 node._create_acquired_filesystems()
827 config = compose_curtin_storage_config(node)
828 self.assertStorageConfig(self.STORAGE_CONFIG, config)
829
830
831class TestPower8ExtraSpaceLayout(
832 MAASServerTestCase, AssertStorageConfigMixin):
833
834 STORAGE_CONFIG = dedent("""\
835 config:
836 - id: sda
837 name: sda
838 type: disk
839 wipe: superblock
840 ptable: gpt
841 model: QEMU HARDDISK
842 serial: QM00001
843 - id: sda-part1
844 name: sda-part1
845 type: partition
846 number: 1
847 offset: 4194304B
848 size: 8388608B
849 device: sda
850 wipe: zero
851 flag: prep
852 grub_device: True
853 - id: sda-part2
854 name: sda-part2
855 type: partition
856 number: 2
857 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf
858 size: 7507804160B
859 wipe: superblock
860 device: sda
861 - id: sda-part2_format
862 type: format
863 fstype: ext4
864 label: root
865 uuid: 90a69b22-e281-4c5b-8df9-b09514f27ba1
866 volume: sda-part2
867 - id: sda-part2_mount
868 type: mount
869 path: /
870 device: sda-part2_format
871 """)
872
873 def test__renders_expected_output(self):
874 node = factory.make_Node(
875 status=NODE_STATUS.ALLOCATED, architecture="ppc64el/generic",
876 bios_boot_method="uefi", with_boot_disk=False)
877 boot_disk = factory.make_PhysicalBlockDevice(
878 node=node, size=8 * 1024 ** 3, name="sda",
879 model="QEMU HARDDISK", serial="QM00001") # 8 GiB
880 partition_table = factory.make_PartitionTable(
881 table_type=PARTITION_TABLE_TYPE.GPT, block_device=boot_disk)
882 root_partition = factory.make_Partition(
883 partition_table=partition_table,
884 uuid="f74ff260-2a5b-4a36-b1b8-37f746b946bf",
885 size=(7 * 1024 ** 3) - PARTITION_TABLE_EXTRA_SPACE,
886 bootable=False)
887 factory.make_Filesystem(
888 partition=root_partition, fstype=FILESYSTEM_TYPE.EXT4,
889 uuid="90a69b22-e281-4c5b-8df9-b09514f27ba1", label="root",
890 mount_point="/")
891 node._create_acquired_filesystems()
892 config = compose_curtin_storage_config(node)
893 self.assertStorageConfig(self.STORAGE_CONFIG, config)
894
895
896class TestPower8NoPartitionTableLayout(
897 MAASServerTestCase, AssertStorageConfigMixin):
898
899 STORAGE_CONFIG = dedent("""\
900 config:
901 - id: sda
902 name: sda
903 type: disk
904 wipe: superblock
905 ptable: gpt
906 model: QEMU HARDDISK
907 serial: QM00001
908 - id: sdb
909 name: sdb
910 type: disk
911 wipe: superblock
912 ptable: gpt
913 model: QEMU HARDDISK
914 serial: QM00002
915 - id: sdb-part1
916 name: sdb-part1
917 type: partition
918 number: 1
919 offset: 4194304B
920 size: 8388608B
921 device: sdb
922 wipe: zero
923 flag: prep
924 grub_device: True
925 - id: sda-part1
926 name: sda-part1
927 type: partition
928 number: 1
929 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf
930 offset: 4194304B
931 size: 8573157376B
932 wipe: superblock
933 device: sda
934 - id: sda-part1_format
935 type: format
936 fstype: ext4
937 label: root
938 uuid: 90a69b22-e281-4c5b-8df9-b09514f27ba1
939 volume: sda-part1
940 - id: sda-part1_mount
941 type: mount
942 path: /
943 device: sda-part1_format
944 """)
945
946 def test__renders_expected_output(self):
947 node = factory.make_Node(
948 status=NODE_STATUS.ALLOCATED, architecture="ppc64el/generic",
949 bios_boot_method="uefi", with_boot_disk=False)
950 root_disk = factory.make_PhysicalBlockDevice(
951 node=node, size=8 * 1024 ** 3, name="sda",
952 model="QEMU HARDDISK", serial="QM00001") # 8 GiB
953 partition_table = factory.make_PartitionTable(
954 table_type=PARTITION_TABLE_TYPE.GPT, block_device=root_disk)
955 boot_disk = factory.make_PhysicalBlockDevice(
956 node=node, size=8 * 1024 ** 3, name="sdb",
957 model="QEMU HARDDISK", serial="QM00002") # 8 GiB
958 node.boot_disk = boot_disk
959 node.save()
960 root_partition = factory.make_Partition(
961 partition_table=partition_table,
962 uuid="f74ff260-2a5b-4a36-b1b8-37f746b946bf",
963 size=(
964 (8 * 1024 ** 3) - PARTITION_TABLE_EXTRA_SPACE -
965 PREP_PARTITION_SIZE),
966 bootable=False)
967 factory.make_Filesystem(
968 partition=root_partition, fstype=FILESYSTEM_TYPE.EXT4,
969 uuid="90a69b22-e281-4c5b-8df9-b09514f27ba1", label="root",
970 mount_point="/")
971 node._create_acquired_filesystems()
972 config = compose_curtin_storage_config(node)
973 self.assertStorageConfig(self.STORAGE_CONFIG, config)
760974
=== modified file 'src/maasserver/tests/test_storage_layouts.py'
--- src/maasserver/tests/test_storage_layouts.py 2015-11-17 23:19:51 +0000
+++ src/maasserver/tests/test_storage_layouts.py 2016-02-24 16:23:03 +0000
@@ -29,7 +29,10 @@
29 MAX_PARTITION_SIZE_FOR_MBR,29 MAX_PARTITION_SIZE_FOR_MBR,
30 PARTITION_ALIGNMENT_SIZE,30 PARTITION_ALIGNMENT_SIZE,
31)31)
32from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE32from maasserver.models.partitiontable import (
33 PARTITION_TABLE_EXTRA_SPACE,
34 PREP_PARTITION_SIZE,
35)
33from maasserver.storage_layouts import (36from maasserver.storage_layouts import (
34 BcacheStorageLayout,37 BcacheStorageLayout,
35 BcacheStorageLayoutBase,38 BcacheStorageLayoutBase,
@@ -63,6 +66,20 @@
63 return factory.make_Node(*args, **kwargs)66 return factory.make_Node(*args, **kwargs)
6467
6568
69def make_ppc64el_Node_with_powernv_boot_method(*args, **kwargs):
70 kwargs['bios_boot_method'] = "powernv"
71 kwargs['with_boot_disk'] = False
72 kwargs['architecture'] = "ppc64el/generic"
73 return factory.make_Node(*args, **kwargs)
74
75
76def make_ppc64el_Node_with_uefi_boot_method(*args, **kwargs):
77 kwargs['bios_boot_method'] = "powerkvm"
78 kwargs['with_boot_disk'] = False
79 kwargs['architecture'] = "ppc64el/generic"
80 return factory.make_Node(*args, **kwargs)
81
82
66class TestFormHelpers(MAASServerTestCase):83class TestFormHelpers(MAASServerTestCase):
6784
68 def test_get_storage_layout_choices(self):85 def test_get_storage_layout_choices(self):
@@ -514,6 +531,66 @@
514 mount_point="/",531 mount_point="/",
515 ))532 ))
516533
534 def test__creates_layout_for_powernv(self):
535 node = make_ppc64el_Node_with_powernv_boot_method()
536 boot_disk = factory.make_PhysicalBlockDevice(
537 node=node, size=LARGE_BLOCK_DEVICE)
538 layout = FlatStorageLayout(node)
539 layout.configure()
540
541 # Validate partition table.
542 partition_table = boot_disk.get_partitiontable()
543 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
544
545 # Validate root partition.
546 partitions = partition_table.partitions.order_by('id').all()
547 root_partition = partitions[0]
548 self.assertIsNotNone(root_partition)
549 self.assertEqual(
550 round_size_to_nearest_block(
551 boot_disk.size - PARTITION_TABLE_EXTRA_SPACE -
552 PREP_PARTITION_SIZE,
553 PARTITION_ALIGNMENT_SIZE,
554 False),
555 root_partition.size)
556 self.assertThat(
557 root_partition.get_effective_filesystem(),
558 MatchesStructure.byEquality(
559 fstype=FILESYSTEM_TYPE.EXT4,
560 label="root",
561 mount_point="/",
562 ))
563
564 def test__creates_layout_for_powerkvm(self):
565 node = make_ppc64el_Node_with_uefi_boot_method()
566 boot_disk = factory.make_PhysicalBlockDevice(
567 node=node, size=LARGE_BLOCK_DEVICE)
568 layout = FlatStorageLayout(node)
569 layout.configure()
570
571 # Validate partition table.
572 partition_table = boot_disk.get_partitiontable()
573 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
574
575 # Validate root partition.
576 partitions = partition_table.partitions.order_by('id').all()
577 root_partition = partitions[0]
578 self.assertIsNotNone(root_partition)
579 self.assertEqual(
580 round_size_to_nearest_block(
581 boot_disk.size - PARTITION_TABLE_EXTRA_SPACE -
582 PREP_PARTITION_SIZE,
583 PARTITION_ALIGNMENT_SIZE,
584 False),
585 root_partition.size)
586 self.assertThat(
587 root_partition.get_effective_filesystem(),
588 MatchesStructure.byEquality(
589 fstype=FILESYSTEM_TYPE.EXT4,
590 label="root",
591 mount_point="/",
592 ))
593
517 def test__creates_layout_with_uefi_defaults(self):594 def test__creates_layout_with_uefi_defaults(self):
518 node = make_Node_with_uefi_boot_method()595 node = make_Node_with_uefi_boot_method()
519 boot_disk = factory.make_PhysicalBlockDevice(596 boot_disk = factory.make_PhysicalBlockDevice(
520597
=== modified file 'src/provisioningserver/boot/powerkvm.py'
--- src/provisioningserver/boot/powerkvm.py 2015-10-29 16:19:48 +0000
+++ src/provisioningserver/boot/powerkvm.py 2016-02-24 16:23:03 +0000
@@ -41,7 +41,7 @@
41class PowerKVMBootMethod(BootMethod):41class PowerKVMBootMethod(BootMethod):
4242
43 name = "powerkvm"43 name = "powerkvm"
44 bios_boot_method = "pxe"44 bios_boot_method = "powerkvm"
45 template_subdir = None45 template_subdir = None
46 bootloader_path = "bootppc64.bin"46 bootloader_path = "bootppc64.bin"
47 bootloader_arches = ['ppc64el']47 bootloader_arches = ['ppc64el']
4848
=== modified file 'src/provisioningserver/boot/powernv.py'
--- src/provisioningserver/boot/powernv.py 2015-08-14 13:48:59 +0000
+++ src/provisioningserver/boot/powernv.py 2016-02-24 16:23:03 +0000
@@ -68,7 +68,7 @@
68class PowerNVBootMethod(BootMethod):68class PowerNVBootMethod(BootMethod):
6969
70 name = "powernv"70 name = "powernv"
71 bios_boot_method = "pxe"71 bios_boot_method = "powernv"
72 template_subdir = "pxe"72 template_subdir = "pxe"
73 bootloader_path = "pxelinux.0"73 bootloader_path = "pxelinux.0"
74 arch_octet = "00:0E"74 arch_octet = "00:0E"

Subscribers

People subscribed via source and target branches