From 5920fa15837cee23b53ff347e15aa7336403d062 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Thu, 8 Apr 2021 17:55:36 +0200 Subject: [PATCH] size_chooser: Add support for overprovisioned devices Currently the max size is limited by the sum of parent devices sizes. Stratis filesystems are first devices where we support overprovisioning (Stratis filesystem is always 1 TiB) so we need a special exception for them. --- blivetgui/dialogs/size_chooser.py | 22 +++++++++++++++++----- tests/blivetgui_tests/size_widgets_test.py | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/blivetgui/dialogs/size_chooser.py b/blivetgui/dialogs/size_chooser.py index 53cf46b8..b41aa563 100644 --- a/blivetgui/dialogs/size_chooser.py +++ b/blivetgui/dialogs/size_chooser.py @@ -65,7 +65,7 @@ class SizeArea(GUIWidget): name = "size area" glade_file = "size_area.ui" - def __init__(self, device_type, parents, min_limit, max_limit, raid_type): + def __init__(self, device_type, parents, min_limit, max_limit, raid_type, overprovisioning=False): """ :param device_type: type of device we are creating :param parents: list of available/selected parents @@ -89,6 +89,7 @@ def __init__(self, device_type, parents, min_limit, max_limit, raid_type): self._min_size_limit = min_limit self._max_size_limit = max_limit + self._overprovisioning = overprovisioning # "main" size chooser self.main_chooser = SizeChooser(max_size=self.max_size, min_size=self.min_size) @@ -157,7 +158,10 @@ def max_size(self): parents, raid level and limits for the newly created device """ if self._parent_area is None: - return min(sum(parent.max_size for parent in self.parents), self.max_size_limit) + if self._overprovisioning: + return self.max_size_limit + else: + return min(sum(parent.max_size for parent in self.parents), self.max_size_limit) else: return self._parent_area.total_max @@ -223,10 +227,18 @@ def get_selection(self): them (either specified by user or just fraction of total size) """ if self._parent_area is None: - # no advanced selection -> we will use all available parents and set - # same size for each of them and return total selected size total_size = self.main_chooser.selected_size - parents = self._get_parents_allocation() + + if self._overprovisioning: + # with overprovisioning parent allocation doesn't really make sense + parents = [ParentSelection(parent_device=p.device, + free_space=size.Size(0), + selected_size=total_size) for p in self.parents] + else: + # no advanced selection -> we will use all available parents and set + # same size for each of them and return total selected size + parents = self._get_parents_allocation() + return SizeSelection(total_size=total_size, parents=parents) else: # selection is handled by the parent area diff --git a/tests/blivetgui_tests/size_widgets_test.py b/tests/blivetgui_tests/size_widgets_test.py index 6306f24a..837ac464 100644 --- a/tests/blivetgui_tests/size_widgets_test.py +++ b/tests/blivetgui_tests/size_widgets_test.py @@ -573,6 +573,28 @@ def test_70_parent_allocation(self): selected_sizes = [r.selected_size for r in ret] self.assertListEqual(selected_sizes, [Size(1), Size(2)]) + def test_75_parent_allocation_overprovisioning(self): + """ Test allocating size on parents without ParentArea with overprovisioning """ + + # -- same size parents + parents = [MagicMock(device=self._mock_device(), min_size=Size("1 MiB"), max_size=Size("1 GiB"), + reserved_size=Size(0)), + MagicMock(device=self._mock_device(), min_size=Size("1 MiB"), max_size=Size("1 GiB"), + reserved_size=Size(0))] + + size_area = SizeArea(device_type="lvm", parents=parents, + min_limit=Size(1), max_limit=Size("200 GiB"), + raid_type=None, overprovisioning=True) + + # select maximum (bigger than parents) --> both parents should have max_limit selected + size_area.main_chooser.selected_size = Size("200 GiB") + ret = size_area.get_selection() + self.assertEqual(len(ret.parents), 2) + self.assertEqual(ret.parents[0].parent_device, parents[0].device) + self.assertEqual(ret.parents[0].selected_size, Size("200 GiB")) + self.assertEqual(ret.parents[1].parent_device, parents[1].device) + self.assertEqual(ret.parents[1].selected_size, Size("200 GiB")) + @unittest.skipUnless("DISPLAY" in os.environ.keys(), "requires X server") class ParentAreaTest(unittest.TestCase):