diff --git a/subiquity/common/filesystem/manipulator.py b/subiquity/common/filesystem/manipulator.py
index 6faa2c60..cffac81d 100644
--- a/subiquity/common/filesystem/manipulator.py
+++ b/subiquity/common/filesystem/manipulator.py
@@ -15,74 +15,15 @@
import logging
-import attr
-
-from subiquity.common.filesystem import boot, gaps
+from subiquity.common.filesystem import boot, gaps, sizes
from subiquity.common.types import Bootloader
from subiquity.models.filesystem import (
align_up,
- MiB,
Partition,
)
log = logging.getLogger('subiquity.common.filesystem.manipulator')
-BIOS_GRUB_SIZE_BYTES = 1 * MiB
-PREP_GRUB_SIZE_BYTES = 8 * MiB
-
-
-@attr.s(auto_attribs=True)
-class PartitionScaleFactors:
- minimum: int
- priority: int
- maximum: int
-
-
-uefi_scale = PartitionScaleFactors(
- minimum=538 * MiB,
- priority=538,
- maximum=1075 * MiB)
-bootfs_scale = PartitionScaleFactors(
- minimum=768 * MiB,
- priority=1024,
- maximum=1536 * MiB)
-rootfs_scale = PartitionScaleFactors(
- minimum=900 * MiB,
- priority=10000,
- maximum=-1)
-
-
-def scale_partitions(all_factors, disk_size):
- """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.
- 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)
- if scaled < cur.minimum:
- ret.append(cur.minimum)
- elif scaled > cur.maximum:
- ret.append(cur.maximum)
- else:
- ret.append(scaled)
- if -1 in ret:
- used = sum(filter(lambda x: x != -1, ret))
- idx = ret.index(-1)
- ret[idx] = disk_size - used
- return ret
-
-
-def get_efi_size(disk):
- all_factors = (uefi_scale, bootfs_scale, rootfs_scale)
- return scale_partitions(all_factors, disk.size)[0]
-
-
-def get_bootfs_size(disk):
- all_factors = (uefi_scale, bootfs_scale, rootfs_scale)
- return scale_partitions(all_factors, disk.size)[1]
-
class FilesystemManipulator:
@@ -157,7 +98,7 @@ class FilesystemManipulator:
def _create_boot_partition(self, disk):
bootloader = self.model.bootloader
if bootloader == Bootloader.UEFI:
- part_size = get_efi_size(disk)
+ part_size = sizes.get_efi_size(disk)
log.debug('_create_boot_partition - adding EFI partition')
spec = dict(size=part_size, fstype='fat32')
if self.model._mount_for_path("/boot/efi") is None:
@@ -168,7 +109,7 @@ class FilesystemManipulator:
log.debug('_create_boot_partition - adding PReP partition')
part = self._create_boot_with_resize(
disk,
- dict(size=PREP_GRUB_SIZE_BYTES, fstype=None, mount=None),
+ dict(size=sizes.PREP_GRUB_SIZE_BYTES, fstype=None, mount=None),
# must be wiped or grub-install will fail
wipe='zero',
flag='prep', grub_device=True)
@@ -176,7 +117,7 @@ class FilesystemManipulator:
log.debug('_create_boot_partition - adding bios_grub partition')
part = self._create_boot_with_resize(
disk,
- dict(size=BIOS_GRUB_SIZE_BYTES, fstype=None, mount=None),
+ dict(size=sizes.BIOS_GRUB_SIZE_BYTES, fstype=None, mount=None),
flag='bios_grub')
disk.grub_device = True
return part
diff --git a/subiquity/common/filesystem/sizes.py b/subiquity/common/filesystem/sizes.py
new file mode 100644
index 00000000..22edd1be
--- /dev/null
+++ b/subiquity/common/filesystem/sizes.py
@@ -0,0 +1,77 @@
+# Copyright 2022 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import attr
+
+from subiquity.models.filesystem import (
+ MiB,
+ )
+
+
+BIOS_GRUB_SIZE_BYTES = 1 * MiB
+PREP_GRUB_SIZE_BYTES = 8 * MiB
+
+
+@attr.s(auto_attribs=True)
+class PartitionScaleFactors:
+ minimum: int
+ priority: int
+ maximum: int
+
+
+uefi_scale = PartitionScaleFactors(
+ minimum=538 * MiB,
+ priority=538,
+ maximum=1075 * MiB)
+bootfs_scale = PartitionScaleFactors(
+ minimum=768 * MiB,
+ priority=1024,
+ maximum=1536 * MiB)
+rootfs_scale = PartitionScaleFactors(
+ minimum=900 * MiB,
+ priority=10000,
+ maximum=-1)
+
+
+def scale_partitions(all_factors, disk_size):
+ """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.
+ 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)
+ if scaled < cur.minimum:
+ ret.append(cur.minimum)
+ elif scaled > cur.maximum:
+ ret.append(cur.maximum)
+ else:
+ ret.append(scaled)
+ if -1 in ret:
+ used = sum(filter(lambda x: x != -1, ret))
+ idx = ret.index(-1)
+ ret[idx] = disk_size - used
+ return ret
+
+
+def get_efi_size(disk):
+ all_factors = (uefi_scale, bootfs_scale, rootfs_scale)
+ return scale_partitions(all_factors, disk.size)[0]
+
+
+def get_bootfs_size(disk):
+ all_factors = (uefi_scale, bootfs_scale, rootfs_scale)
+ return scale_partitions(all_factors, disk.size)[1]
diff --git a/subiquity/common/filesystem/tests/test_manipulator.py b/subiquity/common/filesystem/tests/test_manipulator.py
index f8a4050c..0f1c6d7b 100644
--- a/subiquity/common/filesystem/tests/test_manipulator.py
+++ b/subiquity/common/filesystem/tests/test_manipulator.py
@@ -19,15 +19,7 @@ from subiquity.common.filesystem.actions import (
DeviceAction,
)
from subiquity.common.filesystem import gaps
-from subiquity.common.filesystem.manipulator import (
- bootfs_scale,
- FilesystemManipulator,
- get_efi_size,
- get_bootfs_size,
- PartitionScaleFactors,
- scale_partitions,
- uefi_scale,
- )
+from subiquity.common.filesystem.manipulator import FilesystemManipulator
from subiquity.models.tests.test_filesystem import (
make_disk,
make_model,
@@ -242,57 +234,3 @@ class TestFilesystemManipulator(unittest.TestCase):
manipulator.add_boot_disk(disk1)
part = gaps.parts_and_gaps(disk1)[0]
self.assertEqual(1024 * 1024, part.offset)
-
-
-class TestPartitionSizeScaling(unittest.TestCase):
- def test_scale_factors(self):
- psf = [
- PartitionScaleFactors(minimum=100, priority=500, maximum=500),
- PartitionScaleFactors(minimum=1000, priority=9500, maximum=-1),
- ]
-
- # match priorities, should get same values back
- self.assertEqual([500, 9500], scale_partitions(psf, 10000))
-
- # half priorities, should be scaled
- self.assertEqual([250, 4750], scale_partitions(psf, 5000))
-
- # hit max on first partition, second should use rest of space
- self.assertEqual([500, 19500], scale_partitions(psf, 20000))
-
- # minimums
- self.assertEqual([100, 1000], scale_partitions(psf, 1100))
-
- # ints
- self.assertEqual([105, 1996], scale_partitions(psf, 2101))
-
- def test_no_max_equal_minus_one(self):
- psf = [
- PartitionScaleFactors(minimum=100, priority=500, maximum=500),
- PartitionScaleFactors(minimum=100, priority=500, maximum=500),
- ]
-
- 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),
- # and something small to hit minimums
- (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))
-
- # something in between for scaling
- disk_size = 15 << 30
- disk = make_disk(manipulator.model, preserve=True, size=disk_size)
- efi_size = get_efi_size(disk)
- self.assertTrue(uefi_scale.maximum > efi_size)
- self.assertTrue(efi_size > uefi_scale.minimum)
- bootfs_size = get_bootfs_size(disk)
- self.assertTrue(bootfs_scale.maximum > bootfs_size)
- self.assertTrue(bootfs_size > bootfs_scale.minimum)
diff --git a/subiquity/common/filesystem/tests/test_sizes.py b/subiquity/common/filesystem/tests/test_sizes.py
new file mode 100644
index 00000000..277b915f
--- /dev/null
+++ b/subiquity/common/filesystem/tests/test_sizes.py
@@ -0,0 +1,82 @@
+# Copyright 2022 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import unittest
+
+from subiquity.common.filesystem.sizes import (
+ bootfs_scale,
+ get_efi_size,
+ get_bootfs_size,
+ PartitionScaleFactors,
+ 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):
+ def test_scale_factors(self):
+ psf = [
+ PartitionScaleFactors(minimum=100, priority=500, maximum=500),
+ PartitionScaleFactors(minimum=1000, priority=9500, maximum=-1),
+ ]
+
+ # match priorities, should get same values back
+ self.assertEqual([500, 9500], scale_partitions(psf, 10000))
+
+ # half priorities, should be scaled
+ self.assertEqual([250, 4750], scale_partitions(psf, 5000))
+
+ # hit max on first partition, second should use rest of space
+ self.assertEqual([500, 19500], scale_partitions(psf, 20000))
+
+ # minimums
+ self.assertEqual([100, 1000], scale_partitions(psf, 1100))
+
+ # ints
+ self.assertEqual([105, 1996], scale_partitions(psf, 2101))
+
+ def test_no_max_equal_minus_one(self):
+ psf = [
+ PartitionScaleFactors(minimum=100, priority=500, maximum=500),
+ PartitionScaleFactors(minimum=100, priority=500, maximum=500),
+ ]
+
+ 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),
+ # and something small to hit minimums
+ (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))
+
+ # something in between for scaling
+ disk_size = 15 << 30
+ disk = make_disk(manipulator.model, preserve=True, size=disk_size)
+ efi_size = get_efi_size(disk)
+ self.assertTrue(uefi_scale.maximum > efi_size)
+ self.assertTrue(efi_size > uefi_scale.minimum)
+ bootfs_size = get_bootfs_size(disk)
+ 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 3bb5beb7..8be3d947 100644
--- a/subiquity/server/controllers/filesystem.py
+++ b/subiquity/server/controllers/filesystem.py
@@ -41,10 +41,9 @@ from subiquity.common.errorreport import ErrorReportKind
from subiquity.common.filesystem.actions import (
DeviceAction,
)
-from subiquity.common.filesystem import boot, gaps, labels
+from subiquity.common.filesystem import boot, gaps, labels, sizes
from subiquity.common.filesystem.manipulator import (
FilesystemManipulator,
- get_bootfs_size,
)
from subiquity.common.types import (
Bootloader,
@@ -146,7 +145,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
gap = gaps.largest_gap(disk)
self.create_partition(
device=disk, gap=gap, spec=dict(
- size=get_bootfs_size(disk),
+ size=sizes.get_bootfs_size(disk),
fstype="ext4",
mount='/boot'
))