From 29f416aefed900d022dd072a5563f140a5a54229 Mon Sep 17 00:00:00 2001 From: Scott Hussey Date: Fri, 30 Mar 2018 12:11:31 -0500 Subject: [PATCH] [Fix] whole-disk sizing fails - When using the '>' operator to create a partition using the full available storage left on a physical device fails with 'not enough storage available'. Nothing in MaaS documents what would cause this, but it is possible that the available_size field on the block device does not account for storage consumed for writing the partition table. Change-Id: Iac777e9d18df1df92e25779f9297a3e2dea12a12 --- .../drivers/node/maasdriver/actions/node.py | 19 ++++++++++++++++--- tests/unit/test_maasdriver_calculate_bytes.py | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drydock_provisioner/drivers/node/maasdriver/actions/node.py b/drydock_provisioner/drivers/node/maasdriver/actions/node.py index d5adbead..20e0ab20 100644 --- a/drydock_provisioner/drivers/node/maasdriver/actions/node.py +++ b/drydock_provisioner/drivers/node/maasdriver/actions/node.py @@ -1452,6 +1452,19 @@ class ApplyNodePlatform(BaseMaasAction): class ApplyNodeStorage(BaseMaasAction): """Action configure node storage.""" + # NOTE(sh8121att) Partition tables take size and it seems if the first partition + # on a block device attempts to use the full size of the device + # MAAS will fail that the device is not large enough + # It may be that the block device available_size does not include overhead + # for the partition table and once the table is written, there is not + # enough space for the 'full size' partition. So reserve the below + # when calculating 'rest of device' sizing w/ the '>' operator + # + # This size is based on documentation that for backwards compatability + # the first partition should start on LBA 63 and we'll assume 4096 byte + # blocks, thus 63 (add one for safety) x 4096 = 258048 + PART_TABLE_RESERVATION = 258048 + def start(self): try: machine_list = maas_machine.Machines(self.maas_client) @@ -1609,8 +1622,8 @@ class ApplyNodeStorage(BaseMaasAction): self.maas_client, size=size, bootable=p.bootable) if p.part_uuid is not None: part.uuid = p.part_uuid - msg = "Creating partition %s on dev %s (%s)" % ( - p.name, d.name, n.get_logicalname(d.name)) + msg = "Creating partition %s sized %d bytes on dev %s (%s)" % ( + p.name, size, d.name, n.get_logicalname(d.name)) self.logger.debug(msg) part = maas_dev.create_partition(part) self.task.add_status_msg( @@ -1789,7 +1802,7 @@ class ApplyNodeStorage(BaseMaasAction): raise errors.NotEnoughStorage() if match.group(1) == '>': - computed_size = int(context.available_size) + computed_size = int(context.available_size) - ApplyNodeStorage.PART_TABLE_RESERVATION return computed_size diff --git a/tests/unit/test_maasdriver_calculate_bytes.py b/tests/unit/test_maasdriver_calculate_bytes.py index 9c6df334..7ffd5cdf 100644 --- a/tests/unit/test_maasdriver_calculate_bytes.py +++ b/tests/unit/test_maasdriver_calculate_bytes.py @@ -205,4 +205,4 @@ class TestCalculateBytes(): calc_size = ApplyNodeStorage.calculate_bytes( size_str=size_str, context=vg) - assert calc_size == vg_available + assert calc_size == vg_available - ApplyNodeStorage.PART_TABLE_RESERVATION