Merge lp:~trapnine/maas/fix-1513085 into lp:~maas-committers/maas/trunk

Proposed by Jeffrey C Jones
Status: Merged
Approved by: Jeffrey C Jones
Approved revision: no longer in the source branch.
Merged at revision: 4504
Proposed branch: lp:~trapnine/maas/fix-1513085
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 1347 lines (+256/-192)
21 files modified
src/maasserver/api/tests/test_raid.py (+6/-12)
src/maasserver/api/tests/test_volume_groups.py (+13/-4)
src/maasserver/forms.py (+2/-1)
src/maasserver/models/blockdevice.py (+1/-1)
src/maasserver/models/partition.py (+7/-7)
src/maasserver/models/partitiontable.py (+21/-17)
src/maasserver/models/tests/test_blockdevice.py (+4/-2)
src/maasserver/models/tests/test_filesystemgroup.py (+27/-33)
src/maasserver/models/tests/test_partition.py (+9/-8)
src/maasserver/models/tests/test_partitiontable.py (+27/-18)
src/maasserver/models/virtualblockdevice.py (+21/-11)
src/maasserver/testing/factory.py (+1/-3)
src/maasserver/tests/test_forms_blockdevice.py (+5/-1)
src/maasserver/tests/test_forms_partition.py (+5/-5)
src/maasserver/tests/test_forms_raid.py (+5/-9)
src/maasserver/tests/test_forms_volume_group.py (+7/-2)
src/maasserver/tests/test_preseed_storage.py (+14/-14)
src/maasserver/tests/test_storage_layouts.py (+43/-32)
src/maasserver/utils/converters.py (+5/-3)
src/maasserver/utils/tests/test_converters.py (+22/-6)
src/maasserver/websockets/handlers/tests/test_node.py (+11/-3)
To merge this branch: bzr merge lp:~trapnine/maas/fix-1513085
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+277409@code.launchpad.net

Commit message

Align partitions and logical volumes to 4MiB.

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

Looks really good. Good work. Please backport his change as well. Let me know if you need help with this.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/api/tests/test_raid.py'
--- src/maasserver/api/tests/test_raid.py 2015-10-28 17:32:43 +0000
+++ src/maasserver/api/tests/test_raid.py 2015-11-16 07:08:21 +0000
@@ -403,10 +403,8 @@
403 (parsed_block_devices, parsed_partitions,403 (parsed_block_devices, parsed_partitions,
404 parsed_block_device_spares, parsed_partition_spares) = (404 parsed_block_device_spares, parsed_partition_spares) = (
405 get_devices_from_raid(parsed_device))405 get_devices_from_raid(parsed_device))
406 # Size is equivalent to 7 devices of 9 TB each.406 # Size is equivalent to 7 of the smallest device (the partitions).
407 self.assertEqual(407 self.assertEqual(7 * large_partitions[0].size, parsed_device['size'])
408 7 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE),
409 parsed_device['size'])
410 self.assertItemsEqual(block_devices, parsed_block_devices)408 self.assertItemsEqual(block_devices, parsed_block_devices)
411 self.assertItemsEqual(partitions, parsed_partitions)409 self.assertItemsEqual(partitions, parsed_partitions)
412 self.assertItemsEqual(spare_devices, parsed_block_device_spares)410 self.assertItemsEqual(spare_devices, parsed_block_device_spares)
@@ -450,10 +448,8 @@
450 (parsed_block_devices, parsed_partitions,448 (parsed_block_devices, parsed_partitions,
451 parsed_block_device_spares, parsed_partition_spares) = (449 parsed_block_device_spares, parsed_partition_spares) = (
452 get_devices_from_raid(parsed_device))450 get_devices_from_raid(parsed_device))
453 # Size is equivalent to 6 devices of 9 TB each.451 # Size is equivalent to 6 of the smallest device (the partitions).
454 self.assertEqual(452 self.assertEqual(6 * large_partitions[0].size, parsed_device['size'])
455 6 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE),
456 parsed_device['size'])
457 self.assertItemsEqual(block_devices, parsed_block_devices)453 self.assertItemsEqual(block_devices, parsed_block_devices)
458 self.assertItemsEqual(partitions, parsed_partitions)454 self.assertItemsEqual(partitions, parsed_partitions)
459 self.assertItemsEqual(spare_devices, parsed_block_device_spares)455 self.assertItemsEqual(spare_devices, parsed_block_device_spares)
@@ -497,10 +493,8 @@
497 (parsed_block_devices, parsed_partitions,493 (parsed_block_devices, parsed_partitions,
498 parsed_block_device_spares, parsed_partition_spares) = (494 parsed_block_device_spares, parsed_partition_spares) = (
499 get_devices_from_raid(parsed_device))495 get_devices_from_raid(parsed_device))
500 # Size is equivalent to 4 devices of 9 TB each.496 # Size is equivalent to 4 of the smallest device (the partitions).
501 self.assertEqual(497 self.assertEqual(4 * large_partitions[0].size, parsed_device['size'])
502 4 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE),
503 parsed_device['size'])
504 self.assertItemsEqual(block_devices, parsed_block_devices)498 self.assertItemsEqual(block_devices, parsed_block_devices)
505 self.assertItemsEqual(partitions, parsed_partitions)499 self.assertItemsEqual(partitions, parsed_partitions)
506 self.assertItemsEqual(spare_devices, parsed_block_device_spares)500 self.assertItemsEqual(spare_devices, parsed_block_device_spares)
507501
=== modified file 'src/maasserver/api/tests/test_volume_groups.py'
--- src/maasserver/api/tests/test_volume_groups.py 2015-09-24 16:22:12 +0000
+++ src/maasserver/api/tests/test_volume_groups.py 2015-11-16 07:08:21 +0000
@@ -26,11 +26,18 @@
26 NODE_STATUS,26 NODE_STATUS,
27)27)
28from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE28from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
29from maasserver.models.partition import (
30 MIN_PARTITION_SIZE,
31 PARTITION_ALIGNMENT_SIZE,
32)
29from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE33from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
30from maasserver.testing.api import APITestCase34from maasserver.testing.api import APITestCase
31from maasserver.testing.factory import factory35from maasserver.testing.factory import factory
32from maasserver.testing.orm import reload_object36from maasserver.testing.orm import reload_object
33from maasserver.utils.converters import human_readable_bytes37from maasserver.utils.converters import (
38 human_readable_bytes,
39 round_size_to_nearest_block,
40)
34from testtools.matchers import (41from testtools.matchers import (
35 ContainsDict,42 ContainsDict,
36 Equals,43 Equals,
@@ -132,11 +139,11 @@
132 ]139 ]
133 block_device = factory.make_PhysicalBlockDevice(140 block_device = factory.make_PhysicalBlockDevice(
134 node=node,141 node=node,
135 size=(MIN_BLOCK_DEVICE_SIZE * 3) + PARTITION_TABLE_EXTRA_SPACE)142 size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE)
136 partition_table = factory.make_PartitionTable(143 partition_table = factory.make_PartitionTable(
137 block_device=block_device)144 block_device=block_device)
138 partitions = [145 partitions = [
139 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)146 partition_table.add_partition(size=MIN_PARTITION_SIZE)
140 for _ in range(2)147 for _ in range(2)
141 ]148 ]
142 partition_ids = [149 partition_ids = [
@@ -411,10 +418,12 @@
411 })418 })
412 self.assertEqual(httplib.OK, response.status_code, response.content)419 self.assertEqual(httplib.OK, response.status_code, response.content)
413 logical_volume = json.loads(response.content)420 logical_volume = json.loads(response.content)
421 expected_size = round_size_to_nearest_block(
422 size, PARTITION_ALIGNMENT_SIZE, False)
414 self.assertThat(logical_volume, ContainsDict({423 self.assertThat(logical_volume, ContainsDict({
415 "name": Equals("%s-%s" % (volume_group.name, name)),424 "name": Equals("%s-%s" % (volume_group.name, name)),
416 "uuid": Equals(vguuid),425 "uuid": Equals(vguuid),
417 "size": Equals(size),426 "size": Equals(expected_size),
418 }))427 }))
419428
420 def test_delete_logical_volume_204_when_invalid_id(self):429 def test_delete_logical_volume_204_when_invalid_id(self):
421430
=== modified file 'src/maasserver/forms.py'
--- src/maasserver/forms.py 2015-11-02 16:32:29 +0000
+++ src/maasserver/forms.py 2015-11-16 07:08:21 +0000
@@ -154,6 +154,7 @@
154 nodegroup_fqdn,154 nodegroup_fqdn,
155)155)
156from maasserver.models.nodegroup import NODEGROUP_CLUSTER_NAME_TEMPLATE156from maasserver.models.nodegroup import NODEGROUP_CLUSTER_NAME_TEMPLATE
157from maasserver.models.partition import MIN_PARTITION_SIZE
157from maasserver.models.subnet import (158from maasserver.models.subnet import (
158 create_cidr,159 create_cidr,
159 Subnet,160 Subnet,
@@ -3253,7 +3254,7 @@
3253 This needs to be done on the fly so that we can pass the maximum size.3254 This needs to be done on the fly so that we can pass the maximum size.
3254 """3255 """
3255 self.fields['size'] = BytesField(3256 self.fields['size'] = BytesField(
3256 min_value=MIN_BLOCK_DEVICE_SIZE,3257 min_value=MIN_PARTITION_SIZE,
3257 max_value=self.block_device.size,3258 max_value=self.block_device.size,
3258 required=True)3259 required=True)
32593260
32603261
=== modified file 'src/maasserver/models/blockdevice.py'
--- src/maasserver/models/blockdevice.py 2015-10-28 01:59:30 +0000
+++ src/maasserver/models/blockdevice.py 2015-11-16 07:08:21 +0000
@@ -51,7 +51,7 @@
51)51)
5252
5353
54MIN_BLOCK_DEVICE_SIZE = 2 * 1024 * 1024 # 2MiB54MIN_BLOCK_DEVICE_SIZE = 4 * 1024 * 1024 # 4MiB
55MIN_BLOCK_DEVICE_BLOCK_SIZE = 512 # A ProDOS block55MIN_BLOCK_DEVICE_BLOCK_SIZE = 512 # A ProDOS block
5656
5757
5858
=== modified file 'src/maasserver/models/partition.py'
--- src/maasserver/models/partition.py 2015-10-20 15:02:19 +0000
+++ src/maasserver/models/partition.py 2015-11-16 07:08:21 +0000
@@ -32,7 +32,6 @@
32from django.dispatch import receiver32from django.dispatch import receiver
33from maasserver import DefaultMeta33from maasserver import DefaultMeta
34from maasserver.enum import PARTITION_TABLE_TYPE34from maasserver.enum import PARTITION_TABLE_TYPE
35from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
36from maasserver.models.cleansave import CleanSave35from maasserver.models.cleansave import CleanSave
37from maasserver.models.timestampedmodel import TimestampedModel36from maasserver.models.timestampedmodel import TimestampedModel
38from maasserver.utils.converters import (37from maasserver.utils.converters import (
@@ -45,8 +44,10 @@
45)44)
4645
4746
48MIN_PARTITION_SIZE = MIN_BLOCK_DEVICE_SIZE
49MAX_PARTITION_SIZE_FOR_MBR = (((2 ** 32) - 1) * 512) - (1024 ** 2) # 2 TiB47MAX_PARTITION_SIZE_FOR_MBR = (((2 ** 32) - 1) * 512) - (1024 ** 2) # 2 TiB
48# All partitions are aligned down to 4MiB blocks for performance (lp:1513085)
49PARTITION_ALIGNMENT_SIZE = 4 * 1024 * 1024
50MIN_PARTITION_SIZE = PARTITION_ALIGNMENT_SIZE
5051
5152
52class PartitionManager(Manager):53class PartitionManager(Manager):
@@ -216,17 +217,16 @@
216 bd=self.partition_table.block_device.__unicode__())217 bd=self.partition_table.block_device.__unicode__())
217218
218 def _round_size(self):219 def _round_size(self):
219 """Round the size of this partition to the nearest block."""220 """Round the size of this partition down for alignment."""
220 if self.size is not None and self.partition_table is not None:221 if self.size is not None and self.partition_table is not None:
221 self.size = round_size_to_nearest_block(222 self.size = round_size_to_nearest_block(
222 self.size, self.partition_table.get_block_size())223 self.size, PARTITION_ALIGNMENT_SIZE, False)
223224
224 @classmethod225 @classmethod
225 def _get_mbr_max_for_block_device(self, block_device):226 def _get_mbr_max_for_block_device(self, block_device):
226 """Get the maximum partition size for MBR for this block device."""227 """Get the maximum partition size for MBR for this block device."""
227 block_size = block_device.block_size228 return round_size_to_nearest_block(
228 number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / block_size229 MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False)
229 return block_size * (number_of_blocks - 1)
230230
231 def _get_mbr_max_for_partition(self):231 def _get_mbr_max_for_partition(self):
232 """Get the maximum partition size for MBR for this partition."""232 """Get the maximum partition size for MBR for this partition."""
233233
=== modified file 'src/maasserver/models/partitiontable.py'
--- src/maasserver/models/partitiontable.py 2015-11-04 04:27:46 +0000
+++ src/maasserver/models/partitiontable.py 2015-11-16 07:08:21 +0000
@@ -29,13 +29,17 @@
29)29)
30from maasserver.models.blockdevice import BlockDevice30from maasserver.models.blockdevice import BlockDevice
31from maasserver.models.cleansave import CleanSave31from maasserver.models.cleansave import CleanSave
32from maasserver.models.partition import Partition32from maasserver.models.partition import (
33 Partition,
34 PARTITION_ALIGNMENT_SIZE,
35)
33from maasserver.models.timestampedmodel import TimestampedModel36from maasserver.models.timestampedmodel import TimestampedModel
34from maasserver.utils.converters import round_size_to_nearest_block37from maasserver.utils.converters import round_size_to_nearest_block
3538
36# The first partition on the disk must start at 2MiB, as all previous bytes39# The first 2MiB of the device are used by the partition table and grub. We'll
37# will be used by the partition table and grub.40# reserve the first 4MiB to make sure all partitions stay aligned to 4MB across
38INITIAL_PARTITION_OFFSET = 2 * 1024 * 102441# the device.
42INITIAL_PARTITION_OFFSET = 4 * 1024 * 1024
3943
40# An additional 1MiB of space is left open at the end of the disk to allow for44# An additional 1MiB of space is left open at the end of the disk to allow for
41# the extra MBR table.45# the extra MBR table.
@@ -67,11 +71,11 @@
67 return self.block_device.node71 return self.block_device.node
6872
69 def get_size(self):73 def get_size(self):
70 """Size of partition table."""74 """Total usable size of partition table."""
71 return (75 return round_size_to_nearest_block(
72 self.block_device.size -76 self.block_device.size - PARTITION_TABLE_EXTRA_SPACE,
73 round_size_to_nearest_block(77 PARTITION_ALIGNMENT_SIZE,
74 PARTITION_TABLE_EXTRA_SPACE, self.get_block_size()))78 False)
7579
76 def get_block_size(self):80 def get_block_size(self):
77 """Block size of partition table."""81 """Block size of partition table."""
@@ -89,15 +93,15 @@
89 if used_size is None:93 if used_size is None:
90 used_size = 094 used_size = 0
91 # The extra space taken by the partition table header is used space.95 # The extra space taken by the partition table header is used space.
92 used_size += round_size_to_nearest_block(96 return used_size + PARTITION_TABLE_EXTRA_SPACE
93 PARTITION_TABLE_EXTRA_SPACE, self.get_block_size())
94 return round_size_to_nearest_block(
95 used_size, self.get_block_size())
9697
97 def get_available_size(self, ignore_partitions=[]):98 def get_available_size(self, ignore_partitions=[]):
98 """Return the remaining size available for partitions."""99 """Return the remaining size available for partitions."""
99 used_size = self.get_used_size(ignore_partitions=ignore_partitions)100 used_size = self.get_used_size(ignore_partitions=ignore_partitions)
100 return self.block_device.size - used_size101 # Only report 'alignable' space as available for new partitions
102 return round_size_to_nearest_block(
103 self.block_device.size - used_size,
104 PARTITION_ALIGNMENT_SIZE, False)
101105
102 def add_partition(self, size=None, bootable=False, uuid=None):106 def add_partition(self, size=None, bootable=False, uuid=None):
103 """Adds a partition to this partition table, returns the added107 """Adds a partition to this partition table, returns the added
@@ -105,15 +109,15 @@
105109
106 If size is omitted, the partition will extend to the end of the device.110 If size is omitted, the partition will extend to the end of the device.
107111
108 If size is not a multiple of the device's block size, the size will be112 All partition sizes will be aligned down to PARTITION_ALIGNMENT_SIZE.
109 rounded up to the next multiple.
110 """113 """
111 if size is None:114 if size is None:
112 size = self.get_available_size()115 size = self.get_available_size()
113 if self.table_type == PARTITION_TABLE_TYPE.MBR:116 if self.table_type == PARTITION_TABLE_TYPE.MBR:
114 size = min(size, Partition._get_mbr_max_for_block_device(117 size = min(size, Partition._get_mbr_max_for_block_device(
115 self.block_device))118 self.block_device))
116 size = round_size_to_nearest_block(size, self.get_block_size())119 size = round_size_to_nearest_block(
120 size, PARTITION_ALIGNMENT_SIZE, False)
117 return Partition.objects.create(121 return Partition.objects.create(
118 partition_table=self, size=size, uuid=uuid, bootable=bootable)122 partition_table=self, size=size, uuid=uuid, bootable=bootable)
119123
120124
=== modified file 'src/maasserver/models/tests/test_blockdevice.py'
--- src/maasserver/models/tests/test_blockdevice.py 2015-10-28 01:59:30 +0000
+++ src/maasserver/models/tests/test_blockdevice.py 2015-11-16 07:08:21 +0000
@@ -34,6 +34,7 @@
34 VirtualBlockDevice,34 VirtualBlockDevice,
35 VolumeGroup,35 VolumeGroup,
36)36)
37from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
37from maasserver.testing.factory import factory38from maasserver.testing.factory import factory
38from maasserver.testing.orm import reload_object39from maasserver.testing.orm import reload_object
39from maasserver.testing.testcase import MAASServerTestCase40from maasserver.testing.testcase import MAASServerTestCase
@@ -428,8 +429,9 @@
428 boot_disk = factory.make_PhysicalBlockDevice(node=node)429 boot_disk = factory.make_PhysicalBlockDevice(node=node)
429 partition = boot_disk.create_partition_if_boot_disk()430 partition = boot_disk.create_partition_if_boot_disk()
430 self.assertIsNotNone(partition)431 self.assertIsNotNone(partition)
431 self.assertEquals(432 available_size = boot_disk.get_available_size()
432 boot_disk.get_available_size(), 0,433 self.assertTrue(
434 available_size >= 0 and available_size < PARTITION_ALIGNMENT_SIZE,
433 "Should create a partition for the entire disk.")435 "Should create a partition for the entire disk.")
434436
435437
436438
=== modified file 'src/maasserver/models/tests/test_filesystemgroup.py'
--- src/maasserver/models/tests/test_filesystemgroup.py 2015-11-10 16:55:24 +0000
+++ src/maasserver/models/tests/test_filesystemgroup.py 2015-11-16 07:08:21 +0000
@@ -43,6 +43,7 @@
43 VolumeGroup,43 VolumeGroup,
44 VolumeGroupManager,44 VolumeGroupManager,
45)45)
46from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
46from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE47from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
47from maasserver.models.physicalblockdevice import PhysicalBlockDevice48from maasserver.models.physicalblockdevice import PhysicalBlockDevice
48from maasserver.models.virtualblockdevice import VirtualBlockDevice49from maasserver.models.virtualblockdevice import VirtualBlockDevice
@@ -52,7 +53,10 @@
52 reload_objects,53 reload_objects,
53)54)
54from maasserver.testing.testcase import MAASServerTestCase55from maasserver.testing.testcase import MAASServerTestCase
55from maasserver.utils.converters import machine_readable_bytes56from maasserver.utils.converters import (
57 machine_readable_bytes,
58 round_size_to_nearest_block,
59)
56from maastesting.matchers import (60from maastesting.matchers import (
57 MockCalledOnceWith,61 MockCalledOnceWith,
58 MockNotCalled,62 MockNotCalled,
@@ -327,13 +331,16 @@
327 [filesystem_group.id], result_filesystem_group_ids)331 [filesystem_group.id], result_filesystem_group_ids)
328332
329 def test__bcache_on_partitions(self):333 def test__bcache_on_partitions(self):
330 block_device = factory.make_PhysicalBlockDevice()334 device_size = random.randint(
335 MIN_BLOCK_DEVICE_SIZE * 4, MIN_BLOCK_DEVICE_SIZE * 1024)
336 block_device = factory.make_PhysicalBlockDevice(
337 size=device_size + PARTITION_TABLE_EXTRA_SPACE)
331 partition_table = factory.make_PartitionTable(338 partition_table = factory.make_PartitionTable(
332 block_device=block_device)339 block_device=block_device)
333 partition_one = factory.make_Partition(340 partition_one = factory.make_Partition(
334 partition_table=partition_table)341 partition_table=partition_table, size=device_size / 2)
335 partition_two = factory.make_Partition(342 partition_two = factory.make_Partition(
336 partition_table=partition_table)343 partition_table=partition_table, size=device_size / 2)
337 cache_set = factory.make_CacheSet(partition=partition_one)344 cache_set = factory.make_CacheSet(partition=partition_one)
338 filesystem_backing = factory.make_Filesystem(345 filesystem_backing = factory.make_Filesystem(
339 fstype=FILESYSTEM_TYPE.BCACHE_BACKING, partition=partition_two)346 fstype=FILESYSTEM_TYPE.BCACHE_BACKING, partition=partition_two)
@@ -1324,9 +1331,11 @@
1324 factory.make_VirtualBlockDevice(1331 factory.make_VirtualBlockDevice(
1325 filesystem_group=fsgroup, size=5 * 1000 ** 3)1332 filesystem_group=fsgroup, size=5 * 1000 ** 3)
13261333
1327 self.assertEqual(40 * 1000 ** 3, fsgroup.get_lvm_allocated_size())1334 expected_size = round_size_to_nearest_block(
1335 40 * 1000 ** 3, PARTITION_ALIGNMENT_SIZE, False)
1336 self.assertEqual(expected_size, fsgroup.get_lvm_allocated_size())
1328 self.assertEqual(1337 self.assertEqual(
1329 usable_size - (40 * 1000 ** 3), fsgroup.get_lvm_free_space())1338 usable_size - expected_size, fsgroup.get_lvm_free_space())
13301339
1331 def test_get_virtual_block_device_block_size_returns_backing_for_bc(self):1340 def test_get_virtual_block_device_block_size_returns_backing_for_bc(self):
1332 # This test is not included in the scenario below1341 # This test is not included in the scenario below
@@ -1567,10 +1576,12 @@
1567 logical_volume = volume_group.create_logical_volume(1576 logical_volume = volume_group.create_logical_volume(
1568 name=name, uuid=vguuid, size=size)1577 name=name, uuid=vguuid, size=size)
1569 logical_volume = reload_object(logical_volume)1578 logical_volume = reload_object(logical_volume)
1579 expected_size = round_size_to_nearest_block(
1580 size, PARTITION_ALIGNMENT_SIZE, False)
1570 self.assertThat(logical_volume, MatchesStructure.byEquality(1581 self.assertThat(logical_volume, MatchesStructure.byEquality(
1571 name=name,1582 name=name,
1572 uuid=vguuid,1583 uuid=vguuid,
1573 size=size,1584 size=expected_size,
1574 block_size=volume_group.get_virtual_block_device_block_size(),1585 block_size=volume_group.get_virtual_block_device_block_size(),
1575 ))1586 ))
15761587
@@ -1597,8 +1608,6 @@
1597 bd.get_partitiontable().add_partition()1608 bd.get_partitiontable().add_partition()
1598 for bd in block_devices[5:]1609 for bd in block_devices[5:]
1599 ]1610 ]
1600 # Partition size will be smaller than the disk, because of overhead.
1601 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
1602 spare_block_device = block_devices[0]1611 spare_block_device = block_devices[0]
1603 spare_partition = partitions[0]1612 spare_partition = partitions[0]
1604 uuid = unicode(uuid4())1613 uuid = unicode(uuid4())
@@ -1611,7 +1620,7 @@
1611 spare_devices=[spare_block_device],1620 spare_devices=[spare_block_device],
1612 spare_partitions=[spare_partition])1621 spare_partitions=[spare_partition])
1613 self.assertEqual('md0', raid.name)1622 self.assertEqual('md0', raid.name)
1614 self.assertEqual(6 * partition_size, raid.get_size())1623 self.assertEqual(6 * partitions[1].size, raid.get_size())
1615 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)1624 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)
1616 self.assertEqual(uuid, raid.uuid)1625 self.assertEqual(uuid, raid.uuid)
1617 self.assertEqual(10, raid.filesystems.count())1626 self.assertEqual(10, raid.filesystems.count())
@@ -1689,7 +1698,6 @@
1689 for bd in block_devices[5:]1698 for bd in block_devices[5:]
1690 ]1699 ]
1691 # Partition size will be smaller than the disk, because of overhead.1700 # Partition size will be smaller than the disk, because of overhead.
1692 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
1693 spare_block_device = block_devices[0]1701 spare_block_device = block_devices[0]
1694 spare_partition = partitions[0]1702 spare_partition = partitions[0]
1695 uuid = unicode(uuid4())1703 uuid = unicode(uuid4())
@@ -1702,7 +1710,7 @@
1702 spare_devices=[spare_block_device],1710 spare_devices=[spare_block_device],
1703 spare_partitions=[spare_partition])1711 spare_partitions=[spare_partition])
1704 self.assertEqual('md0', raid.name)1712 self.assertEqual('md0', raid.name)
1705 self.assertEqual(partition_size, raid.get_size())1713 self.assertEqual(partitions[1].size, raid.get_size())
1706 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_1, raid.group_type)1714 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_1, raid.group_type)
1707 self.assertEqual(uuid, raid.uuid)1715 self.assertEqual(uuid, raid.uuid)
1708 self.assertEqual(10, raid.filesystems.count())1716 self.assertEqual(10, raid.filesystems.count())
@@ -1742,8 +1750,6 @@
1742 bd.get_partitiontable().add_partition()1750 bd.get_partitiontable().add_partition()
1743 for bd in block_devices[5:]1751 for bd in block_devices[5:]
1744 ]1752 ]
1745 # Partition size will be smaller than the disk, because of overhead.
1746 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
1747 spare_block_device = block_devices[0]1753 spare_block_device = block_devices[0]
1748 spare_partition = partitions[0]1754 spare_partition = partitions[0]
1749 uuid = unicode(uuid4())1755 uuid = unicode(uuid4())
@@ -1756,7 +1762,7 @@
1756 spare_devices=[spare_block_device],1762 spare_devices=[spare_block_device],
1757 spare_partitions=[spare_partition])1763 spare_partitions=[spare_partition])
1758 self.assertEqual('md0', raid.name)1764 self.assertEqual('md0', raid.name)
1759 self.assertEqual(7 * partition_size, raid.get_size())1765 self.assertEqual(7 * partitions[1].size, raid.get_size())
1760 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_5, raid.group_type)1766 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_5, raid.group_type)
1761 self.assertEqual(uuid, raid.uuid)1767 self.assertEqual(uuid, raid.uuid)
1762 self.assertEqual(10, raid.filesystems.count())1768 self.assertEqual(10, raid.filesystems.count())
@@ -1906,11 +1912,9 @@
1906 partition = factory.make_PartitionTable(1912 partition = factory.make_PartitionTable(
1907 block_device=factory.make_PhysicalBlockDevice(1913 block_device=factory.make_PhysicalBlockDevice(
1908 node=node, size=device_size)).add_partition()1914 node=node, size=device_size)).add_partition()
1909 # Partition size will be smaller than the disk, because of overhead.
1910 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
1911 raid.add_partition(partition, FILESYSTEM_TYPE.RAID)1915 raid.add_partition(partition, FILESYSTEM_TYPE.RAID)
1912 self.assertEqual(11, raid.filesystems.count())1916 self.assertEqual(11, raid.filesystems.count())
1913 self.assertEqual(10 * partition_size, raid.get_size())1917 self.assertEqual(10 * partition.size, raid.get_size())
19141918
1915 def test_add_spare_partition_to_array(self):1919 def test_add_spare_partition_to_array(self):
1916 node = factory.make_Node()1920 node = factory.make_Node()
@@ -1928,11 +1932,9 @@
1928 partition = factory.make_PartitionTable(1932 partition = factory.make_PartitionTable(
1929 block_device=factory.make_PhysicalBlockDevice(1933 block_device=factory.make_PhysicalBlockDevice(
1930 node=node, size=device_size)).add_partition()1934 node=node, size=device_size)).add_partition()
1931 # Partition size will be smaller than the disk, because of overhead.
1932 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
1933 raid.add_partition(partition, FILESYSTEM_TYPE.RAID_SPARE)1935 raid.add_partition(partition, FILESYSTEM_TYPE.RAID_SPARE)
1934 self.assertEqual(11, raid.filesystems.count())1936 self.assertEqual(11, raid.filesystems.count())
1935 self.assertEqual(9 * partition_size, raid.get_size())1937 self.assertEqual(9 * partition.size, raid.get_size())
19361938
1937 def test_add_device_from_another_node_to_array_fails(self):1939 def test_add_device_from_another_node_to_array_fails(self):
1938 node = factory.make_Node()1940 node = factory.make_Node()
@@ -2054,8 +2056,6 @@
2054 node=node, size=device_size)).add_partition()2056 node=node, size=device_size)).add_partition()
2055 for _ in range(4)2057 for _ in range(4)
2056 ]2058 ]
2057 # Partition size will be smaller than the disk, because of overhead.
2058 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
2059 uuid = unicode(uuid4())2059 uuid = unicode(uuid4())
2060 raid = RAID.objects.create_raid(2060 raid = RAID.objects.create_raid(
2061 name='md0',2061 name='md0',
@@ -2070,7 +2070,7 @@
2070 "devices and any number of spares.']}")):2070 "devices and any number of spares.']}")):
2071 raid.remove_partition(partitions[0])2071 raid.remove_partition(partitions[0])
2072 self.assertEqual(4, raid.filesystems.count())2072 self.assertEqual(4, raid.filesystems.count())
2073 self.assertEqual(2 * partition_size, raid.get_size())2073 self.assertEqual(2 * partitions[0].size, raid.get_size())
2074 # Ensure the filesystems are the exact same before and after.2074 # Ensure the filesystems are the exact same before and after.
2075 self.assertItemsEqual(2075 self.assertItemsEqual(
2076 fsids_before, [fs.id for fs in raid.filesystems.all()])2076 fsids_before, [fs.id for fs in raid.filesystems.all()])
@@ -2102,8 +2102,6 @@
2102 node=node, size=device_size)).add_partition()2102 node=node, size=device_size)).add_partition()
2103 for _ in range(10)2103 for _ in range(10)
2104 ]2104 ]
2105 # Partition size will be smaller than the disk, because of overhead.
2106 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
2107 uuid = unicode(uuid4())2105 uuid = unicode(uuid4())
2108 raid = RAID.objects.create_raid(2106 raid = RAID.objects.create_raid(
2109 name='md0',2107 name='md0',
@@ -2113,7 +2111,7 @@
2113 spare_partitions=partitions[-2:])2111 spare_partitions=partitions[-2:])
2114 raid.remove_partition(partitions[0])2112 raid.remove_partition(partitions[0])
2115 self.assertEqual(9, raid.filesystems.count())2113 self.assertEqual(9, raid.filesystems.count())
2116 self.assertEqual(6 * partition_size, raid.get_size())2114 self.assertEqual(6 * partitions[0].size, raid.get_size())
21172115
2118 def test_remove_invalid_partition_from_array_fails(self):2116 def test_remove_invalid_partition_from_array_fails(self):
2119 node = factory.make_Node(bios_boot_method="uefi")2117 node = factory.make_Node(bios_boot_method="uefi")
@@ -2125,8 +2123,6 @@
2125 node=node, size=device_size)).add_partition()2123 node=node, size=device_size)).add_partition()
2126 for _ in range(10)2124 for _ in range(10)
2127 ]2125 ]
2128 # Partition size will be smaller than the disk, because of overhead.
2129 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
2130 uuid = unicode(uuid4())2126 uuid = unicode(uuid4())
2131 raid = RAID.objects.create_raid(2127 raid = RAID.objects.create_raid(
2132 name='md0',2128 name='md0',
@@ -2142,7 +2138,7 @@
2142 block_device=factory.make_PhysicalBlockDevice(2138 block_device=factory.make_PhysicalBlockDevice(
2143 node=node, size=device_size)).add_partition())2139 node=node, size=device_size)).add_partition())
2144 self.assertEqual(10, raid.filesystems.count())2140 self.assertEqual(10, raid.filesystems.count())
2145 self.assertEqual(9 * partition_size, raid.get_size())2141 self.assertEqual(9 * partitions[0].size, raid.get_size())
21462142
2147 def test_remove_device_from_array_fails(self):2143 def test_remove_device_from_array_fails(self):
2148 node = factory.make_Node()2144 node = factory.make_Node()
@@ -2251,8 +2247,6 @@
2251 backing_partition = factory.make_PartitionTable(2247 backing_partition = factory.make_PartitionTable(
2252 block_device=factory.make_PhysicalBlockDevice(2248 block_device=factory.make_PhysicalBlockDevice(
2253 node=node, size=backing_size)).add_partition()2249 node=node, size=backing_size)).add_partition()
2254 # Partition size will be smaller than the disk, because of overhead.
2255 partition_size = backing_size - PARTITION_TABLE_EXTRA_SPACE
2256 uuid = unicode(uuid4())2250 uuid = unicode(uuid4())
2257 bcache = Bcache.objects.create_bcache(2251 bcache = Bcache.objects.create_bcache(
2258 name='bcache0',2252 name='bcache0',
@@ -2262,7 +2256,7 @@
2262 cache_mode=CACHE_MODE_TYPE.WRITEBACK)2256 cache_mode=CACHE_MODE_TYPE.WRITEBACK)
22632257
2264 # Verify the filesystems were properly created on the target devices2258 # Verify the filesystems were properly created on the target devices
2265 self.assertEqual(partition_size, bcache.get_size())2259 self.assertEqual(backing_partition.size, bcache.get_size())
2266 self.assertEqual(2260 self.assertEqual(
2267 FILESYSTEM_TYPE.BCACHE_CACHE,2261 FILESYSTEM_TYPE.BCACHE_CACHE,
2268 cache_partition.get_effective_filesystem().fstype)2262 cache_partition.get_effective_filesystem().fstype)
22692263
=== modified file 'src/maasserver/models/tests/test_partition.py'
--- src/maasserver/models/tests/test_partition.py 2015-11-04 19:39:51 +0000
+++ src/maasserver/models/tests/test_partition.py 2015-11-16 07:08:21 +0000
@@ -29,6 +29,7 @@
29from maasserver.models.partition import (29from maasserver.models.partition import (
30 MIN_PARTITION_SIZE,30 MIN_PARTITION_SIZE,
31 Partition,31 Partition,
32 PARTITION_ALIGNMENT_SIZE,
32)33)
33from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE34from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
34from maasserver.testing.factory import factory35from maasserver.testing.factory import factory
@@ -45,18 +46,18 @@
45 node = factory.make_Node()46 node = factory.make_Node()
46 block_device = factory.make_PhysicalBlockDevice(47 block_device = factory.make_PhysicalBlockDevice(
47 node=node,48 node=node,
48 size=(MIN_BLOCK_DEVICE_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE)49 size=(MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE)
49 partition_table = factory.make_PartitionTable(50 partition_table = factory.make_PartitionTable(
50 block_device=block_device)51 block_device=block_device)
51 free_partitions = [52 free_partitions = [
52 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)53 partition_table.add_partition(size=MIN_PARTITION_SIZE)
53 for _ in range(2)54 for _ in range(2)
54 ]55 ]
55 # Make used partitions.56 # Make used partitions.
56 for _ in range(2):57 for _ in range(2):
57 factory.make_Filesystem(58 factory.make_Filesystem(
58 partition=partition_table.add_partition(59 partition=partition_table.add_partition(
59 size=MIN_BLOCK_DEVICE_SIZE))60 size=MIN_PARTITION_SIZE))
60 self.assertItemsEqual(61 self.assertItemsEqual(
61 free_partitions,62 free_partitions,
62 Partition.objects.get_free_partitions_for_node(node))63 Partition.objects.get_free_partitions_for_node(node))
@@ -213,12 +214,12 @@
213 partition.save()214 partition.save()
214 self.assertEquals('%s' % uuid, partition.uuid)215 self.assertEquals('%s' % uuid, partition.uuid)
215216
216 def test_size_is_rounded_to_next_block(self):217 def test_size_is_rounded_to_current_block(self):
217 partition = factory.make_Partition()218 partition = factory.make_Partition()
218 partition.size = partition.get_block_size() * 4096219 partition.size = PARTITION_ALIGNMENT_SIZE * 4
219 partition.size += 1220 partition.size += 1
220 partition.save()221 partition.save()
221 self.assertEquals(4097, partition.size / partition.get_block_size())222 self.assertEquals(PARTITION_ALIGNMENT_SIZE * 4, partition.size)
222223
223 def test_validate_enough_space_for_new_partition(self):224 def test_validate_enough_space_for_new_partition(self):
224 partition_table = factory.make_PartitionTable()225 partition_table = factory.make_PartitionTable()
@@ -235,7 +236,7 @@
235 def test_validate_enough_space_for_resize_partition(self):236 def test_validate_enough_space_for_resize_partition(self):
236 partition_table = factory.make_PartitionTable()237 partition_table = factory.make_PartitionTable()
237 partition = partition_table.add_partition()238 partition = partition_table.add_partition()
238 partition.size += partition_table.get_block_size() * 2239 partition.size += PARTITION_ALIGNMENT_SIZE * 2
239 error = self.assertRaises(ValidationError, partition.save)240 error = self.assertRaises(ValidationError, partition.save)
240 self.assertEquals({241 self.assertEquals({
241 "size": [242 "size": [
@@ -298,7 +299,7 @@
298 node = factory.make_Node(bios_boot_method="uefi")299 node = factory.make_Node(bios_boot_method="uefi")
299 block_device = factory.make_PhysicalBlockDevice(300 block_device = factory.make_PhysicalBlockDevice(
300 node=node,301 node=node,
301 size=(MIN_BLOCK_DEVICE_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE)302 size=(MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE)
302 partition_table = factory.make_PartitionTable(303 partition_table = factory.make_PartitionTable(
303 block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT)304 block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT)
304 partitions = [305 partitions = [
305306
=== modified file 'src/maasserver/models/tests/test_partitiontable.py'
--- src/maasserver/models/tests/test_partitiontable.py 2015-11-04 04:27:46 +0000
+++ src/maasserver/models/tests/test_partitiontable.py 2015-11-16 07:08:21 +0000
@@ -23,7 +23,11 @@
23 BlockDevice,23 BlockDevice,
24 MIN_BLOCK_DEVICE_SIZE,24 MIN_BLOCK_DEVICE_SIZE,
25)25)
26from maasserver.models.partition import MAX_PARTITION_SIZE_FOR_MBR26from maasserver.models.partition import (
27 MAX_PARTITION_SIZE_FOR_MBR,
28 MIN_PARTITION_SIZE,
29 PARTITION_ALIGNMENT_SIZE,
30)
27from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE31from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
28from maasserver.testing.factory import factory32from maasserver.testing.factory import factory
29from maasserver.testing.testcase import MAASServerTestCase33from maasserver.testing.testcase import MAASServerTestCase
@@ -41,7 +45,11 @@
41 def test_get_size_returns_block_device_size_minus_initial_offset(self):45 def test_get_size_returns_block_device_size_minus_initial_offset(self):
42 partition_table = factory.make_PartitionTable()46 partition_table = factory.make_PartitionTable()
43 self.assertEquals(47 self.assertEquals(
44 partition_table.block_device.size - PARTITION_TABLE_EXTRA_SPACE,48 round_size_to_nearest_block(
49 partition_table.block_device.size -
50 PARTITION_TABLE_EXTRA_SPACE,
51 PARTITION_ALIGNMENT_SIZE,
52 False),
45 partition_table.get_size())53 partition_table.get_size())
4654
47 def test_get_block_size_returns_block_device_block_size(self):55 def test_get_block_size_returns_block_device_block_size(self):
@@ -52,17 +60,17 @@
5260
53 def test_add_misaligned_partition(self):61 def test_add_misaligned_partition(self):
54 """Tests whether a partition size are adjusted according to62 """Tests whether a partition size are adjusted according to
55 device block size."""63 partition alignment size (4MiB)."""
56 block_size = 409664 block_size = 4096
57 device = factory.make_BlockDevice(65 device = factory.make_BlockDevice(
58 size=MIN_BLOCK_DEVICE_SIZE * 2 + PARTITION_TABLE_EXTRA_SPACE,66 size=MIN_PARTITION_SIZE * 2 + PARTITION_TABLE_EXTRA_SPACE,
59 block_size=block_size)67 block_size=block_size)
60 partition_table = factory.make_PartitionTable(block_device=device)68 partition_table = factory.make_PartitionTable(block_device=device)
61 partition = partition_table.add_partition(69 partition = partition_table.add_partition(
62 size=MIN_BLOCK_DEVICE_SIZE + 54)70 size=MIN_PARTITION_SIZE + 54)
63 self.assertEqual(71 self.assertEqual(
64 round_size_to_nearest_block(72 round_size_to_nearest_block(
65 MIN_BLOCK_DEVICE_SIZE + 54, block_size),73 MIN_PARTITION_SIZE + 54, PARTITION_ALIGNMENT_SIZE, False),
66 partition.size)74 partition.size)
6775
68 def test_add_partition_no_size(self):76 def test_add_partition_no_size(self):
@@ -85,9 +93,10 @@
85 partition_table = factory.make_PartitionTable(93 partition_table = factory.make_PartitionTable(
86 table_type=PARTITION_TABLE_TYPE.MBR, block_device=device)94 table_type=PARTITION_TABLE_TYPE.MBR, block_device=device)
87 partition = partition_table.add_partition()95 partition = partition_table.add_partition()
88 number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / block_size
89 self.assertEqual(96 self.assertEqual(
90 partition.size, block_size * (number_of_blocks - 1))97 round_size_to_nearest_block(
98 MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False),
99 partition.size)
91100
92 def test_add_second_partition_no_size(self):101 def test_add_second_partition_no_size(self):
93 """Tests whether a second partition with no specified size starts from102 """Tests whether a second partition with no specified size starts from
@@ -95,12 +104,12 @@
95 device."""104 device."""
96 block_size = 4096105 block_size = 4096
97 device = factory.make_BlockDevice(106 device = factory.make_BlockDevice(
98 size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,107 size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,
99 block_size=block_size)108 block_size=block_size)
100 partition_table = factory.make_PartitionTable(block_device=device)109 partition_table = factory.make_PartitionTable(block_device=device)
101 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)110 partition_table.add_partition(size=MIN_PARTITION_SIZE)
102 partition = partition_table.add_partition()111 partition = partition_table.add_partition()
103 self.assertEqual(MIN_BLOCK_DEVICE_SIZE * 2, partition.size)112 self.assertEqual(MIN_PARTITION_SIZE * 2, partition.size)
104113
105 def test_add_partition_to_full_device(self):114 def test_add_partition_to_full_device(self):
106 """Tests whether we fail to add a partition to an already full device.115 """Tests whether we fail to add a partition to an already full device.
@@ -117,26 +126,26 @@
117 def test_get_available_size(self):126 def test_get_available_size(self):
118 block_size = 4096127 block_size = 4096
119 device = factory.make_BlockDevice(128 device = factory.make_BlockDevice(
120 size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,129 size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,
121 block_size=block_size)130 block_size=block_size)
122 partition_table = factory.make_PartitionTable(block_device=device)131 partition_table = factory.make_PartitionTable(block_device=device)
123 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)132 partition_table.add_partition(size=MIN_PARTITION_SIZE)
124 self.assertEquals(133 self.assertEquals(
125 MIN_BLOCK_DEVICE_SIZE * 2, partition_table.get_available_size())134 MIN_PARTITION_SIZE * 2, partition_table.get_available_size())
126135
127 def test_get_available_size_skips_partitions(self):136 def test_get_available_size_skips_partitions(self):
128 block_size = 4096137 block_size = 4096
129 device = factory.make_BlockDevice(138 device = factory.make_BlockDevice(
130 size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,139 size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE,
131 block_size=block_size)140 block_size=block_size)
132 partition_table = factory.make_PartitionTable(block_device=device)141 partition_table = factory.make_PartitionTable(block_device=device)
133 ignore_partitions = [142 ignore_partitions = [
134 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)143 partition_table.add_partition(size=MIN_PARTITION_SIZE)
135 for _ in range(2)144 for _ in range(2)
136 ]145 ]
137 partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE)146 partition_table.add_partition(size=MIN_PARTITION_SIZE)
138 self.assertEquals(147 self.assertEquals(
139 MIN_BLOCK_DEVICE_SIZE * 2,148 MIN_PARTITION_SIZE * 2,
140 partition_table.get_available_size(149 partition_table.get_available_size(
141 ignore_partitions=ignore_partitions))150 ignore_partitions=ignore_partitions))
142151
143152
=== modified file 'src/maasserver/models/virtualblockdevice.py'
--- src/maasserver/models/virtualblockdevice.py 2015-08-14 13:48:59 +0000
+++ src/maasserver/models/virtualblockdevice.py 2015-11-16 07:08:21 +0000
@@ -30,7 +30,11 @@
30)30)
31from maasserver.models.filesystemgroup import FilesystemGroup31from maasserver.models.filesystemgroup import FilesystemGroup
32from maasserver.models.node import Node32from maasserver.models.node import Node
33from maasserver.utils.converters import human_readable_bytes33from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
34from maasserver.utils.converters import (
35 human_readable_bytes,
36 round_size_to_nearest_block,
37)
34from maasserver.utils.orm import get_one38from maasserver.utils.orm import get_one
3539
3640
@@ -109,16 +113,22 @@
109113
110 # Check if the size of this is not larger than the free size of114 # Check if the size of this is not larger than the free size of
111 # its filesystem group if its lvm.115 # its filesystem group if its lvm.
112 if (self.filesystem_group.is_lvm() and116 if self.filesystem_group.is_lvm():
113 self.size > self.filesystem_group.get_lvm_free_space(117
114 skip_volumes=[self])):118 # align virtual partition to partition alignment size
115 raise ValidationError(119 # otherwise on creation it may be rounded up, overfilling group
116 "There is not enough free space (%s) "120 self.size = round_size_to_nearest_block(
117 "on volume group %s." % (121 self.size, PARTITION_ALIGNMENT_SIZE, False)
118 human_readable_bytes(self.size),122
119 self.filesystem_group.name,123 if self.size > self.filesystem_group.get_lvm_free_space(
120 ))124 skip_volumes=[self]):
121 elif not self.filesystem_group.is_lvm():125 raise ValidationError(
126 "There is not enough free space (%s) "
127 "on volume group %s." % (
128 human_readable_bytes(self.size),
129 self.filesystem_group.name,
130 ))
131 else:
122 # If not a volume group the size of the virtual block device132 # If not a volume group the size of the virtual block device
123 # must equal the size of the filesystem group.133 # must equal the size of the filesystem group.
124 assert self.size == self.filesystem_group.get_size()134 assert self.size == self.filesystem_group.get_size()
125135
=== modified file 'src/maasserver/testing/factory.py'
--- src/maasserver/testing/factory.py 2015-11-02 22:17:02 +0000
+++ src/maasserver/testing/factory.py 2015-11-16 07:08:21 +0000
@@ -1287,9 +1287,7 @@
1287 raise ValueError(1287 raise ValueError(
1288 "Cannot make another partition on partition_table not "1288 "Cannot make another partition on partition_table not "
1289 "enough free space.")1289 "enough free space.")
1290 size = round_size_to_nearest_block(1290 size = random.randint(MIN_PARTITION_SIZE, available_size)
1291 random.randint(MIN_PARTITION_SIZE, available_size),
1292 partition_table.get_block_size())
1293 if bootable is None:1291 if bootable is None:
1294 bootable = random.choice([True, False])1292 bootable = random.choice([True, False])
1295 return Partition.objects.create(1293 return Partition.objects.create(
12961294
=== modified file 'src/maasserver/tests/test_forms_blockdevice.py'
--- src/maasserver/tests/test_forms_blockdevice.py 2015-09-24 19:54:30 +0000
+++ src/maasserver/tests/test_forms_blockdevice.py 2015-11-16 07:08:21 +0000
@@ -31,9 +31,11 @@
31)31)
32from maasserver.models import Filesystem32from maasserver.models import Filesystem
33from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE33from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
34from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
34from maasserver.testing.factory import factory35from maasserver.testing.factory import factory
35from maasserver.testing.orm import reload_object36from maasserver.testing.orm import reload_object
36from maasserver.testing.testcase import MAASServerTestCase37from maasserver.testing.testcase import MAASServerTestCase
38from maasserver.utils.converters import round_size_to_nearest_block
37from maasserver.utils.orm import get_one39from maasserver.utils.orm import get_one
38from testtools.matchers import MatchesStructure40from testtools.matchers import MatchesStructure
3941
@@ -379,8 +381,10 @@
379 })381 })
380 self.assertTrue(form.is_valid(), form.errors)382 self.assertTrue(form.is_valid(), form.errors)
381 block_device = form.save()383 block_device = form.save()
384 expected_size = round_size_to_nearest_block(
385 size, PARTITION_ALIGNMENT_SIZE, False)
382 self.assertThat(block_device, MatchesStructure.byEquality(386 self.assertThat(block_device, MatchesStructure.byEquality(
383 name=name,387 name=name,
384 uuid=vguuid,388 uuid=vguuid,
385 size=size,389 size=expected_size,
386 ))390 ))
387391
=== modified file 'src/maasserver/tests/test_forms_partition.py'
--- src/maasserver/tests/test_forms_partition.py 2015-09-24 19:54:30 +0000
+++ src/maasserver/tests/test_forms_partition.py 2015-11-16 07:08:21 +0000
@@ -26,9 +26,11 @@
26)26)
27from maasserver.models import Filesystem27from maasserver.models import Filesystem
28from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE28from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
29from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
29from maasserver.testing.factory import factory30from maasserver.testing.factory import factory
30from maasserver.testing.orm import reload_object31from maasserver.testing.orm import reload_object
31from maasserver.testing.testcase import MAASServerTestCase32from maasserver.testing.testcase import MAASServerTestCase
33from maasserver.utils.converters import round_size_to_nearest_block
32from maasserver.utils.orm import get_one34from maasserver.utils.orm import get_one
3335
3436
@@ -84,15 +86,13 @@
84 form.is_valid(),86 form.is_valid(),
85 "Should be valid because size is large enough and a string.")87 "Should be valid because size is large enough and a string.")
8688
87 def test_size_rounded_up_and_placed_on_block_boundry(self):89 def test_size_rounded_down_and_placed_on_alignment_boundry(self):
88 block_size = 409690 block_size = 4096
89 block_device = factory.make_PhysicalBlockDevice(block_size=block_size)91 block_device = factory.make_PhysicalBlockDevice(block_size=block_size)
90 k_size = (MIN_BLOCK_DEVICE_SIZE / 1000) + 192 k_size = (MIN_BLOCK_DEVICE_SIZE / 1000) + 1
91 size = "%sk" % k_size93 size = "%sk" % k_size
92 block_count = (k_size * 1000) / block_size94 rounded_size = round_size_to_nearest_block(
93 if (k_size * 1000) % block_size > 0:95 k_size * 1000, PARTITION_ALIGNMENT_SIZE, False)
94 block_count += 1
95 rounded_size = block_count * block_size
96 data = {96 data = {
97 'size': size,97 'size': size,
98 }98 }
9999
=== modified file 'src/maasserver/tests/test_forms_raid.py'
--- src/maasserver/tests/test_forms_raid.py 2015-10-29 16:39:49 +0000
+++ src/maasserver/tests/test_forms_raid.py 2015-11-16 07:08:21 +0000
@@ -26,7 +26,6 @@
26 UpdateRaidForm,26 UpdateRaidForm,
27)27)
28from maasserver.models.filesystemgroup import RAID28from maasserver.models.filesystemgroup import RAID
29from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
30from maasserver.testing.factory import factory29from maasserver.testing.factory import factory
31from maasserver.testing.testcase import MAASServerTestCase30from maasserver.testing.testcase import MAASServerTestCase
3231
@@ -126,12 +125,11 @@
126 for bd in bds125 for bd in bds
127 if bd.get_partitiontable() is None126 if bd.get_partitiontable() is None
128 ]127 ]
129 partitions = [128 partition_objs = [
130 bd.get_partitiontable().add_partition().id129 bd.get_partitiontable().add_partition()
131 for bd in bds[5:]130 for bd in bds[5:]
132 ]131 ]
133 # Partition size will be smaller than the disk, because of overhead.132 partitions = [partition.id for partition in partition_objs]
134 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
135 form = CreateRaidForm(node=node, data={133 form = CreateRaidForm(node=node, data={
136 'name': 'md1',134 'name': 'md1',
137 'level': FILESYSTEM_GROUP_TYPE.RAID_6,135 'level': FILESYSTEM_GROUP_TYPE.RAID_6,
@@ -141,7 +139,7 @@
141 self.assertTrue(form.is_valid(), form.errors)139 self.assertTrue(form.is_valid(), form.errors)
142 raid = form.save()140 raid = form.save()
143 self.assertEqual('md1', raid.name)141 self.assertEqual('md1', raid.name)
144 self.assertEqual(8 * partition_size, raid.get_size())142 self.assertEqual(8 * partition_objs[0].size, raid.get_size())
145 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)143 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)
146 self.assertItemsEqual(144 self.assertItemsEqual(
147 block_devices,145 block_devices,
@@ -183,8 +181,6 @@
183 part.name181 part.name
184 for part in partitions182 for part in partitions
185 ]183 ]
186 # Partition size will be smaller than the disk, because of overhead.
187 partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE
188 form = CreateRaidForm(node=node, data={184 form = CreateRaidForm(node=node, data={
189 'name': 'md1',185 'name': 'md1',
190 'level': FILESYSTEM_GROUP_TYPE.RAID_6,186 'level': FILESYSTEM_GROUP_TYPE.RAID_6,
@@ -194,7 +190,7 @@
194 self.assertTrue(form.is_valid(), form.errors)190 self.assertTrue(form.is_valid(), form.errors)
195 raid = form.save()191 raid = form.save()
196 self.assertEqual('md1', raid.name)192 self.assertEqual('md1', raid.name)
197 self.assertEqual(8 * partition_size, raid.get_size())193 self.assertEqual(8 * partitions[0].size, raid.get_size())
198 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)194 self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type)
199 self.assertItemsEqual(195 self.assertItemsEqual(
200 block_devices_ids,196 block_devices_ids,
201197
=== modified file 'src/maasserver/tests/test_forms_volume_group.py'
--- src/maasserver/tests/test_forms_volume_group.py 2015-10-28 01:59:30 +0000
+++ src/maasserver/tests/test_forms_volume_group.py 2015-11-16 07:08:21 +0000
@@ -24,9 +24,11 @@
24 UpdateVolumeGroupForm,24 UpdateVolumeGroupForm,
25)25)
26from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE26from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
27from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE
27from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE28from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
28from maasserver.testing.factory import factory29from maasserver.testing.factory import factory
29from maasserver.testing.testcase import MAASServerTestCase30from maasserver.testing.testcase import MAASServerTestCase
31from maasserver.utils.converters import round_size_to_nearest_block
30from testtools.matchers import MatchesStructure32from testtools.matchers import MatchesStructure
3133
3234
@@ -512,9 +514,10 @@
512 factory.make_name("lv"),514 factory.make_name("lv"),
513 size=volume_group.get_size() - MIN_BLOCK_DEVICE_SIZE - 1)515 size=volume_group.get_size() - MIN_BLOCK_DEVICE_SIZE - 1)
514 name = factory.make_name("lv")516 name = factory.make_name("lv")
517 free_space = volume_group.get_lvm_free_space()
515 data = {518 data = {
516 'name': name,519 'name': name,
517 'size': MIN_BLOCK_DEVICE_SIZE + 2,520 'size': free_space + 2,
518 }521 }
519 form = CreateLogicalVolumeForm(volume_group, data=data)522 form = CreateLogicalVolumeForm(volume_group, data=data)
520 self.assertFalse(523 self.assertFalse(
@@ -560,9 +563,11 @@
560 form = CreateLogicalVolumeForm(volume_group, data=data)563 form = CreateLogicalVolumeForm(volume_group, data=data)
561 self.assertTrue(form.is_valid(), form._errors)564 self.assertTrue(form.is_valid(), form._errors)
562 logical_volume = form.save()565 logical_volume = form.save()
566 expected_size = round_size_to_nearest_block(
567 size, PARTITION_ALIGNMENT_SIZE, False)
563 self.assertThat(568 self.assertThat(
564 logical_volume, MatchesStructure.byEquality(569 logical_volume, MatchesStructure.byEquality(
565 name=name,570 name=name,
566 uuid=vguuid,571 uuid=vguuid,
567 size=size,572 size=expected_size,
568 ))573 ))
569574
=== modified file 'src/maasserver/tests/test_preseed_storage.py'
--- src/maasserver/tests/test_preseed_storage.py 2015-11-04 04:27:46 +0000
+++ src/maasserver/tests/test_preseed_storage.py 2015-11-16 07:08:21 +0000
@@ -83,7 +83,7 @@
83 size: 536870912B83 size: 536870912B
84 device: sda84 device: sda
85 wipe: superblock85 wipe: superblock
86 offset: 2097152B86 offset: 4194304B
87 flag: boot87 flag: boot
88 - id: sda-part288 - id: sda-part2
89 name: sda-part289 name: sda-part2
@@ -99,7 +99,7 @@
99 type: partition99 type: partition
100 number: 3100 number: 3
101 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf101 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf
102 size: 6976176128B102 size: 6970933248B
103 wipe: superblock103 wipe: superblock
104 device: sda104 device: sda
105 - id: sda-part1_format105 - id: sda-part1_format
@@ -195,7 +195,7 @@
195 size: 536870912B195 size: 536870912B
196 device: sda196 device: sda
197 wipe: superblock197 wipe: superblock
198 offset: 2097152B198 offset: 4194304B
199 flag: boot199 flag: boot
200 - id: sda-part2200 - id: sda-part2
201 name: sda-part2201 name: sda-part2
@@ -233,7 +233,7 @@
233 type: partition233 type: partition
234 number: 6234 number: 6
235 uuid: 8c365c80-900b-40a1-a8c7-1e445878d19a235 uuid: 8c365c80-900b-40a1-a8c7-1e445878d19a
236 size: 2144337920B236 size: 2139095040B
237 device: sda237 device: sda
238 wipe: superblock238 wipe: superblock
239 flag: logical239 flag: logical
@@ -370,10 +370,10 @@
370 type: partition370 type: partition
371 number: 1371 number: 1
372 uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398372 uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398
373 size: 8586788864B373 size: 8581545984B
374 device: sda374 device: sda
375 wipe: superblock375 wipe: superblock
376 offset: 2097152B376 offset: 4194304B
377 - id: sda-part1_format377 - id: sda-part1_format
378 type: format378 type: format
379 fstype: ext4379 fstype: ext4
@@ -435,10 +435,10 @@
435 type: partition435 type: partition
436 number: 1436 number: 1
437 uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398437 uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398
438 size: 8586788864B438 size: 8581545984B
439 device: sda439 device: sda
440 wipe: superblock440 wipe: superblock
441 offset: 2097152B441 offset: 4194304B
442 - id: sda-part1_format442 - id: sda-part1_format
443 type: format443 type: format
444 fstype: ext4444 fstype: ext4
@@ -548,7 +548,7 @@
548 size: 536870912B548 size: 536870912B
549 device: sda549 device: sda
550 wipe: superblock550 wipe: superblock
551 offset: 2097152B551 offset: 4194304B
552 flag: boot552 flag: boot
553 - id: sda-part2553 - id: sda-part2
554 name: sda-part2554 name: sda-part2
@@ -564,16 +564,16 @@
564 type: partition564 type: partition
565 number: 3565 number: 3
566 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf566 uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf
567 size: 6976176128B567 size: 6970933248B
568 device: sda568 device: sda
569 wipe: superblock569 wipe: superblock
570 - id: sdb-part1570 - id: sdb-part1
571 name: sdb-part1571 name: sdb-part1
572 type: partition572 type: partition
573 number: 1573 number: 1
574 offset: 2097152B574 offset: 4194304B
575 uuid: f3281144-a0b6-46f1-90af-8541f97f7b1f575 uuid: f3281144-a0b6-46f1-90af-8541f97f7b1f
576 size: 2144337920B576 size: 2139095040B
577 wipe: superblock577 wipe: superblock
578 device: sdb578 device: sdb
579 - id: bcache0579 - id: bcache0
@@ -610,9 +610,9 @@
610 name: md0-part1610 name: md0-part1
611 type: partition611 type: partition
612 number: 1612 number: 1
613 offset: 2097152B613 offset: 4194304B
614 uuid: 18a6e885-3e6d-4505-8a0d-cf34df11a8b0614 uuid: 18a6e885-3e6d-4505-8a0d-cf34df11a8b0
615 size: 2199020109824B615 size: 2199014866944B
616 wipe: superblock616 wipe: superblock
617 device: md0617 device: md0
618 - id: sda-part1_format618 - id: sda-part1_format
619619
=== modified file 'src/maasserver/tests/test_storage_layouts.py'
--- src/maasserver/tests/test_storage_layouts.py 2015-10-27 20:53:16 +0000
+++ src/maasserver/tests/test_storage_layouts.py 2015-11-16 07:08:21 +0000
@@ -25,7 +25,10 @@
25)25)
26from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE26from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE
27from maasserver.models.filesystemgroup import VolumeGroup27from maasserver.models.filesystemgroup import VolumeGroup
28from maasserver.models.partition import MAX_PARTITION_SIZE_FOR_MBR28from maasserver.models.partition import (
29 MAX_PARTITION_SIZE_FOR_MBR,
30 PARTITION_ALIGNMENT_SIZE,
31)
29from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE32from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
30from maasserver.storage_layouts import (33from maasserver.storage_layouts import (
31 BcacheStorageLayout,34 BcacheStorageLayout,
@@ -46,6 +49,7 @@
46)49)
47from maasserver.testing.factory import factory50from maasserver.testing.factory import factory
48from maasserver.testing.testcase import MAASServerTestCase51from maasserver.testing.testcase import MAASServerTestCase
52from maasserver.utils.converters import round_size_to_nearest_block
49from maastesting.matchers import MockCalledOnceWith53from maastesting.matchers import MockCalledOnceWith
50from testtools.matchers import MatchesStructure54from testtools.matchers import MatchesStructure
5155
@@ -53,13 +57,6 @@
53LARGE_BLOCK_DEVICE = 10 * 1024 * 1024 * 1024 # 10 GiB57LARGE_BLOCK_DEVICE = 10 * 1024 * 1024 * 1024 # 10 GiB
5458
5559
56def round_size_by_blocks(size, block_size):
57 number_of_blocks = size / block_size
58 if size % block_size > 0:
59 number_of_blocks += 1
60 return number_of_blocks * block_size
61
62
63def make_Node_with_uefi_boot_method(*args, **kwargs):60def make_Node_with_uefi_boot_method(*args, **kwargs):
64 kwargs['bios_boot_method'] = "uefi"61 kwargs['bios_boot_method'] = "uefi"
65 kwargs['with_boot_disk'] = False62 kwargs['with_boot_disk'] = False
@@ -435,7 +432,8 @@
435 def assertEFIPartition(self, partition, boot_disk):432 def assertEFIPartition(self, partition, boot_disk):
436 self.assertIsNotNone(partition)433 self.assertIsNotNone(partition)
437 self.assertEquals(434 self.assertEquals(
438 round_size_by_blocks(EFI_PARTITION_SIZE, boot_disk.block_size),435 round_size_to_nearest_block(
436 EFI_PARTITION_SIZE, boot_disk.block_size),
439 partition.size)437 partition.size)
440 self.assertThat(438 self.assertThat(
441 partition.get_effective_filesystem(), MatchesStructure.byEquality(439 partition.get_effective_filesystem(), MatchesStructure.byEquality(
@@ -474,9 +472,10 @@
474 root_partition = partitions[0]472 root_partition = partitions[0]
475 self.assertIsNotNone(root_partition)473 self.assertIsNotNone(root_partition)
476 self.assertEquals(474 self.assertEquals(
477 round_size_by_blocks(475 round_size_to_nearest_block(
478 boot_disk.size - PARTITION_TABLE_EXTRA_SPACE,476 boot_disk.size - PARTITION_TABLE_EXTRA_SPACE,
479 boot_disk.block_size),477 PARTITION_ALIGNMENT_SIZE,
478 False),
480 root_partition.size)479 root_partition.size)
481 self.assertThat(480 self.assertThat(
482 root_partition.get_effective_filesystem(),481 root_partition.get_effective_filesystem(),
@@ -500,10 +499,12 @@
500 # Validate root partition.499 # Validate root partition.
501 partitions = partition_table.partitions.order_by('id').all()500 partitions = partition_table.partitions.order_by('id').all()
502 root_partition = partitions[0]501 root_partition = partitions[0]
503 number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / boot_disk.block_size
504 self.assertIsNotNone(root_partition)502 self.assertIsNotNone(root_partition)
505 self.assertEquals(503 self.assertEquals(
506 (boot_disk.block_size * (number_of_blocks - 1)),504 round_size_to_nearest_block(
505 MAX_PARTITION_SIZE_FOR_MBR,
506 PARTITION_ALIGNMENT_SIZE,
507 False),
507 root_partition.size)508 root_partition.size)
508 self.assertThat(509 self.assertThat(
509 root_partition.get_effective_filesystem(),510 root_partition.get_effective_filesystem(),
@@ -533,10 +534,11 @@
533 root_partition = partitions[1]534 root_partition = partitions[1]
534 self.assertIsNotNone(root_partition)535 self.assertIsNotNone(root_partition)
535 self.assertEquals(536 self.assertEquals(
536 round_size_by_blocks(537 round_size_to_nearest_block(
537 boot_disk.size - EFI_PARTITION_SIZE -538 boot_disk.size - EFI_PARTITION_SIZE -
538 PARTITION_TABLE_EXTRA_SPACE,539 PARTITION_TABLE_EXTRA_SPACE,
539 boot_disk.block_size),540 PARTITION_ALIGNMENT_SIZE,
541 False),
540 root_partition.size)542 root_partition.size)
541 self.assertThat(543 self.assertThat(
542 root_partition.get_effective_filesystem(),544 root_partition.get_effective_filesystem(),
@@ -570,8 +572,8 @@
570 boot_partition = partitions[1]572 boot_partition = partitions[1]
571 self.assertIsNotNone(boot_partition)573 self.assertIsNotNone(boot_partition)
572 self.assertEquals(574 self.assertEquals(
573 round_size_by_blocks(575 round_size_to_nearest_block(
574 boot_size, boot_disk.block_size),576 boot_size, PARTITION_ALIGNMENT_SIZE, False),
575 boot_partition.size)577 boot_partition.size)
576 self.assertThat(578 self.assertThat(
577 boot_partition.get_effective_filesystem(),579 boot_partition.get_effective_filesystem(),
@@ -585,10 +587,11 @@
585 root_partition = partitions[2]587 root_partition = partitions[2]
586 self.assertIsNotNone(root_partition)588 self.assertIsNotNone(root_partition)
587 self.assertEquals(589 self.assertEquals(
588 round_size_by_blocks(590 round_size_to_nearest_block(
589 boot_disk.size - boot_partition.size -591 boot_disk.size - boot_partition.size -
590 EFI_PARTITION_SIZE - PARTITION_TABLE_EXTRA_SPACE,592 EFI_PARTITION_SIZE - PARTITION_TABLE_EXTRA_SPACE,
591 boot_disk.block_size),593 PARTITION_ALIGNMENT_SIZE,
594 False),
592 root_partition.size)595 root_partition.size)
593 self.assertThat(596 self.assertThat(
594 root_partition.get_effective_filesystem(),597 root_partition.get_effective_filesystem(),
@@ -622,7 +625,8 @@
622 root_partition = partitions[1]625 root_partition = partitions[1]
623 self.assertIsNotNone(root_partition)626 self.assertIsNotNone(root_partition)
624 self.assertEquals(627 self.assertEquals(
625 round_size_by_blocks(root_size, boot_disk.block_size),628 round_size_to_nearest_block(
629 root_size, PARTITION_ALIGNMENT_SIZE, False),
626 root_partition.size)630 root_partition.size)
627 self.assertThat(631 self.assertThat(
628 root_partition.get_effective_filesystem(),632 root_partition.get_effective_filesystem(),
@@ -659,8 +663,8 @@
659 boot_partition = partitions[1]663 boot_partition = partitions[1]
660 self.assertIsNotNone(boot_partition)664 self.assertIsNotNone(boot_partition)
661 self.assertEquals(665 self.assertEquals(
662 round_size_by_blocks(666 round_size_to_nearest_block(
663 boot_size, boot_disk.block_size),667 boot_size, PARTITION_ALIGNMENT_SIZE, False),
664 boot_partition.size)668 boot_partition.size)
665 self.assertThat(669 self.assertThat(
666 boot_partition.get_effective_filesystem(),670 boot_partition.get_effective_filesystem(),
@@ -674,7 +678,8 @@
674 root_partition = partitions[2]678 root_partition = partitions[2]
675 self.assertIsNotNone(root_partition)679 self.assertIsNotNone(root_partition)
676 self.assertEquals(680 self.assertEquals(
677 round_size_by_blocks(root_size, boot_disk.block_size),681 round_size_to_nearest_block(
682 root_size, PARTITION_ALIGNMENT_SIZE, False),
678 root_partition.size)683 root_partition.size)
679 self.assertThat(684 self.assertThat(
680 root_partition.get_effective_filesystem(),685 root_partition.get_effective_filesystem(),
@@ -716,7 +721,8 @@
716 'id').all()[0]721 'id').all()[0]
717 self.assertIsNotNone(root_partition)722 self.assertIsNotNone(root_partition)
718 self.assertEquals(723 self.assertEquals(
719 round_size_by_blocks(root_size, root_device.block_size),724 round_size_to_nearest_block(
725 root_size, PARTITION_ALIGNMENT_SIZE, False),
720 root_partition.size)726 root_partition.size)
721 self.assertThat(727 self.assertThat(
722 root_partition.get_effective_filesystem(),728 root_partition.get_effective_filesystem(),
@@ -980,7 +986,9 @@
980 1, volume_group.virtual_devices.count(),986 1, volume_group.virtual_devices.count(),
981 "Should have only 1 logical volume.")987 "Should have only 1 logical volume.")
982 logical_volume = volume_group.virtual_devices.first()988 logical_volume = volume_group.virtual_devices.first()
983 self.assertEquals(lv_size, logical_volume.size)989 expected_size = round_size_to_nearest_block(
990 lv_size, PARTITION_ALIGNMENT_SIZE, False)
991 self.assertEquals(expected_size, logical_volume.size)
984 self.assertEquals(layout.DEFAULT_LV_NAME, logical_volume.name)992 self.assertEquals(layout.DEFAULT_LV_NAME, logical_volume.name)
985 self.assertThat(993 self.assertThat(
986 logical_volume.get_effective_filesystem(),994 logical_volume.get_effective_filesystem(),
@@ -1003,14 +1011,13 @@
1003 root_partition = partitions[0]1011 root_partition = partitions[0]
1004 volume_group = VolumeGroup.objects.get(1012 volume_group = VolumeGroup.objects.get(
1005 filesystems__partition=root_partition)1013 filesystems__partition=root_partition)
1006 number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / boot_disk.block_size
1007 self.assertIsNotNone(volume_group)1014 self.assertIsNotNone(volume_group)
1008 self.assertEquals(1015 self.assertEquals(
1009 4, partition_table.partitions.count(),1016 4, partition_table.partitions.count(),
1010 "Should have 4 partitions.")1017 "Should have 4 partitions.")
1011 self.assertEquals(1018 expected_size = round_size_to_nearest_block(
1012 boot_disk.block_size * (number_of_blocks - 1),1019 MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False)
1013 root_partition.size)1020 self.assertEquals(expected_size, root_partition.size)
10141021
10151022
1016class TestBcacheStorageLayoutBase(MAASServerTestCase):1023class TestBcacheStorageLayoutBase(MAASServerTestCase):
@@ -1185,7 +1192,7 @@
1185 ssd = factory.make_PhysicalBlockDevice(1192 ssd = factory.make_PhysicalBlockDevice(
1186 node=node, size=5 * 1024 * 1024 * 1024, block_size=4096,1193 node=node, size=5 * 1024 * 1024 * 1024, block_size=4096,
1187 tags=['ssd'])1194 tags=['ssd'])
1188 cache_size = round_size_by_blocks(1195 cache_size = round_size_to_nearest_block(
1189 random.randint(1196 random.randint(
1190 3 * 1024 * 1024 * 1024, 5 * 1024 * 1024 * 1024),1197 3 * 1024 * 1024 * 1024, 5 * 1024 * 1024 * 1024),
1191 4096)1198 4096)
@@ -1200,7 +1207,10 @@
1200 self.assertIsNotNone(partition_table)1207 self.assertIsNotNone(partition_table)
1201 partition = partition_table.partitions.order_by('id').all()[0]1208 partition = partition_table.partitions.order_by('id').all()[0]
1202 self.assertEquals(partition, cache_device)1209 self.assertEquals(partition, cache_device)
1203 self.assertEquals(cache_size, partition.size)1210 self.assertEquals(
1211 round_size_to_nearest_block(
1212 cache_size, PARTITION_ALIGNMENT_SIZE, False),
1213 partition.size)
12041214
1205 def test_raises_error_when_invalid_cache_device(self):1215 def test_raises_error_when_invalid_cache_device(self):
1206 node = make_Node_with_uefi_boot_method()1216 node = make_Node_with_uefi_boot_method()
@@ -1234,7 +1244,8 @@
1234 "Cannot use cache_size and cache_no_part at the same time."],1244 "Cannot use cache_size and cache_no_part at the same time."],
1235 "cache_no_part": [1245 "cache_no_part": [
1236 "Cannot use cache_size and cache_no_part at the same time."],1246 "Cannot use cache_size and cache_no_part at the same time."],
1237 }, layout.errors)1247 },
1248 layout.errors)
12381249
1239 def test_raises_error_when_precentage_to_low_for_cache_size(self):1250 def test_raises_error_when_precentage_to_low_for_cache_size(self):
1240 node = make_Node_with_uefi_boot_method()1251 node = make_Node_with_uefi_boot_method()
12411252
=== modified file 'src/maasserver/utils/converters.py'
--- src/maasserver/utils/converters.py 2015-10-11 00:26:09 +0000
+++ src/maasserver/utils/converters.py 2015-11-16 07:08:21 +0000
@@ -100,12 +100,14 @@
100 return int(humanized)100 return int(humanized)
101101
102102
103def round_size_to_nearest_block(size, block_size):103def round_size_to_nearest_block(size, block_size, round_up=True):
104 """Round the size to the nearest block returning the new size.104 """Round the size to the nearest block returning the new size.
105105
106 :param round_up: Round the size to fill an entire block.106 :param size: The requested size to round.
107 :param block_size: The block size to round to.
108 :param round_up: If True, will round up to fill current block, else down.
107 """109 """
108 number_of_blocks = size / block_size110 number_of_blocks = size / block_size
109 if size % block_size > 0:111 if round_up and size % block_size > 0:
110 number_of_blocks += 1112 number_of_blocks += 1
111 return block_size * number_of_blocks113 return block_size * number_of_blocks
112114
=== modified file 'src/maasserver/utils/tests/test_converters.py'
--- src/maasserver/utils/tests/test_converters.py 2015-08-14 13:48:59 +0000
+++ src/maasserver/utils/tests/test_converters.py 2015-11-16 07:08:21 +0000
@@ -114,18 +114,34 @@
114114
115class TestRoundSizeToNearestBlock(MAASTestCase):115class TestRoundSizeToNearestBlock(MAASTestCase):
116116
117 def test__adds_extra_block(self):117 def test__round_up_adds_extra_block(self):
118 block_size = 4096118 block_size = 4096
119 size = block_size + 1119 size = block_size + 1
120 self.assertEquals(120 self.assertEquals(
121 2 * block_size,121 2 * block_size,
122 round_size_to_nearest_block(size, block_size),122 round_size_to_nearest_block(size, block_size, True),
123 "Should add another block to the size.")123 "Should add an extra block to the size.")
124124
125 def test__doesnt_add_extra_block(self):125 def test__round_up_doesnt_add_extra_block(self):
126 block_size = 4096126 block_size = 4096
127 size = block_size127 size = block_size
128 self.assertEquals(128 self.assertEquals(
129 size,129 size,
130 round_size_to_nearest_block(size, block_size),130 round_size_to_nearest_block(size, block_size, True),
131 "Shouldn't add another block to the size.")131 "Shouldn't add an extra block to the size.")
132
133 def test__round_down_removes_block(self):
134 block_size = 4096
135 size = block_size + 1
136 self.assertEquals(
137 1 * block_size,
138 round_size_to_nearest_block(size, block_size, False),
139 "Should remove block from the size.")
140
141 def test__round_down_doesnt_remove_block(self):
142 block_size = 4096
143 size = block_size * 2
144 self.assertEquals(
145 size,
146 round_size_to_nearest_block(size, block_size, False),
147 "Shouldn't remove a block from the size.")
132148
=== modified file 'src/maasserver/websockets/handlers/tests/test_node.py'
--- src/maasserver/websockets/handlers/tests/test_node.py 2015-11-10 23:41:49 +0000
+++ src/maasserver/websockets/handlers/tests/test_node.py 2015-11-16 07:08:21 +0000
@@ -48,7 +48,10 @@
48from maasserver.models.interface import Interface48from maasserver.models.interface import Interface
49from maasserver.models.node import Node49from maasserver.models.node import Node
50from maasserver.models.nodeprobeddetails import get_single_probed_details50from maasserver.models.nodeprobeddetails import get_single_probed_details
51from maasserver.models.partition import Partition51from maasserver.models.partition import (
52 Partition,
53 PARTITION_ALIGNMENT_SIZE,
54)
52from maasserver.node_action import compile_node_actions55from maasserver.node_action import compile_node_actions
53from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture56from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture
54from maasserver.testing.architecture import make_usable_architecture57from maasserver.testing.architecture import make_usable_architecture
@@ -66,6 +69,7 @@
66from maasserver.third_party_drivers import get_third_party_driver69from maasserver.third_party_drivers import get_third_party_driver
67from maasserver.utils.converters import (70from maasserver.utils.converters import (
68 human_readable_bytes,71 human_readable_bytes,
72 round_size_to_nearest_block,
69 XMLToYAML,73 XMLToYAML,
70)74)
71from maasserver.utils.orm import (75from maasserver.utils.orm import (
@@ -1477,7 +1481,9 @@
1477 self.assertEquals(1481 self.assertEquals(
1478 1, Partition.objects.count())1482 1, Partition.objects.count())
1479 self.assertEquals(1483 self.assertEquals(
1480 human_readable_bytes(size),1484 human_readable_bytes(
1485 round_size_to_nearest_block(
1486 size, PARTITION_ALIGNMENT_SIZE, False)),
1481 human_readable_bytes(Partition.objects.first().size))1487 human_readable_bytes(Partition.objects.first().size))
14821488
1483 def test_create_partition_with_filesystem(self):1489 def test_create_partition_with_filesystem(self):
@@ -1502,7 +1508,9 @@
1502 self.assertEquals(1508 self.assertEquals(
1503 1, Partition.objects.count())1509 1, Partition.objects.count())
1504 self.assertEquals(1510 self.assertEquals(
1505 human_readable_bytes(size),1511 human_readable_bytes(
1512 round_size_to_nearest_block(
1513 size, PARTITION_ALIGNMENT_SIZE, False)),
1506 human_readable_bytes(Partition.objects.first().size))1514 human_readable_bytes(Partition.objects.first().size))
1507 self.assertEquals(1515 self.assertEquals(
1508 fstype,1516 fstype,