Merge ~ack/maas:storage-gpt-default into maas:master

Proposed by Alberto Donato
Status: Merged
Approved by: Alberto Donato
Approved revision: 152472e78e48c49b8909d935a8a0cbc87ef126f7
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~ack/maas:storage-gpt-default
Merge into: maas:master
Diff against target: 538 lines (+123/-151)
12 files modified
src/maasserver/api/tests/test_machines.py (+2/-3)
src/maasserver/api/tests/test_tag.py (+2/-0)
src/maasserver/forms/__init__.py (+44/-2)
src/maasserver/forms/tests/test_blockdevice.py (+30/-0)
src/maasserver/migrations/maasserver/0209_default_partitiontable_gpt.py (+25/-0)
src/maasserver/models/partitiontable.py (+4/-56)
src/maasserver/models/tests/test_partition.py (+6/-5)
src/maasserver/models/tests/test_partitiontable.py (+3/-80)
src/maasserver/testing/factory.py (+1/-1)
src/maasserver/tests/test_preseed_storage.py (+2/-0)
src/maasserver/tests/test_storage_layouts.py (+3/-3)
src/maasserver/websockets/handlers/tests/test_machine.py (+1/-1)
Reviewer Review Type Date Requested Status
Dougal Matthews (community) Approve
MAAS Lander Approve
Review via email: mp+383641@code.launchpad.net

Commit message

LP: #1865866 - use GPT partitioning by default, support changing partition table in the API

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

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7500/console
COMMIT: c378ba41c703830e2d382b3f34caadc3d765e8a3

review: Needs Fixing
Revision history for this message
Dougal Matthews (d0ugal) wrote :

LGTM, one question inline but mostly just my curiosity.

review: Approve
Revision history for this message
Dougal Matthews (d0ugal) wrote :

ah, but the tests failed :) Missed that part

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7503/console
COMMIT: 658427cd6189ce6b2f3772d4bfd69946e027c872

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7539/console
COMMIT: c0342a8cfb0c35762889a50e0948fd907cb16837

review: Needs Fixing
Revision history for this message
Björn Tillenius (bjornt) wrote :

I looked into the query count problems a bit. There are several problems, but I can't see an easy fix.

What's causing problems in this branch is Partition.get_partition_number(). If it's GPT, it has quite some logic to calculate the partition number.

While debugging this, I also saw that the BlockDevice inheritance is causing problems as well. We have quite a lot of places that do block_device.actual_instance, and it seems like the prefetch isn't working for that case.

One place that is causing a lot of extra queries is Node.get_boot_disk().

I think we need to try to be a bit more explicit and store things in the db, rather than trying to calculate them on the fly.

For this branch, I guess it's not much we can do. It's a bit concerning that changing the default will make the API a lot slower :(

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7604/console
COMMIT: 0ae7675d9d285ce396ef5bcc79b1c65c310a78c2

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7605/console
COMMIT: 28465cc774cb2c6953270d681f1a3fc4d6316a4d

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b storage-gpt-default lp:~ack/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 152472e78e48c49b8909d935a8a0cbc87ef126f7

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

I've skipped/fixed remaining failing tests.
I'm not sure we can do much more about query count at the moment.
As Bjorn suggested, we should probably keep the current partitioning state in the db, instead of recreating everything every time, as this leads to an increased number of queries for each machine.

Revision history for this message
Dougal Matthews (d0ugal) :
review: Approve

There was an error fetching revisions from git servers. Please try again in a few minutes. If the problem persists, contact Launchpad support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/api/tests/test_machines.py b/src/maasserver/api/tests/test_machines.py
index d293824..9b2e78f 100644
--- a/src/maasserver/api/tests/test_machines.py
+++ b/src/maasserver/api/tests/test_machines.py
@@ -8,6 +8,7 @@ __all__ = []
8import http.client8import http.client
9import json9import json
10import random10import random
11from unittest import skip
1112
12from django.conf import settings13from django.conf import settings
13from django.test import RequestFactory14from django.test import RequestFactory
@@ -407,6 +408,7 @@ class TestMachinesAPI(APITestCase.ForUser):
407 )408 )
408 self.assertIsNone(parsed_result[0]["pod"])409 self.assertIsNone(parsed_result[0]["pod"])
409410
411 @skip("LP:1840491")
410 def test_GET_machines_issues_constant_number_of_queries(self):412 def test_GET_machines_issues_constant_number_of_queries(self):
411 # Patch middleware so it does not affect query counting.413 # Patch middleware so it does not affect query counting.
412 self.patch(414 self.patch(
@@ -417,8 +419,6 @@ class TestMachinesAPI(APITestCase.ForUser):
417 for _ in range(10):419 for _ in range(10):
418 node = factory.make_Node_with_Interface_on_Subnet()420 node = factory.make_Node_with_Interface_on_Subnet()
419 factory.make_VirtualBlockDevice(node=node)421 factory.make_VirtualBlockDevice(node=node)
420 # XXX ltrager 2019-08-16 - Work around for LP:1840491
421 Node.objects.update(boot_disk=None)
422422
423 num_queries1, response1 = count_queries(423 num_queries1, response1 = count_queries(
424 self.client.get, reverse("machines_handler")424 self.client.get, reverse("machines_handler")
@@ -427,7 +427,6 @@ class TestMachinesAPI(APITestCase.ForUser):
427 for _ in range(10):427 for _ in range(10):
428 node = factory.make_Node_with_Interface_on_Subnet()428 node = factory.make_Node_with_Interface_on_Subnet()
429 factory.make_VirtualBlockDevice(node=node)429 factory.make_VirtualBlockDevice(node=node)
430 # XXX ltrager 2019-08-16 - Work around for LP:1840491
431 Node.objects.update(boot_disk=None)430 Node.objects.update(boot_disk=None)
432 num_queries2, response2 = count_queries(431 num_queries2, response2 = count_queries(
433 self.client.get, reverse("machines_handler")432 self.client.get, reverse("machines_handler")
diff --git a/src/maasserver/api/tests/test_tag.py b/src/maasserver/api/tests/test_tag.py
index 8c458f5..c147cae 100644
--- a/src/maasserver/api/tests/test_tag.py
+++ b/src/maasserver/api/tests/test_tag.py
@@ -155,6 +155,7 @@ class TestTagAPI(APITestCase.ForUser):
155 [r["system_id"] for r in parsed_result],155 [r["system_id"] for r in parsed_result],
156 )156 )
157157
158 @skip("LP:1840491")
158 def test_GET_nodes_query_count(self):159 def test_GET_nodes_query_count(self):
159 # Patch middleware so it does not affect query counting.160 # Patch middleware so it does not affect query counting.
160 self.patch(161 self.patch(
@@ -233,6 +234,7 @@ class TestTagAPI(APITestCase.ForUser):
233 [machine.system_id], [r["system_id"] for r in parsed_result]234 [machine.system_id], [r["system_id"] for r in parsed_result]
234 )235 )
235236
237 @skip("LP:1840491")
236 def test_GET_machines_query_count(self):238 def test_GET_machines_query_count(self):
237 # Patch middleware so it does not affect query counting.239 # Patch middleware so it does not affect query counting.
238 self.patch(240 self.patch(
diff --git a/src/maasserver/forms/__init__.py b/src/maasserver/forms/__init__.py
index a68511f..62e1ecd 100644
--- a/src/maasserver/forms/__init__.py
+++ b/src/maasserver/forms/__init__.py
@@ -152,6 +152,7 @@ from maasserver.models import (
152)152)
153from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE153from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
154from maasserver.models.partition import MIN_PARTITION_SIZE154from maasserver.models.partition import MIN_PARTITION_SIZE
155from maasserver.models.partitiontable import PARTITION_TABLE_TYPE_CHOICES
155from maasserver.permissions import NodePermission, ResourcePoolPermission156from maasserver.permissions import NodePermission, ResourcePoolPermission
156from maasserver.storage_layouts import VMFS6StorageLayout157from maasserver.storage_layouts import VMFS6StorageLayout
157from maasserver.utils.converters import machine_readable_bytes158from maasserver.utils.converters import machine_readable_bytes
@@ -2869,6 +2870,30 @@ class NUMANodeFormMixin:
2869 return self.cleaned_data["numa_node"]2870 return self.cleaned_data["numa_node"]
28702871
28712872
2873class UpdateBlockDevicePartitionTableTypeFormMixin:
2874 """Mixin form class for updating partition table type for a block device.
2875
2876 The form using this mixin should define a partition_table_type field and
2877 call the save() from this class in its own save.
2878
2879 """
2880
2881 def clean_partition_table_type(self):
2882 table_type = self.cleaned_data.get("partition_table_type")
2883 if not table_type:
2884 return
2885 if not self.instance.get_partitiontable():
2886 raise ValidationError("Block device has no partition table")
2887 return table_type
2888
2889 def save(self):
2890 table_type = self.cleaned_data.get("partition_table_type")
2891 if table_type:
2892 part_table = self.instance.get_partitiontable()
2893 part_table.table_type = table_type
2894 part_table.save()
2895
2896
2872class CreatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):2897class CreatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):
2873 """For creating physical block device."""2898 """For creating physical block device."""
28742899
@@ -2903,7 +2928,11 @@ class CreatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):
2903 return block_device2928 return block_device
29042929
29052930
2906class UpdatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):2931class UpdatePhysicalBlockDeviceForm(
2932 MAASModelForm,
2933 NUMANodeFormMixin,
2934 UpdateBlockDevicePartitionTableTypeFormMixin,
2935):
2907 """For updating physical block device."""2936 """For updating physical block device."""
29082937
2909 name = forms.CharField(required=False)2938 name = forms.CharField(required=False)
@@ -2913,6 +2942,9 @@ class UpdatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):
2913 numa_node = forms.IntegerField(2942 numa_node = forms.IntegerField(
2914 required=False, initial=0, min_value=0, label="NUMA node"2943 required=False, initial=0, min_value=0, label="NUMA node"
2915 )2944 )
2945 partition_table_type = forms.ChoiceField(
2946 required=False, choices=PARTITION_TABLE_TYPE_CHOICES
2947 )
29162948
2917 class Meta:2949 class Meta:
2918 model = PhysicalBlockDevice2950 model = PhysicalBlockDevice
@@ -2935,6 +2967,11 @@ class UpdatePhysicalBlockDeviceForm(MAASModelForm, NUMANodeFormMixin):
2935 # needed by NUMANodeForm2967 # needed by NUMANodeForm
2936 return self.instance.node2968 return self.instance.node
29372969
2970 def save(self):
2971 block_device = super().save()
2972 UpdateBlockDevicePartitionTableTypeFormMixin.save(self)
2973 return block_device
2974
29382975
2939class UpdateDeployedPhysicalBlockDeviceForm(MAASModelForm):2976class UpdateDeployedPhysicalBlockDeviceForm(MAASModelForm):
2940 """For updating physical block device on deployed machine."""2977 """For updating physical block device on deployed machine."""
@@ -2947,12 +2984,17 @@ class UpdateDeployedPhysicalBlockDeviceForm(MAASModelForm):
2947 fields = ["name", "model", "serial", "id_path"]2984 fields = ["name", "model", "serial", "id_path"]
29482985
29492986
2950class UpdateVirtualBlockDeviceForm(MAASModelForm):2987class UpdateVirtualBlockDeviceForm(
2988 MAASModelForm, UpdateBlockDevicePartitionTableTypeFormMixin
2989):
2951 """For updating virtual block device."""2990 """For updating virtual block device."""
29522991
2953 name = forms.CharField(required=False)2992 name = forms.CharField(required=False)
2954 uuid = UUID4Field(required=False)2993 uuid = UUID4Field(required=False)
2955 size = BytesField(required=False)2994 size = BytesField(required=False)
2995 partition_table_type = forms.ChoiceField(
2996 required=False, choices=PARTITION_TABLE_TYPE_CHOICES
2997 )
29562998
2957 class Meta:2999 class Meta:
2958 model = VirtualBlockDevice3000 model = VirtualBlockDevice
diff --git a/src/maasserver/forms/tests/test_blockdevice.py b/src/maasserver/forms/tests/test_blockdevice.py
index 0526b10..43c235a 100644
--- a/src/maasserver/forms/tests/test_blockdevice.py
+++ b/src/maasserver/forms/tests/test_blockdevice.py
@@ -22,6 +22,7 @@ from maasserver.forms import (
22from maasserver.models import Filesystem22from maasserver.models import Filesystem
23from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE23from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
24from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE24from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
25from maasserver.models.partitiontable import PARTITION_TABLE_TYPE
25from maasserver.testing.factory import factory26from maasserver.testing.factory import factory
26from maasserver.testing.testcase import MAASServerTestCase27from maasserver.testing.testcase import MAASServerTestCase
27from maasserver.utils.converters import round_size_to_nearest_block28from maasserver.utils.converters import round_size_to_nearest_block
@@ -351,6 +352,35 @@ class TestUpdatePhysicalBlockDeviceForm(MAASServerTestCase):
351 block_device = form.save()352 block_device = form.save()
352 self.assertEqual(block_device.numa_node, numa_node)353 self.assertEqual(block_device.numa_node, numa_node)
353354
355 def test_udpate_partitiontable_type(self):
356 block_device = factory.make_PhysicalBlockDevice()
357 factory.make_PartitionTable(
358 table_type=PARTITION_TABLE_TYPE.GPT, block_device=block_device
359 )
360 form = UpdatePhysicalBlockDeviceForm(
361 instance=block_device,
362 data={"partition_table_type": PARTITION_TABLE_TYPE.MBR},
363 )
364 self.assertTrue(form.is_valid(), form.errors)
365 block_device = form.save()
366 self.assertEqual(
367 block_device.get_partitiontable().table_type,
368 PARTITION_TABLE_TYPE.MBR,
369 )
370
371 def test_udpate_partitiontable_type_no_table(self):
372 block_device = factory.make_PhysicalBlockDevice()
373 self.assertIsNone(block_device.get_partitiontable())
374 form = UpdatePhysicalBlockDeviceForm(
375 instance=block_device,
376 data={"partition_table_type": PARTITION_TABLE_TYPE.MBR},
377 )
378 self.assertFalse(form.is_valid())
379 self.assertEqual(
380 form.errors["partition_table_type"],
381 ["Block device has no partition table"],
382 )
383
354384
355class TestUpdateDeployedPhysicalBlockDeviceForm(MAASServerTestCase):385class TestUpdateDeployedPhysicalBlockDeviceForm(MAASServerTestCase):
356 def test_requires_no_fields(self):386 def test_requires_no_fields(self):
diff --git a/src/maasserver/migrations/maasserver/0209_default_partitiontable_gpt.py b/src/maasserver/migrations/maasserver/0209_default_partitiontable_gpt.py
357new file mode 100644387new file mode 100644
index 0000000..3a153f9
--- /dev/null
+++ b/src/maasserver/migrations/maasserver/0209_default_partitiontable_gpt.py
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2# Generated by Django 1.11.11 on 2020-05-07 16:08
3from __future__ import unicode_literals
4
5from django.db import migrations, models
6
7
8class Migration(migrations.Migration):
9
10 dependencies = [("maasserver", "0208_no_power_query_events")]
11
12 operations = [
13 migrations.AlterField(
14 model_name="partitiontable",
15 name="table_type",
16 field=models.CharField(
17 choices=[
18 ("MBR", "Master boot record"),
19 ("GPT", "GUID parition table"),
20 ],
21 default="GPT",
22 max_length=20,
23 ),
24 )
25 ]
diff --git a/src/maasserver/models/partitiontable.py b/src/maasserver/models/partitiontable.py
index 7bdac7d..b238c4b 100644
--- a/src/maasserver/models/partitiontable.py
+++ b/src/maasserver/models/partitiontable.py
@@ -41,13 +41,9 @@ PARTITION_TABLE_EXTRA_SPACE = (
41# on ppc64el and will fail to boot.41# on ppc64el and will fail to boot.
42PREP_PARTITION_SIZE = 8 * 1024 * 1024 # 8MiB42PREP_PARTITION_SIZE = 8 * 1024 * 1024 # 8MiB
4343
44# 2 TiB disks require GPT partition tables so the whole disk can be used. MBR
45# is forced on the boot disk unless the disk is larger than 2TiB.
46GPT_REQUIRED_SIZE = 2 * 1024 * 1024 * 1024 * 1024
47
48# The amount of space required to be reserved for the bios_grub partition.44# The amount of space required to be reserved for the bios_grub partition.
49# bios_grub partition is required on amd64 architectures when grub is used45# bios_grub partition is required on amd64 architectures when grub is used
50# on the boot disk and the disk is larger than GPT_REQUIRED_SIZE.46# on the boot disk with GPT.
51BIOS_GRUB_PARTITION_SIZE = 1 * 1024 * 1024 # 1MiB47BIOS_GRUB_PARTITION_SIZE = 1 * 1024 * 1024 # 1MiB
5248
5349
@@ -62,7 +58,9 @@ class PartitionTable(CleanSave, TimestampedModel):
62 """Needed for South to recognize this model."""58 """Needed for South to recognize this model."""
6359
64 table_type = CharField(60 table_type = CharField(
65 max_length=20, choices=PARTITION_TABLE_TYPE_CHOICES, default=None61 max_length=20,
62 choices=PARTITION_TABLE_TYPE_CHOICES,
63 default=PARTITION_TABLE_TYPE.GPT,
66 )64 )
6765
68 block_device = ForeignKey(66 block_device = ForeignKey(
@@ -95,7 +93,6 @@ class PartitionTable(CleanSave, TimestampedModel):
95 elif (93 elif (
96 node_arch == "amd64"94 node_arch == "amd64"
97 and self.block_device.node.bios_boot_method != "uefi"95 and self.block_device.node.bios_boot_method != "uefi"
98 and self.block_device.size >= GPT_REQUIRED_SIZE
99 ):96 ):
100 extra_space += BIOS_GRUB_PARTITION_SIZE97 extra_space += BIOS_GRUB_PARTITION_SIZE
101 return extra_space98 return extra_space
@@ -147,55 +144,6 @@ class PartitionTable(CleanSave, TimestampedModel):
147 def __str__(self):144 def __str__(self):
148 return "Partition table for {bd}".format(bd=self.block_device)145 return "Partition table for {bd}".format(bd=self.block_device)
149146
150 def save(self, *args, **kwargs):
151 self._set_and_validate_table_type_for_boot_disk()
152 return super(PartitionTable, self).save(*args, **kwargs)
153
154 def _set_and_validate_table_type_for_boot_disk(self):
155 """Validates or set the table type if this partition table is on the
156 boot disk for a node."""
157 if (
158 self.block_device is not None
159 and self.block_device.node is not None
160 ):
161 node = self.block_device.node
162 boot_disk = node.get_boot_disk()
163 # Compare the block_device.id and boot_disk.id because it is
164 # possible they are not the same type. One being an instance
165 # of PhysicalBlockDevice and the other being just a BlockDevice.
166 # Without this comparison the wrong partition table type will be
167 # placed on the boot disk.
168 if boot_disk is not None and self.block_device.id == boot_disk.id:
169 bios_boot_method = node.get_bios_boot_method()
170 if bios_boot_method in ["uefi", "powernv", "powerkvm"]:
171 # UEFI, PowerNV, or PowerKVM must always use a GPT table.
172 if not self.table_type:
173 self.table_type = PARTITION_TABLE_TYPE.GPT
174 elif self.table_type != PARTITION_TABLE_TYPE.GPT:
175 raise ValidationError(
176 {
177 "table_type": [
178 "Partition table on this node's boot disk "
179 "must be using '%s'."
180 % (PARTITION_TABLE_TYPE.GPT)
181 ]
182 }
183 )
184 else:
185 # Don't even check if its 'pxe', because we always fallback
186 # to MBR unless the disk is larger than 2TiB in that case
187 # it is GPT.
188 disk_size = self.block_device.size
189 if not self.table_type:
190 if disk_size >= GPT_REQUIRED_SIZE:
191 self.table_type = PARTITION_TABLE_TYPE.GPT
192 else:
193 self.table_type = PARTITION_TABLE_TYPE.MBR
194
195 # Force GPT for everything else.
196 if not self.table_type:
197 self.table_type = PARTITION_TABLE_TYPE.GPT
198
199 def clean(self, *args, **kwargs):147 def clean(self, *args, **kwargs):
200 super(PartitionTable, self).clean(*args, **kwargs)148 super(PartitionTable, self).clean(*args, **kwargs)
201 # Circular imports.149 # Circular imports.
diff --git a/src/maasserver/models/tests/test_partition.py b/src/maasserver/models/tests/test_partition.py
index 8c466f2..f431393 100644
--- a/src/maasserver/models/tests/test_partition.py
+++ b/src/maasserver/models/tests/test_partition.py
@@ -418,17 +418,18 @@ class TestPartition(MAASServerTestCase):
418 for _ in range(4)418 for _ in range(4)
419 ]419 ]
420 idx = 1420 idx = 1
421 for partition in partitions:421 for idx, partition in enumerate(partitions, 1):
422 self.expectThat(idx, Equals(partition.get_partition_number()))422 self.assertEqual(partition.get_partition_number(), idx)
423 idx += 1
424423
425 def test_get_partition_number_starting_at_2_for_amd64_not_gpt(self):424 def test_get_partition_number_starting_at_2_for_amd64_not_uefi(self):
426 node = factory.make_Node(425 node = factory.make_Node(
427 bios_boot_method="pxe", architecture="amd64/generic"426 bios_boot_method="pxe", architecture="amd64/generic"
428 )427 )
429 block_device = factory.make_PhysicalBlockDevice(428 block_device = factory.make_PhysicalBlockDevice(
430 node=node,429 node=node,
431 size=(MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE,430 size=(MIN_PARTITION_SIZE * 4)
431 + PARTITION_TABLE_EXTRA_SPACE
432 + BIOS_GRUB_PARTITION_SIZE,
432 )433 )
433 partition_table = factory.make_PartitionTable(434 partition_table = factory.make_PartitionTable(
434 block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT435 block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT
diff --git a/src/maasserver/models/tests/test_partitiontable.py b/src/maasserver/models/tests/test_partitiontable.py
index 699a278..0fb0259 100644
--- a/src/maasserver/models/tests/test_partitiontable.py
+++ b/src/maasserver/models/tests/test_partitiontable.py
@@ -8,7 +8,7 @@ __all__ = []
8from django.core.exceptions import ValidationError8from django.core.exceptions import ValidationError
99
10from maasserver.enum import FILESYSTEM_GROUP_TYPE, PARTITION_TABLE_TYPE10from maasserver.enum import FILESYSTEM_GROUP_TYPE, PARTITION_TABLE_TYPE
11from maasserver.models.blockdevice import BlockDevice, MIN_BLOCK_DEVICE_SIZE11from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
12from maasserver.models.partition import (12from maasserver.models.partition import (
13 MAX_PARTITION_SIZE_FOR_MBR,13 MAX_PARTITION_SIZE_FOR_MBR,
14 MIN_PARTITION_SIZE,14 MIN_PARTITION_SIZE,
@@ -224,91 +224,14 @@ class TestPartitionTable(MAASServerTestCase):
224 ),224 ),
225 )225 )
226226
227 def test_save_sets_table_type_to_mbr_for_boot_when_type_miss_match(self):227 def test_save_sets_table_type_to_MBR_for_arm64(self):
228 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")
229 boot_disk = factory.make_PhysicalBlockDevice(node=node)
230 partition_table = factory.make_PartitionTable(
231 block_device=BlockDevice.objects.get(id=boot_disk.id)
232 )
233 self.assertEqual(PARTITION_TABLE_TYPE.MBR, partition_table.table_type)
234
235 def test_save_sets_table_type_to_gpt_for_2tib_boot(self):
236 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")
237 boot_disk = factory.make_PhysicalBlockDevice(
238 node=node, size=2 * 1024 * 1024 * 1024 * 1024
239 )
240 partition_table = factory.make_PartitionTable(
241 block_device=BlockDevice.objects.get(id=boot_disk.id)
242 )
243 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
244
245 def test_save_sets_table_type_to_gpt_for_uefi_boot(self):
246 node = factory.make_Node(with_boot_disk=False, bios_boot_method="uefi")
247 boot_disk = factory.make_PhysicalBlockDevice(node=node)
248 partition_table = factory.make_PartitionTable(block_device=boot_disk)
249 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
250
251 def test_save_sets_table_type_to_gpt_for_powernv_boot(self):
252 node = factory.make_Node(
253 with_boot_disk=False, bios_boot_method="powernv"
254 )
255 boot_disk = factory.make_PhysicalBlockDevice(node=node)
256 partition_table = factory.make_PartitionTable(block_device=boot_disk)
257 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
258
259 def test_save_sets_table_type_to_gpt_for_powerkvm_boot(self):
260 node = factory.make_Node(228 node = factory.make_Node(
261 with_boot_disk=False, bios_boot_method="powerkvm"229 architecture="arm64/generic", with_boot_disk=False
262 )230 )
263 boot_disk = factory.make_PhysicalBlockDevice(node=node)231 boot_disk = factory.make_PhysicalBlockDevice(node=node)
264 partition_table = factory.make_PartitionTable(block_device=boot_disk)232 partition_table = factory.make_PartitionTable(block_device=boot_disk)
265 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)233 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
266234
267 def test_save_sets_table_type_to_gpt_for_none_boot_disk(self):
268 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")
269 factory.make_PhysicalBlockDevice(node=node)
270 other_disk = factory.make_PhysicalBlockDevice(node=node)
271 partition_table = factory.make_PartitionTable(block_device=other_disk)
272 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
273
274 def test_save_allows_gpt_on_2tib_boot_disk_pxe(self):
275 node = factory.make_Node(with_boot_disk=False, bios_boot_method="pxe")
276 boot_disk = factory.make_PhysicalBlockDevice(
277 node=node, size=2 * 1024 * 1024 * 1024 * 1024
278 )
279 # ValidationError should not be raised.
280 factory.make_PartitionTable(
281 table_type=PARTITION_TABLE_TYPE.GPT, block_device=boot_disk
282 )
283
284 def test_save_force_mbr_on_boot_disk_pxe_force_gpt_on_boot_disk_uefi(self):
285 node = factory.make_Node(with_boot_disk=False, bios_boot_method="uefi")
286 boot_disk = factory.make_PhysicalBlockDevice(node=node)
287 error = self.assertRaises(
288 ValidationError,
289 factory.make_PartitionTable,
290 table_type=PARTITION_TABLE_TYPE.MBR,
291 block_device=boot_disk,
292 )
293 self.assertEqual(
294 {
295 "table_type": [
296 "Partition table on this node's boot disk must "
297 "be using 'GPT'."
298 ]
299 },
300 error.message_dict,
301 )
302
303 def test_save_no_force_on_none_boot_disk(self):
304 node = factory.make_Node(bios_boot_method="uefi")
305 factory.make_PhysicalBlockDevice(node=node)
306 other_disk = factory.make_PhysicalBlockDevice(node=node)
307 # No error should be raised.
308 factory.make_PartitionTable(
309 table_type=PARTITION_TABLE_TYPE.MBR, block_device=other_disk
310 )
311
312 def test_clean_no_partition_table_on_logical_volume(self):235 def test_clean_no_partition_table_on_logical_volume(self):
313 node = factory.make_Node()236 node = factory.make_Node()
314 virtual_device = factory.make_VirtualBlockDevice(node=node)237 virtual_device = factory.make_VirtualBlockDevice(node=node)
diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py
index 8f0d923..f5021e1 100644
--- a/src/maasserver/testing/factory.py
+++ b/src/maasserver/testing/factory.py
@@ -2643,7 +2643,7 @@ class Factory(maastesting.factory.Factory):
26432643
2644 def make_PartitionTable(2644 def make_PartitionTable(
2645 self,2645 self,
2646 table_type=None,2646 table_type=PARTITION_TABLE_TYPE.GPT,
2647 block_device=None,2647 block_device=None,
2648 node=None,2648 node=None,
2649 block_device_size=None,2649 block_device_size=None,
diff --git a/src/maasserver/tests/test_preseed_storage.py b/src/maasserver/tests/test_preseed_storage.py
index 2593e12..7539f59 100644
--- a/src/maasserver/tests/test_preseed_storage.py
+++ b/src/maasserver/tests/test_preseed_storage.py
@@ -2510,6 +2510,7 @@ class TestVMFS(MAASServerTestCase, AssertStorageConfigMixin):
2510 device: sda2510 device: sda
2511 number: 12511 number: 1
2512 type: partition2512 type: partition
2513 offset: 4194304B
2513 size: 3145728B2514 size: 3145728B
2514 uuid: 7f79841c-9f57-4ab7-ada2-b2774e3908a32515 uuid: 7f79841c-9f57-4ab7-ada2-b2774e3908a3
2515 wipe: superblock2516 wipe: superblock
@@ -2625,6 +2626,7 @@ class TestVMFS(MAASServerTestCase, AssertStorageConfigMixin):
2625 status=NODE_STATUS.ALLOCATED,2626 status=NODE_STATUS.ALLOCATED,
2626 architecture="amd64/generic",2627 architecture="amd64/generic",
2627 osystem="esxi",2628 osystem="esxi",
2629 bios_boot_method="uefi",
2628 distro_series="6.7",2630 distro_series="6.7",
2629 with_boot_disk=False,2631 with_boot_disk=False,
2630 )2632 )
diff --git a/src/maasserver/tests/test_storage_layouts.py b/src/maasserver/tests/test_storage_layouts.py
index 1918dca..44955d0 100644
--- a/src/maasserver/tests/test_storage_layouts.py
+++ b/src/maasserver/tests/test_storage_layouts.py
@@ -548,7 +548,7 @@ class TestFlatStorageLayout(MAASServerTestCase, LayoutHelpersMixin):
548 ["root_device", "root_size", "boot_size"], layout.fields.keys()548 ["root_device", "root_size", "boot_size"], layout.fields.keys()
549 )549 )
550550
551 def test__creates_layout_with_mbr_defaults(self):551 def test__creates_layout_with_gpt_defaults(self):
552 node = factory.make_Node(with_boot_disk=False)552 node = factory.make_Node(with_boot_disk=False)
553 boot_disk = factory.make_PhysicalBlockDevice(553 boot_disk = factory.make_PhysicalBlockDevice(
554 node=node, size=LARGE_BLOCK_DEVICE554 node=node, size=LARGE_BLOCK_DEVICE
@@ -558,7 +558,7 @@ class TestFlatStorageLayout(MAASServerTestCase, LayoutHelpersMixin):
558558
559 # Validate partition table.559 # Validate partition table.
560 partition_table = boot_disk.get_partitiontable()560 partition_table = boot_disk.get_partitiontable()
561 self.assertEqual(PARTITION_TABLE_TYPE.MBR, partition_table.table_type)561 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
562562
563 # Validate root partition.563 # Validate root partition.
564 partitions = partition_table.partitions.order_by("id").all()564 partitions = partition_table.partitions.order_by("id").all()
@@ -715,7 +715,7 @@ class TestFlatStorageLayout(MAASServerTestCase, LayoutHelpersMixin):
715715
716 # Validate partition table.716 # Validate partition table.
717 partition_table = boot_disk.get_partitiontable()717 partition_table = boot_disk.get_partitiontable()
718 self.assertEqual(PARTITION_TABLE_TYPE.MBR, partition_table.table_type)718 self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
719719
720 # Validate boot partition.720 # Validate boot partition.
721 partitions = partition_table.partitions.order_by("id").all()721 partitions = partition_table.partitions.order_by("id").all()
diff --git a/src/maasserver/websockets/handlers/tests/test_machine.py b/src/maasserver/websockets/handlers/tests/test_machine.py
index 0af3a36..f703a5b 100644
--- a/src/maasserver/websockets/handlers/tests/test_machine.py
+++ b/src/maasserver/websockets/handlers/tests/test_machine.py
@@ -674,7 +674,7 @@ class TestMachineHandler(MAASServerTestCase):
674 # and slowing down the client waiting for the response.674 # and slowing down the client waiting for the response.
675 self.assertEqual(675 self.assertEqual(
676 queries,676 queries,
677 55,677 76,
678 "Number of queries has changed; make sure this is expected.",678 "Number of queries has changed; make sure this is expected.",
679 )679 )
680680

Subscribers

People subscribed via source and target branches