From a67ce9b8cdb790ea91a8c0a87273f4b8989d8811 Mon Sep 17 00:00:00 2001 From: Dan Bungert Date: Mon, 3 Apr 2023 11:06:57 -0600 Subject: [PATCH] storage: autoinstall sizing-policy Co-authored-by: Ryan Mounce --- documentation/autoinstall-reference.md | 18 ++++++++++++ subiquity/common/tests/test_types.py | 32 ++++++++++++++++++++++ subiquity/common/types.py | 8 ++++++ subiquity/server/controllers/filesystem.py | 7 +++-- 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 subiquity/common/tests/test_types.py diff --git a/documentation/autoinstall-reference.md b/documentation/autoinstall-reference.md index 6c66326b..d34852dd 100644 --- a/documentation/autoinstall-reference.md +++ b/documentation/autoinstall-reference.md @@ -311,6 +311,24 @@ When using the "lvm" layout, LUKS encryption can be enabled by supplying a passw The default is to use the lvm layout. +#### sizing-policy + +The lvm layout will, by default, attempt to leave room for snapshots and further expansion. A sizing-policy key may be supplied to control this behavior. + +**type:** string (enumeration) +**default:** scaled + +Supported values are: + + * `scaled` -> adjust space allocated to the root LV based on space available to the VG + * `all` -> allocate all remaining VG space to the root LV + +The scaling system is currently as follows: + * Less than 10 GiB: use all remaining space for root filesystem + * Between 10-20 GiB: 10 GiB root filesystem + * Between 20-200 GiB: use half of remaining space for root filesystem + * Greater than 200 GiB: 100 GiB root filesystem + #### action-based config For full flexibility, the installer allows storage configuration to be done using a syntax which is a superset of that supported by curtin, described at https://curtin.readthedocs.io/en/latest/topics/storage.html. diff --git a/subiquity/common/tests/test_types.py b/subiquity/common/tests/test_types.py new file mode 100644 index 00000000..cc59e4fc --- /dev/null +++ b/subiquity/common/tests/test_types.py @@ -0,0 +1,32 @@ +# Copyright 2023 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.types import SizingPolicy + + +class TestSizingPolicy(unittest.TestCase): + def test_all(self): + actual = SizingPolicy.from_string('all') + self.assertEqual(SizingPolicy.ALL, actual) + + def test_scaled_size(self): + actual = SizingPolicy.from_string('scaled') + self.assertEqual(SizingPolicy.SCALED, actual) + + def test_default(self): + actual = SizingPolicy.from_string(None) + self.assertEqual(SizingPolicy.SCALED, actual) diff --git a/subiquity/common/types.py b/subiquity/common/types.py index fd28e642..b86c77a6 100644 --- a/subiquity/common/types.py +++ b/subiquity/common/types.py @@ -379,6 +379,14 @@ class SizingPolicy(enum.Enum): SCALED = enum.auto() ALL = enum.auto() + @classmethod + def from_string(cls, value): + if value is None or value == 'scaled': + return cls.SCALED + if value == 'all': + return cls.ALL + raise Exception(f'Unknown SizingPolicy value {value}') + @attr.s(auto_attribs=True) class GuidedResizeValues: diff --git a/subiquity/server/controllers/filesystem.py b/subiquity/server/controllers/filesystem.py index cdd7945e..61618f71 100644 --- a/subiquity/server/controllers/filesystem.py +++ b/subiquity/server/controllers/filesystem.py @@ -976,8 +976,11 @@ class FilesystemController(SubiquityController, FilesystemManipulator): else: capability = GuidedCapability.DIRECT password = layout.get('password', None) - await self.guided(GuidedChoiceV2(target=target, capability=capability, - password=password)) + sizing_policy = SizingPolicy.from_string( + layout.get('sizing-policy', None)) + await self.guided( + GuidedChoiceV2(target=target, capability=capability, + password=password, sizing_policy=sizing_policy)) def validate_layout_mode(self, mode): if mode not in ('reformat_disk', 'use_gap'):