Merge lp:~blake-rouse/maas/fix-1630667 into lp:~maas-committers/maas/trunk
- fix-1630667
- Merge into trunk
Proposed by
Blake Rouse
Status: | Merged |
---|---|
Approved by: | Andres Rodriguez |
Approved revision: | no longer in the source branch. |
Merged at revision: | 5474 |
Proposed branch: | lp:~blake-rouse/maas/fix-1630667 |
Merge into: | lp:~maas-committers/maas/trunk |
Diff against target: |
424 lines (+206/-16) 6 files modified
src/maasserver/models/partition.py (+12/-3) src/maasserver/models/partitiontable.py (+9/-0) src/maasserver/models/tests/test_partition.py (+25/-3) src/maasserver/models/tests/test_partitiontable.py (+25/-0) src/maasserver/preseed_storage.py (+51/-7) src/maasserver/tests/test_preseed_storage.py (+84/-3) |
To merge this branch: | bzr merge lp:~blake-rouse/maas/fix-1630667 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mike Pontillo (community) | Approve | ||
Review via email: mp+307965@code.launchpad.net |
Commit message
Create bios_grub partition on boot disk when the machine is set to PXE boot and the boot disk is larger than 2TiB on amd64.
On i386 machines they cannot use more than a 2TiB disk so this is limited to only amd64. When the boot disk is larger than 2TiB the first partition placed on the disk is now bios_grub flagged partition. Grub will use this partition to place it stage 1 similar to how MBR works. This is only used for PXE booted machines, UEFI machines do not create this partition and still use the /boot/efi partition to place the bootloader.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/maasserver/models/partition.py' | |||
2 | --- src/maasserver/models/partition.py 2016-05-12 19:07:37 +0000 | |||
3 | +++ src/maasserver/models/partition.py 2016-10-07 15:48:42 +0000 | |||
4 | @@ -172,21 +172,30 @@ | |||
5 | 172 | 172 | ||
6 | 173 | def get_partition_number(self): | 173 | def get_partition_number(self): |
7 | 174 | """Return the partition number in the table.""" | 174 | """Return the partition number in the table.""" |
8 | 175 | # Circular imports. | ||
9 | 176 | from maasserver.models.partitiontable import GPT_REQUIRED_SIZE | ||
10 | 175 | # Sort manually instead of with `order_by`, this will prevent django | 177 | # Sort manually instead of with `order_by`, this will prevent django |
11 | 176 | # from making a query if the partitions are already cached. | 178 | # from making a query if the partitions are already cached. |
12 | 177 | partitions_in_table = self.partition_table.partitions.all() | 179 | partitions_in_table = self.partition_table.partitions.all() |
13 | 178 | partitions_in_table = sorted(partitions_in_table, key=attrgetter('id')) | 180 | partitions_in_table = sorted(partitions_in_table, key=attrgetter('id')) |
14 | 179 | idx = partitions_in_table.index(self) | 181 | idx = partitions_in_table.index(self) |
15 | 180 | if self.partition_table.table_type == PARTITION_TABLE_TYPE.GPT: | 182 | if self.partition_table.table_type == PARTITION_TABLE_TYPE.GPT: |
19 | 181 | # ppc64el machines get part1 skipped when this partition is on | 183 | # In some instances the first partition is skipped because it |
20 | 182 | # the boot disk. This is because the prep partition is part1 and | 184 | # is used by the machine architecture for a specific reason. |
21 | 183 | # is added when the preseed for storage is generated. | 185 | # * ppc64el - reserved for prep partition |
22 | 186 | # * amd64 (disk >= 2TiB) - reserved for bios_grub partition | ||
23 | 184 | node = self.get_node() | 187 | node = self.get_node() |
24 | 185 | arch, _ = node.split_arch() | 188 | arch, _ = node.split_arch() |
25 | 186 | boot_disk = node.get_boot_disk() | 189 | boot_disk = node.get_boot_disk() |
26 | 190 | bios_boot_method = node.get_bios_boot_method() | ||
27 | 187 | if (arch == "ppc64el" and | 191 | if (arch == "ppc64el" and |
28 | 188 | self.partition_table.block_device.id == boot_disk.id): | 192 | self.partition_table.block_device.id == boot_disk.id): |
29 | 189 | return idx + 2 | 193 | return idx + 2 |
30 | 194 | elif (arch == "amd64" and | ||
31 | 195 | self.partition_table.block_device.id == boot_disk.id and | ||
32 | 196 | bios_boot_method != "uefi" and | ||
33 | 197 | boot_disk.size >= GPT_REQUIRED_SIZE): | ||
34 | 198 | return idx + 2 | ||
35 | 190 | else: | 199 | else: |
36 | 191 | return idx + 1 | 200 | return idx + 1 |
37 | 192 | elif self.partition_table.table_type == PARTITION_TABLE_TYPE.MBR: | 201 | elif self.partition_table.table_type == PARTITION_TABLE_TYPE.MBR: |
38 | 193 | 202 | ||
39 | === modified file 'src/maasserver/models/partitiontable.py' | |||
40 | --- src/maasserver/models/partitiontable.py 2016-10-03 18:57:27 +0000 | |||
41 | +++ src/maasserver/models/partitiontable.py 2016-10-07 15:48:42 +0000 | |||
42 | @@ -51,6 +51,11 @@ | |||
43 | 51 | # is forced on the boot disk unless the disk is larger than 2TiB. | 51 | # is forced on the boot disk unless the disk is larger than 2TiB. |
44 | 52 | GPT_REQUIRED_SIZE = 2 * 1024 * 1024 * 1024 * 1024 | 52 | GPT_REQUIRED_SIZE = 2 * 1024 * 1024 * 1024 * 1024 |
45 | 53 | 53 | ||
46 | 54 | # The amount of space required to be reserved for the bios_grub partition. | ||
47 | 55 | # bios_grub partition is required on amd64 architectures when grub is used | ||
48 | 56 | # on the boot disk and the disk is larger than GPT_REQUIRED_SIZE. | ||
49 | 57 | BIOS_GRUB_PARTITION_SIZE = 1 * 1024 * 1024 # 1MiB | ||
50 | 58 | |||
51 | 54 | 59 | ||
52 | 55 | class PartitionTable(CleanSave, TimestampedModel): | 60 | class PartitionTable(CleanSave, TimestampedModel): |
53 | 56 | """A partition table on a block device. | 61 | """A partition table on a block device. |
54 | @@ -90,6 +95,10 @@ | |||
55 | 90 | node_arch, _ = self.block_device.node.split_arch() | 95 | node_arch, _ = self.block_device.node.split_arch() |
56 | 91 | if node_arch == "ppc64el": | 96 | if node_arch == "ppc64el": |
57 | 92 | extra_space += PREP_PARTITION_SIZE | 97 | extra_space += PREP_PARTITION_SIZE |
58 | 98 | elif (node_arch == "amd64" and | ||
59 | 99 | self.block_device.node.bios_boot_method != "uefi" and | ||
60 | 100 | self.block_device.size >= GPT_REQUIRED_SIZE): | ||
61 | 101 | extra_space += BIOS_GRUB_PARTITION_SIZE | ||
62 | 93 | return extra_space | 102 | return extra_space |
63 | 94 | 103 | ||
64 | 95 | def get_used_size(self, ignore_partitions=[]): | 104 | def get_used_size(self, ignore_partitions=[]): |
65 | 96 | 105 | ||
66 | === modified file 'src/maasserver/models/tests/test_partition.py' | |||
67 | --- src/maasserver/models/tests/test_partition.py 2016-05-12 19:07:37 +0000 | |||
68 | +++ src/maasserver/models/tests/test_partition.py 2016-10-07 15:48:42 +0000 | |||
69 | @@ -6,7 +6,6 @@ | |||
70 | 6 | __all__ = [] | 6 | __all__ = [] |
71 | 7 | 7 | ||
72 | 8 | import random | 8 | import random |
73 | 9 | from unittest import skip | ||
74 | 10 | from unittest.mock import sentinel | 9 | from unittest.mock import sentinel |
75 | 11 | from uuid import uuid4 | 10 | from uuid import uuid4 |
76 | 12 | 11 | ||
77 | @@ -25,6 +24,7 @@ | |||
78 | 25 | PARTITION_ALIGNMENT_SIZE, | 24 | PARTITION_ALIGNMENT_SIZE, |
79 | 26 | ) | 25 | ) |
80 | 27 | from maasserver.models.partitiontable import ( | 26 | from maasserver.models.partitiontable import ( |
81 | 27 | BIOS_GRUB_PARTITION_SIZE, | ||
82 | 28 | PARTITION_TABLE_EXTRA_SPACE, | 28 | PARTITION_TABLE_EXTRA_SPACE, |
83 | 29 | PREP_PARTITION_SIZE, | 29 | PREP_PARTITION_SIZE, |
84 | 30 | ) | 30 | ) |
85 | @@ -306,10 +306,10 @@ | |||
86 | 306 | self.expectThat(idx, Equals(partition.get_partition_number())) | 306 | self.expectThat(idx, Equals(partition.get_partition_number())) |
87 | 307 | idx += 1 | 307 | idx += 1 |
88 | 308 | 308 | ||
89 | 309 | @skip("XXX: GavinPanella 2016-04-12 bug=1569365: Fails spuriously.") | ||
90 | 310 | def test_get_partition_number_returns_starting_at_2_for_ppc64el(self): | 309 | def test_get_partition_number_returns_starting_at_2_for_ppc64el(self): |
91 | 311 | node = factory.make_Node( | 310 | node = factory.make_Node( |
93 | 312 | architecture="ppc64el/generic", bios_boot_method="uefi") | 311 | architecture="ppc64el/generic", bios_boot_method="uefi", |
94 | 312 | with_boot_disk=False) | ||
95 | 313 | block_device = factory.make_PhysicalBlockDevice( | 313 | block_device = factory.make_PhysicalBlockDevice( |
96 | 314 | node=node, | 314 | node=node, |
97 | 315 | size=( | 315 | size=( |
98 | @@ -328,6 +328,28 @@ | |||
99 | 328 | self.expectThat(idx, Equals(partition.get_partition_number())) | 328 | self.expectThat(idx, Equals(partition.get_partition_number())) |
100 | 329 | idx += 1 | 329 | idx += 1 |
101 | 330 | 330 | ||
102 | 331 | def test_get_partition_number_returns_starting_at_2_for_amd64_gpt(self): | ||
103 | 332 | node = factory.make_Node( | ||
104 | 333 | architecture="amd64/generic", bios_boot_method="pxe", | ||
105 | 334 | with_boot_disk=False) | ||
106 | 335 | block_device = factory.make_PhysicalBlockDevice( | ||
107 | 336 | node=node, | ||
108 | 337 | size=( | ||
109 | 338 | (2 * (1024 ** 4)) + PARTITION_TABLE_EXTRA_SPACE + | ||
110 | 339 | BIOS_GRUB_PARTITION_SIZE)) | ||
111 | 340 | node.boot_disk = block_device | ||
112 | 341 | node.save() | ||
113 | 342 | partition_table = factory.make_PartitionTable( | ||
114 | 343 | block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT) | ||
115 | 344 | partitions = [ | ||
116 | 345 | partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) | ||
117 | 346 | for _ in range(4) | ||
118 | 347 | ] | ||
119 | 348 | idx = 2 | ||
120 | 349 | for partition in partitions: | ||
121 | 350 | self.expectThat(idx, Equals(partition.get_partition_number())) | ||
122 | 351 | idx += 1 | ||
123 | 352 | |||
124 | 331 | def test_get_partition_number_returns_correct_numbering_for_mbr(self): | 353 | def test_get_partition_number_returns_correct_numbering_for_mbr(self): |
125 | 332 | block_device = factory.make_PhysicalBlockDevice( | 354 | block_device = factory.make_PhysicalBlockDevice( |
126 | 333 | size=(MIN_BLOCK_DEVICE_SIZE * 6) + PARTITION_TABLE_EXTRA_SPACE) | 355 | size=(MIN_BLOCK_DEVICE_SIZE * 6) + PARTITION_TABLE_EXTRA_SPACE) |
127 | 334 | 356 | ||
128 | === modified file 'src/maasserver/models/tests/test_partitiontable.py' | |||
129 | --- src/maasserver/models/tests/test_partitiontable.py 2016-10-03 18:57:27 +0000 | |||
130 | +++ src/maasserver/models/tests/test_partitiontable.py 2016-10-07 15:48:42 +0000 | |||
131 | @@ -20,6 +20,7 @@ | |||
132 | 20 | PARTITION_ALIGNMENT_SIZE, | 20 | PARTITION_ALIGNMENT_SIZE, |
133 | 21 | ) | 21 | ) |
134 | 22 | from maasserver.models.partitiontable import ( | 22 | from maasserver.models.partitiontable import ( |
135 | 23 | BIOS_GRUB_PARTITION_SIZE, | ||
136 | 23 | PARTITION_TABLE_EXTRA_SPACE, | 24 | PARTITION_TABLE_EXTRA_SPACE, |
137 | 24 | PREP_PARTITION_SIZE, | 25 | PREP_PARTITION_SIZE, |
138 | 25 | ) | 26 | ) |
139 | @@ -59,6 +60,20 @@ | |||
140 | 59 | False), | 60 | False), |
141 | 60 | partition_table.get_size()) | 61 | partition_table.get_size()) |
142 | 61 | 62 | ||
143 | 63 | def test_get_size_returns_block_device_size_minus_amd64_gpt(self): | ||
144 | 64 | node = factory.make_Node(architecture="amd64/generic") | ||
145 | 65 | block_device = factory.make_PhysicalBlockDevice( | ||
146 | 66 | node=node, size=2 * (1024 ** 4)) | ||
147 | 67 | partition_table = factory.make_PartitionTable( | ||
148 | 68 | block_device=block_device) | ||
149 | 69 | self.assertEqual( | ||
150 | 70 | round_size_to_nearest_block( | ||
151 | 71 | partition_table.block_device.size - | ||
152 | 72 | PARTITION_TABLE_EXTRA_SPACE - BIOS_GRUB_PARTITION_SIZE, | ||
153 | 73 | PARTITION_ALIGNMENT_SIZE, | ||
154 | 74 | False), | ||
155 | 75 | partition_table.get_size()) | ||
156 | 76 | |||
157 | 62 | def test_get_block_size_returns_block_device_block_size(self): | 77 | def test_get_block_size_returns_block_device_block_size(self): |
158 | 63 | partition_table = factory.make_PartitionTable() | 78 | partition_table = factory.make_PartitionTable() |
159 | 64 | self.assertEqual( | 79 | self.assertEqual( |
160 | @@ -148,6 +163,16 @@ | |||
161 | 148 | PARTITION_TABLE_EXTRA_SPACE + PREP_PARTITION_SIZE, | 163 | PARTITION_TABLE_EXTRA_SPACE + PREP_PARTITION_SIZE, |
162 | 149 | partition_table.get_overhead_size()) | 164 | partition_table.get_overhead_size()) |
163 | 150 | 165 | ||
164 | 166 | def test_get_overhead_size_for_amd64_gpt(self): | ||
165 | 167 | node = factory.make_Node(architecture="amd64/generic") | ||
166 | 168 | block_device = factory.make_PhysicalBlockDevice( | ||
167 | 169 | node=node, size=2 * (1024 ** 4)) | ||
168 | 170 | partition_table = factory.make_PartitionTable( | ||
169 | 171 | block_device=block_device) | ||
170 | 172 | self.assertEquals( | ||
171 | 173 | PARTITION_TABLE_EXTRA_SPACE + BIOS_GRUB_PARTITION_SIZE, | ||
172 | 174 | partition_table.get_overhead_size()) | ||
173 | 175 | |||
174 | 151 | def test_get_available_size(self): | 176 | def test_get_available_size(self): |
175 | 152 | block_size = 4096 | 177 | block_size = 4096 |
176 | 153 | device = factory.make_BlockDevice( | 178 | device = factory.make_BlockDevice( |
177 | 154 | 179 | ||
178 | === modified file 'src/maasserver/preseed_storage.py' | |||
179 | --- src/maasserver/preseed_storage.py 2016-10-04 18:37:44 +0000 | |||
180 | +++ src/maasserver/preseed_storage.py 2016-10-07 15:48:42 +0000 | |||
181 | @@ -17,6 +17,7 @@ | |||
182 | 17 | ) | 17 | ) |
183 | 18 | from maasserver.models.partition import Partition | 18 | from maasserver.models.partition import Partition |
184 | 19 | from maasserver.models.partitiontable import ( | 19 | from maasserver.models.partitiontable import ( |
185 | 20 | BIOS_GRUB_PARTITION_SIZE, | ||
186 | 20 | GPT_REQUIRED_SIZE, | 21 | GPT_REQUIRED_SIZE, |
187 | 21 | INITIAL_PARTITION_OFFSET, | 22 | INITIAL_PARTITION_OFFSET, |
188 | 22 | PARTITION_TABLE_EXTRA_SPACE, | 23 | PARTITION_TABLE_EXTRA_SPACE, |
189 | @@ -118,6 +119,15 @@ | |||
190 | 118 | self.boot_disk.id == block_device.id and | 119 | self.boot_disk.id == block_device.id and |
191 | 119 | arch == "ppc64el") | 120 | arch == "ppc64el") |
192 | 120 | 121 | ||
193 | 122 | def _requires_bios_grub_partition(self, block_device): | ||
194 | 123 | """Return True if block device requires the bios_grub partition.""" | ||
195 | 124 | arch, _ = self.node.split_arch() | ||
196 | 125 | bios_boot_method = self.node.get_bios_boot_method() | ||
197 | 126 | return ( | ||
198 | 127 | arch == "amd64" and | ||
199 | 128 | bios_boot_method != "uefi" and | ||
200 | 129 | block_device.size >= GPT_REQUIRED_SIZE) | ||
201 | 130 | |||
202 | 121 | def _add_partition_operations(self): | 131 | def _add_partition_operations(self): |
203 | 122 | """Add all the partition operations. | 132 | """Add all the partition operations. |
204 | 123 | 133 | ||
205 | @@ -126,14 +136,16 @@ | |||
206 | 126 | """ | 136 | """ |
207 | 127 | for block_device in self.node.blockdevice_set.order_by('id'): | 137 | for block_device in self.node.blockdevice_set.order_by('id'): |
208 | 128 | requires_prep = self._requires_prep_partition(block_device) | 138 | requires_prep = self._requires_prep_partition(block_device) |
209 | 139 | requires_bios_grub = self._requires_bios_grub_partition( | ||
210 | 140 | block_device) | ||
211 | 129 | partition_table = block_device.get_partitiontable() | 141 | partition_table = block_device.get_partitiontable() |
212 | 130 | if partition_table is not None: | 142 | if partition_table is not None: |
213 | 131 | partitions = list(partition_table.partitions.order_by('id')) | 143 | partitions = list(partition_table.partitions.order_by('id')) |
214 | 132 | for idx, partition in enumerate(partitions): | 144 | for idx, partition in enumerate(partitions): |
219 | 133 | # If this is the last partition and prep partition is | 145 | # If this is the first partition and prep or bios_grub |
220 | 134 | # required then set boot_disk_first_partition so extra | 146 | # partition is required then set boot_disk_first_partition |
221 | 135 | # space can be removed. | 147 | # so partition creation can occur in the correct order. |
222 | 136 | if requires_prep and idx == 0: | 148 | if (requires_prep or requires_bios_grub) and idx == 0: |
223 | 137 | self.boot_disk_first_partition = partition | 149 | self.boot_disk_first_partition = partition |
224 | 138 | self.operations["partition"].append(partition) | 150 | self.operations["partition"].append(partition) |
225 | 139 | 151 | ||
226 | @@ -195,6 +207,7 @@ | |||
227 | 195 | # Set the partition table type if a partition table exists or if this | 207 | # Set the partition table type if a partition table exists or if this |
228 | 196 | # is the boot disk. | 208 | # is the boot disk. |
229 | 197 | add_prep_partition = False | 209 | add_prep_partition = False |
230 | 210 | add_bios_grub_partition = False | ||
231 | 198 | partition_table = block_device.get_partitiontable() | 211 | partition_table = block_device.get_partitiontable() |
232 | 199 | if partition_table is not None: | 212 | if partition_table is not None: |
233 | 200 | disk_operation["ptable"] = self._get_ptable_type( | 213 | disk_operation["ptable"] = self._get_ptable_type( |
234 | @@ -207,8 +220,10 @@ | |||
235 | 207 | disk_operation["ptable"] = "gpt" | 220 | disk_operation["ptable"] = "gpt" |
236 | 208 | if node_arch == "ppc64el": | 221 | if node_arch == "ppc64el": |
237 | 209 | add_prep_partition = True | 222 | add_prep_partition = True |
239 | 210 | elif block_device.size >= GPT_REQUIRED_SIZE: | 223 | elif (block_device.size >= GPT_REQUIRED_SIZE and |
240 | 224 | node_arch == "amd64"): | ||
241 | 211 | disk_operation["ptable"] = "gpt" | 225 | disk_operation["ptable"] = "gpt" |
242 | 226 | add_bios_grub_partition = True | ||
243 | 212 | else: | 227 | else: |
244 | 213 | disk_operation["ptable"] = "msdos" | 228 | disk_operation["ptable"] = "msdos" |
245 | 214 | 229 | ||
246 | @@ -221,10 +236,16 @@ | |||
247 | 221 | disk_operation["grub_device"] = True | 236 | disk_operation["grub_device"] = True |
248 | 222 | self.storage_config.append(disk_operation) | 237 | self.storage_config.append(disk_operation) |
249 | 223 | 238 | ||
251 | 224 | # Add the prep partition at the end of the disk when it is required. | 239 | # Add the prep partition at the beginning of the disk |
252 | 240 | # when it is required. | ||
253 | 225 | if add_prep_partition: | 241 | if add_prep_partition: |
254 | 226 | self._generate_prep_partition(block_device.get_name()) | 242 | self._generate_prep_partition(block_device.get_name()) |
255 | 227 | 243 | ||
256 | 244 | # Add the bios_grub partition at the beginning of the disk | ||
257 | 245 | # when it is required. | ||
258 | 246 | if add_bios_grub_partition: | ||
259 | 247 | self._generate_bios_grub_partition(block_device.get_name()) | ||
260 | 248 | |||
261 | 228 | def _get_ptable_type(self, partition_table): | 249 | def _get_ptable_type(self, partition_table): |
262 | 229 | """Return the value for the "ptable" entry in the physical operation. | 250 | """Return the value for the "ptable" entry in the physical operation. |
263 | 230 | """ | 251 | """ |
264 | @@ -254,6 +275,20 @@ | |||
265 | 254 | } | 275 | } |
266 | 255 | self.storage_config.append(partition_operation) | 276 | self.storage_config.append(partition_operation) |
267 | 256 | 277 | ||
268 | 278 | def _generate_bios_grub_partition(self, device_name): | ||
269 | 279 | """Generate the bios_grub partition at the beginning of the device.""" | ||
270 | 280 | partition_operation = { | ||
271 | 281 | "id": "%s-part1" % (device_name), | ||
272 | 282 | "type": "partition", | ||
273 | 283 | "number": 1, | ||
274 | 284 | "offset": "%dB" % INITIAL_PARTITION_OFFSET, | ||
275 | 285 | "size": "%dB" % BIOS_GRUB_PARTITION_SIZE, | ||
276 | 286 | "device": device_name, | ||
277 | 287 | "wipe": "zero", | ||
278 | 288 | "flag": "bios_grub", | ||
279 | 289 | } | ||
280 | 290 | self.storage_config.append(partition_operation) | ||
281 | 291 | |||
282 | 257 | def _generate_partition_operations(self): | 292 | def _generate_partition_operations(self): |
283 | 258 | """Generate all partition operations.""" | 293 | """Generate all partition operations.""" |
284 | 259 | for partition in self.operations["partition"]: | 294 | for partition in self.operations["partition"]: |
285 | @@ -261,7 +296,16 @@ | |||
286 | 261 | # This is the first partition in the boot disk and add prep | 296 | # This is the first partition in the boot disk and add prep |
287 | 262 | # partition at the beginning of the partition table. | 297 | # partition at the beginning of the partition table. |
288 | 263 | device_name = partition.partition_table.block_device.get_name() | 298 | device_name = partition.partition_table.block_device.get_name() |
290 | 264 | self._generate_prep_partition(device_name) | 299 | if self._requires_prep_partition( |
291 | 300 | partition.partition_table.block_device): | ||
292 | 301 | self._generate_prep_partition(device_name) | ||
293 | 302 | elif self._requires_bios_grub_partition( | ||
294 | 303 | partition.partition_table.block_device): | ||
295 | 304 | self._generate_bios_grub_partition(device_name) | ||
296 | 305 | else: | ||
297 | 306 | raise ValueError( | ||
298 | 307 | "boot_disk_first_partition set when prep and " | ||
299 | 308 | "bios_grub partition are not required.") | ||
300 | 265 | self._generate_partition_operation( | 309 | self._generate_partition_operation( |
301 | 266 | partition, include_initial=False) | 310 | partition, include_initial=False) |
302 | 267 | else: | 311 | else: |
303 | 268 | 312 | ||
304 | === modified file 'src/maasserver/tests/test_preseed_storage.py' | |||
305 | --- src/maasserver/tests/test_preseed_storage.py 2016-10-03 18:57:27 +0000 | |||
306 | +++ src/maasserver/tests/test_preseed_storage.py 2016-10-07 15:48:42 +0000 | |||
307 | @@ -22,6 +22,7 @@ | |||
308 | 22 | VolumeGroup, | 22 | VolumeGroup, |
309 | 23 | ) | 23 | ) |
310 | 24 | from maasserver.models.partitiontable import ( | 24 | from maasserver.models.partitiontable import ( |
311 | 25 | BIOS_GRUB_PARTITION_SIZE, | ||
312 | 25 | PARTITION_TABLE_EXTRA_SPACE, | 26 | PARTITION_TABLE_EXTRA_SPACE, |
313 | 26 | PREP_PARTITION_SIZE, | 27 | PREP_PARTITION_SIZE, |
314 | 27 | ) | 28 | ) |
315 | @@ -546,6 +547,14 @@ | |||
316 | 546 | ptable: gpt | 547 | ptable: gpt |
317 | 547 | path: /dev/disk/by-id/wwn-0x55cd2e400009bf84 | 548 | path: /dev/disk/by-id/wwn-0x55cd2e400009bf84 |
318 | 548 | grub_device: true | 549 | grub_device: true |
319 | 550 | - id: sdb-part1 | ||
320 | 551 | type: partition | ||
321 | 552 | number: 1 | ||
322 | 553 | size: 1048576B | ||
323 | 554 | device: sdb | ||
324 | 555 | wipe: zero | ||
325 | 556 | offset: 4194304B | ||
326 | 557 | flag: bios_grub | ||
327 | 549 | - id: sda-part1 | 558 | - id: sda-part1 |
328 | 550 | name: sda-part1 | 559 | name: sda-part1 |
329 | 551 | type: partition | 560 | type: partition |
330 | @@ -570,13 +579,14 @@ | |||
331 | 570 | 579 | ||
332 | 571 | def test__renders_expected_output(self): | 580 | def test__renders_expected_output(self): |
333 | 572 | node = factory.make_Node( | 581 | node = factory.make_Node( |
335 | 573 | status=NODE_STATUS.ALLOCATED, with_boot_disk=False) | 582 | status=NODE_STATUS.ALLOCATED, architecture="amd64/generic", |
336 | 583 | with_boot_disk=False) | ||
337 | 574 | first_disk = factory.make_PhysicalBlockDevice( | 584 | first_disk = factory.make_PhysicalBlockDevice( |
338 | 575 | node=node, size=8 * 1024 ** 3, name="sda", | 585 | node=node, size=8 * 1024 ** 3, name="sda", |
339 | 576 | model="QEMU HARDDISK", serial="QM00001") # 8 GiB | 586 | model="QEMU HARDDISK", serial="QM00001") # 8 GiB |
340 | 577 | boot_disk = factory.make_PhysicalBlockDevice( | 587 | boot_disk = factory.make_PhysicalBlockDevice( |
343 | 578 | node=node, size=8 * 1024 ** 4, name="sdb", | 588 | node=node, size=2 * 1024 ** 4, name="sdb", |
344 | 579 | id_path="/dev/disk/by-id/wwn-0x55cd2e400009bf84") | 589 | id_path="/dev/disk/by-id/wwn-0x55cd2e400009bf84") # 2 TiB |
345 | 580 | node.boot_disk = boot_disk | 590 | node.boot_disk = boot_disk |
346 | 581 | node.save() | 591 | node.save() |
347 | 582 | partition_table = factory.make_PartitionTable( | 592 | partition_table = factory.make_PartitionTable( |
348 | @@ -596,6 +606,77 @@ | |||
349 | 596 | self.assertStorageConfig(self.STORAGE_CONFIG, config) | 606 | self.assertStorageConfig(self.STORAGE_CONFIG, config) |
350 | 597 | 607 | ||
351 | 598 | 608 | ||
352 | 609 | class TestGPTPXELargeBootDiskLayout( | ||
353 | 610 | MAASServerTestCase, AssertStorageConfigMixin): | ||
354 | 611 | |||
355 | 612 | STORAGE_CONFIG = dedent("""\ | ||
356 | 613 | config: | ||
357 | 614 | - id: sda | ||
358 | 615 | name: sda | ||
359 | 616 | type: disk | ||
360 | 617 | wipe: superblock | ||
361 | 618 | ptable: gpt | ||
362 | 619 | model: QEMU HARDDISK | ||
363 | 620 | serial: QM00001 | ||
364 | 621 | grub_device: true | ||
365 | 622 | - id: sda-part1 | ||
366 | 623 | type: partition | ||
367 | 624 | number: 1 | ||
368 | 625 | size: 1048576B | ||
369 | 626 | device: sda | ||
370 | 627 | wipe: zero | ||
371 | 628 | offset: 4194304B | ||
372 | 629 | flag: bios_grub | ||
373 | 630 | - id: sda-part2 | ||
374 | 631 | name: sda-part2 | ||
375 | 632 | type: partition | ||
376 | 633 | number: 2 | ||
377 | 634 | uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398 | ||
378 | 635 | size: 8581545984B | ||
379 | 636 | device: sda | ||
380 | 637 | wipe: superblock | ||
381 | 638 | - id: sda-part2_format | ||
382 | 639 | type: format | ||
383 | 640 | fstype: ext4 | ||
384 | 641 | label: root | ||
385 | 642 | uuid: 90a69b22-e281-4c5b-8df9-b09514f27ba1 | ||
386 | 643 | volume: sda-part2 | ||
387 | 644 | - id: sda-part2_mount | ||
388 | 645 | type: mount | ||
389 | 646 | path: / | ||
390 | 647 | options: rw,relatime,errors=remount-ro,data=journal | ||
391 | 648 | device: sda-part2_format | ||
392 | 649 | """) | ||
393 | 650 | |||
394 | 651 | def test__renders_expected_output(self): | ||
395 | 652 | node = factory.make_Node( | ||
396 | 653 | status=NODE_STATUS.ALLOCATED, architecture="amd64/generic", | ||
397 | 654 | with_boot_disk=False) | ||
398 | 655 | boot_disk = factory.make_PhysicalBlockDevice( | ||
399 | 656 | node=node, size=2 * 1024 ** 4, name="sda", | ||
400 | 657 | model="QEMU HARDDISK", serial="QM00001") # 2 TiB | ||
401 | 658 | node.boot_disk = boot_disk | ||
402 | 659 | node.save() | ||
403 | 660 | partition_table = factory.make_PartitionTable( | ||
404 | 661 | table_type=PARTITION_TABLE_TYPE.GPT, block_device=boot_disk) | ||
405 | 662 | root_partition = factory.make_Partition( | ||
406 | 663 | partition_table=partition_table, | ||
407 | 664 | uuid="6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398", | ||
408 | 665 | size=( | ||
409 | 666 | (8 * 1024 ** 3) - | ||
410 | 667 | PARTITION_TABLE_EXTRA_SPACE - | ||
411 | 668 | BIOS_GRUB_PARTITION_SIZE), | ||
412 | 669 | bootable=False) | ||
413 | 670 | factory.make_Filesystem( | ||
414 | 671 | partition=root_partition, fstype=FILESYSTEM_TYPE.EXT4, | ||
415 | 672 | uuid="90a69b22-e281-4c5b-8df9-b09514f27ba1", label="root", | ||
416 | 673 | mount_point="/", mount_options=( | ||
417 | 674 | "rw,relatime,errors=remount-ro,data=journal")) | ||
418 | 675 | node._create_acquired_filesystems() | ||
419 | 676 | config = compose_curtin_storage_config(node) | ||
420 | 677 | self.assertStorageConfig(self.STORAGE_CONFIG, config) | ||
421 | 678 | |||
422 | 679 | |||
423 | 599 | class TestComplexDiskLayout( | 680 | class TestComplexDiskLayout( |
424 | 600 | MAASServerTestCase, AssertStorageConfigMixin): | 681 | MAASServerTestCase, AssertStorageConfigMixin): |
425 | 601 | 682 |
Looks good to me.