diff --git a/subiquity/ui/views/filesystem/partition.py b/subiquity/ui/views/filesystem/partition.py index cc43ef512..3bf2fe7c4 100644 --- a/subiquity/ui/views/filesystem/partition.py +++ b/subiquity/ui/views/filesystem/partition.py @@ -21,6 +21,7 @@ """ import logging import re +from typing import Optional from urwid import connect_signal, Text @@ -91,6 +92,7 @@ def _make_widget(self, form): class SizeWidget(StringEditor): def __init__(self, form): self.form = form + self.accurate_value: Optional[int] = None super().__init__() def lost_focus(self): @@ -112,6 +114,9 @@ def lost_focus(self): ('info_minor', _("Capped partition size at {size}").format( size=self.form.size_str))) + # This will invoke self.form.clean_size() and it is expected that + # size_str (and therefore self.value) are propertly aligned. + self.accurate_value = self.form.size else: aligned_sz = align_up(sz, self.form.alignment) aligned_sz_str = humanize_size(aligned_sz) @@ -120,6 +125,7 @@ def lost_focus(self): self.form.size.show_extra( ('info_minor', _("Rounded size up to {size}").format( size=aligned_sz_str))) + self.accurate_value = aligned_sz class SizeField(FormField): diff --git a/subiquity/ui/views/filesystem/tests/test_partition.py b/subiquity/ui/views/filesystem/tests/test_partition.py index cde9fbaaf..acb194b7c 100644 --- a/subiquity/ui/views/filesystem/tests/test_partition.py +++ b/subiquity/ui/views/filesystem/tests/test_partition.py @@ -9,6 +9,7 @@ from subiquity.client.controllers.filesystem import FilesystemController from subiquity.common.filesystem import gaps from subiquity.models.filesystem import ( + MiB, dehumanize_size, ) from subiquity.models.tests.test_filesystem import ( @@ -64,6 +65,7 @@ def test_create_partition(self): gap = gaps.Gap(device=disk, offset=1 << 20, size=99 << 30) view, stretchy = make_partition_view(model, disk, gap=gap) view_helpers.enter_data(stretchy.form, valid_data) + stretchy.form.size.widget.lost_focus() view_helpers.click(stretchy.form.done_btn.base_widget) valid_data['mount'] = '/' valid_data['size'] = dehumanize_size(valid_data['size']) @@ -82,6 +84,7 @@ def test_edit_partition(self): view, stretchy = make_partition_view(model, disk, partition=partition) self.assertTrue(stretchy.form.done_btn.enabled) view_helpers.enter_data(stretchy.form, form_data) + stretchy.form.size.widget.lost_focus() view_helpers.click(stretchy.form.done_btn.base_widget) expected_data = { 'size': dehumanize_size(form_data['size']), @@ -117,6 +120,7 @@ def test_edit_existing_partition(self): self.assertFalse(stretchy.form.size.enabled) self.assertTrue(stretchy.form.done_btn.enabled) view_helpers.enter_data(stretchy.form, form_data) + stretchy.form.size.widget.lost_focus() view_helpers.click(stretchy.form.done_btn.base_widget) expected_data = { 'fstype': 'xfs', @@ -184,6 +188,7 @@ def test_edit_boot_partition(self): self.assertEqual(stretchy.form.mount.value, "/boot/efi") view_helpers.enter_data(stretchy.form, form_data) + stretchy.form.size.widget.lost_focus() view_helpers.click(stretchy.form.done_btn.base_widget) expected_data = { 'size': dehumanize_size(form_data['size']), @@ -252,3 +257,26 @@ def test_format_entire_unusual_filesystem(self): view, stretchy = make_format_entire_view(model, disk) self.assertEqual( stretchy.form.fstype.value, None) + + def test_create_partition_unaligned_size(self): + # In LP: #2013201, the user would type in 1.1G and the partition + # created would not be aligned to a MiB boundary. + unaligned_data = { + 'size': '1.1G', # Corresponds to 1181116006.4 bytes (not an int) + 'fstype': 'ext4', + } + valid_data = { + 'mount': '/', + 'size': 1127 * MiB, # ~1.10058 GiB + 'use_swap': False, + 'fstype': 'ext4', + } + model, disk = make_model_and_disk() + gap = gaps.Gap(device=disk, offset=1 << 20, size=99 << 30) + view, stretchy = make_partition_view(model, disk, gap=gap) + view_helpers.enter_data(stretchy.form, unaligned_data) + stretchy.form.size.widget.lost_focus() + view_helpers.click(stretchy.form.done_btn.base_widget) + view.controller.partition_disk_handler.assert_called_once_with( + stretchy.disk, valid_data, partition=None, gap=gap + ) diff --git a/subiquitycore/ui/form.py b/subiquitycore/ui/form.py index 3adaf258f..43cf51cf2 100644 --- a/subiquitycore/ui/form.py +++ b/subiquitycore/ui/form.py @@ -554,7 +554,11 @@ def as_data(self): data = {} for field in self._fields: if field.enabled: - data[field.field.name] = field.value + accurate_value = getattr(field.widget, "accurate_value", None) + if accurate_value is not None: + data[field.field.name] = accurate_value + else: + data[field.field.name] = field.value return data