From 8a16a74d341b70b36f120fa68f2a9efd385f8855 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Fri, 10 Jun 2022 11:52:41 -0600 Subject: [PATCH 1/3] filesystem: send minimal gaps to create_partition Before calling create_partition, pre-split gaps to the desired size of the partition. --- subiquity/common/filesystem/boot.py | 2 +- subiquity/common/filesystem/manipulator.py | 1 + subiquity/server/controllers/filesystem.py | 22 +++++++++------------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/subiquity/common/filesystem/boot.py b/subiquity/common/filesystem/boot.py index cb148d55..a9f29f20 100644 --- a/subiquity/common/filesystem/boot.py +++ b/subiquity/common/filesystem/boot.py @@ -209,7 +209,7 @@ def get_add_part_plan(device, *, spec, args): create_part_plan = CreatePartPlan(gap=None, spec=spec, args=args) if gaps.largest_gap_size(device) >= size: - create_part_plan.gap = gaps.largest_gap(device) + create_part_plan.gap = gaps.largest_gap(device).split(size)[0] return create_part_plan else: new_parts = [p for p in partitions if not p.preserve] diff --git a/subiquity/common/filesystem/manipulator.py b/subiquity/common/filesystem/manipulator.py index e6ca3f51..1d59ceb9 100644 --- a/subiquity/common/filesystem/manipulator.py +++ b/subiquity/common/filesystem/manipulator.py @@ -220,6 +220,7 @@ class FilesystemManipulator: spec['size'], gap.size) spec['size'] = gap.size + gap = gap.split(spec['size'])[0] self.create_partition(disk, gap, spec) log.debug("Successfully added partition") diff --git a/subiquity/server/controllers/filesystem.py b/subiquity/server/controllers/filesystem.py index c0a265da..371fd8ff 100644 --- a/subiquity/server/controllers/filesystem.py +++ b/subiquity/server/controllers/filesystem.py @@ -148,18 +148,13 @@ class FilesystemController(SubiquityController, FilesystemManipulator): if DeviceAction.TOGGLE_BOOT in DeviceAction.supported(disk): self.add_boot_disk(disk) gap = gaps.largest_gap(disk) - self.create_partition( - device=disk, gap=gap, spec=dict( - size=sizes.get_bootfs_size(disk), - fstype="ext4", - mount='/boot' - )) - gap = gaps.largest_gap(disk) - part = self.create_partition( - device=disk, gap=gap, spec=dict( - size=gaps.largest_gap_size(disk), - fstype=None, - )) + size = sizes.get_bootfs_size(disk) + gap_boot, gap_rest = gap.split(size) + spec = dict(size=size, fstype="ext4", mount='/boot') + self.create_partition(device=disk, gap=gap_boot, spec=spec) + + spec = dict(size=gap_rest.size, fstype=None) + part = self.create_partition(device=disk, gap=gap_rest, spec=spec) vg_name = 'ubuntu-vg' i = 0 while self.model._one(type='lvm_volgroup', name=vg_name) is not None: @@ -376,7 +371,8 @@ class FilesystemController(SubiquityController, FilesystemManipulator): 'mount': data.partition.mount, } - self.create_partition(disk, data.gap, spec, wipe='superblock') + gap = gaps.at_offset(disk, data.gap.offset).split(requested_size)[0] + self.create_partition(disk, gap, spec, wipe='superblock') return await self.v2_GET() async def v2_delete_partition_POST(self, data: ModifyPartitionV2) \ From 19631f04ffc54dea1593c36b30a5b960529971a4 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Fri, 10 Jun 2022 14:29:03 -0600 Subject: [PATCH 2/3] filesystem: create_partition size from gap Previously it used the size from the spec --- subiquity/common/filesystem/manipulator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subiquity/common/filesystem/manipulator.py b/subiquity/common/filesystem/manipulator.py index 1d59ceb9..8a171cde 100644 --- a/subiquity/common/filesystem/manipulator.py +++ b/subiquity/common/filesystem/manipulator.py @@ -79,7 +79,7 @@ class FilesystemManipulator: def create_partition(self, device, gap, spec, **kw): part = self.model.add_partition( - device, size=spec["size"], offset=gap.offset, **kw) + device, size=gap.size, offset=gap.offset, **kw) self.create_filesystem(part, spec) return part From 6dffc15748b0ceb8c9ae4b158f20b00b9d46d86f Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Tue, 14 Jun 2022 13:30:51 -0600 Subject: [PATCH 3/3] filesystem: bootfs size func takes an input size Previously it operated on a disk, but we may want to scale based on only part of a disk. --- subiquity/common/filesystem/boot.py | 3 ++- subiquity/common/filesystem/sizes.py | 16 ++++++++-------- .../common/filesystem/tests/test_manipulator.py | 2 +- subiquity/common/filesystem/tests/test_sizes.py | 14 ++++---------- subiquity/server/controllers/filesystem.py | 2 +- 5 files changed, 16 insertions(+), 21 deletions(-) diff --git a/subiquity/common/filesystem/boot.py b/subiquity/common/filesystem/boot.py index a9f29f20..9aa9fbd8 100644 --- a/subiquity/common/filesystem/boot.py +++ b/subiquity/common/filesystem/boot.py @@ -239,7 +239,8 @@ def get_boot_device_plan_uefi(device): plans.append(MountBootEfiPlan(part)) return MultiStepPlan(plans=plans) - spec = dict(size=sizes.get_efi_size(device), fstype='fat32', mount=None) + size = sizes.get_efi_size(device.size) + spec = dict(size=size, fstype='fat32', mount=None) if device._m._mount_for_path("/boot/efi") is None: spec['mount'] = '/boot/efi' diff --git a/subiquity/common/filesystem/sizes.py b/subiquity/common/filesystem/sizes.py index fec1375e..c494e721 100644 --- a/subiquity/common/filesystem/sizes.py +++ b/subiquity/common/filesystem/sizes.py @@ -45,15 +45,15 @@ rootfs_scale = PartitionScaleFactors( maximum=-1) -def scale_partitions(all_factors, disk_size): +def scale_partitions(all_factors, available_space): """for the list of scale factors, provide list of scaled partition size. Assumes at most one scale factor with maximum==-1, and - disk_size is at least as big as the sum of all partition minimums. + available_space is at least as big as the sum of all partition minimums. The scale factor with maximum==-1 is given all remaining disk space.""" ret = [] sum_priorities = sum([factor.priority for factor in all_factors]) for cur in all_factors: - scaled = int((disk_size / sum_priorities) * cur.priority) + scaled = int((available_space / sum_priorities) * cur.priority) if scaled < cur.minimum: ret.append(cur.minimum) elif scaled > cur.maximum: @@ -63,15 +63,15 @@ def scale_partitions(all_factors, disk_size): if -1 in ret: used = sum(filter(lambda x: x != -1, ret)) idx = ret.index(-1) - ret[idx] = disk_size - used + ret[idx] = available_space - used return ret -def get_efi_size(disk): +def get_efi_size(available_space): all_factors = (uefi_scale, bootfs_scale, rootfs_scale) - return scale_partitions(all_factors, disk.size)[0] + return scale_partitions(all_factors, available_space)[0] -def get_bootfs_size(disk): +def get_bootfs_size(available_space): all_factors = (uefi_scale, bootfs_scale, rootfs_scale) - return scale_partitions(all_factors, disk.size)[1] + return scale_partitions(all_factors, available_space)[1] diff --git a/subiquity/common/filesystem/tests/test_manipulator.py b/subiquity/common/filesystem/tests/test_manipulator.py index 108ee3c2..7ca13371 100644 --- a/subiquity/common/filesystem/tests/test_manipulator.py +++ b/subiquity/common/filesystem/tests/test_manipulator.py @@ -474,7 +474,7 @@ class TestFilesystemManipulator(unittest.TestCase): def boot_size_for_disk(self, disk): bl = disk._m.bootloader if bl == Bootloader.UEFI: - return sizes.get_efi_size(disk) + return sizes.get_efi_size(disk.size) elif bl == Bootloader.PREP: return sizes.PREP_GRUB_SIZE_BYTES else: diff --git a/subiquity/common/filesystem/tests/test_sizes.py b/subiquity/common/filesystem/tests/test_sizes.py index e908f5fd..191441ca 100644 --- a/subiquity/common/filesystem/tests/test_sizes.py +++ b/subiquity/common/filesystem/tests/test_sizes.py @@ -23,9 +23,6 @@ from subiquity.common.filesystem.sizes import ( scale_partitions, uefi_scale, ) -from subiquity.common.filesystem.tests.test_manipulator import make_manipulator -from subiquity.models.filesystem import Bootloader -from subiquity.models.tests.test_filesystem import make_disk class TestPartitionSizeScaling(unittest.TestCase): @@ -59,7 +56,6 @@ class TestPartitionSizeScaling(unittest.TestCase): self.assertEqual([500, 500], scale_partitions(psf, 2000)) def test_efi(self): - manipulator = make_manipulator(Bootloader.UEFI) tests = [ # something large to hit maximums (30 << 30, uefi_scale.maximum, bootfs_scale.maximum), @@ -67,16 +63,14 @@ class TestPartitionSizeScaling(unittest.TestCase): (8 << 30, uefi_scale.minimum, bootfs_scale.minimum), ] for disk_size, uefi, bootfs in tests: - disk = make_disk(manipulator.model, preserve=True, size=disk_size) - self.assertEqual(uefi, get_efi_size(disk)) - self.assertEqual(bootfs, get_bootfs_size(disk)) + self.assertEqual(uefi, get_efi_size(disk_size)) + self.assertEqual(bootfs, get_bootfs_size(disk_size)) # something in between for scaling disk_size = 20 << 30 - disk = make_disk(manipulator.model, preserve=True, size=disk_size) - efi_size = get_efi_size(disk) + efi_size = get_efi_size(disk_size) self.assertTrue(uefi_scale.maximum > efi_size) self.assertTrue(efi_size > uefi_scale.minimum) - bootfs_size = get_bootfs_size(disk) + bootfs_size = get_bootfs_size(disk_size) self.assertTrue(bootfs_scale.maximum > bootfs_size) self.assertTrue(bootfs_size > bootfs_scale.minimum) diff --git a/subiquity/server/controllers/filesystem.py b/subiquity/server/controllers/filesystem.py index 371fd8ff..53927442 100644 --- a/subiquity/server/controllers/filesystem.py +++ b/subiquity/server/controllers/filesystem.py @@ -148,7 +148,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator): if DeviceAction.TOGGLE_BOOT in DeviceAction.supported(disk): self.add_boot_disk(disk) gap = gaps.largest_gap(disk) - size = sizes.get_bootfs_size(disk) + size = sizes.get_bootfs_size(gap.size) gap_boot, gap_rest = gap.split(size) spec = dict(size=size, fstype="ext4", mount='/boot') self.create_partition(device=disk, gap=gap_boot, spec=spec)