diff --git a/subiquity/common/apidef.py b/subiquity/common/apidef.py index 25280e47..2bc90502 100644 --- a/subiquity/common/apidef.py +++ b/subiquity/common/apidef.py @@ -258,6 +258,9 @@ class API: def GET() -> StorageResponseV2: ... def POST() -> StorageResponseV2: ... + class orig_config: + def GET() -> StorageResponseV2: ... + class guided: def GET() -> GuidedStorageResponseV2: ... def POST(data: Payload[GuidedChoiceV2]) \ diff --git a/subiquity/models/filesystem.py b/subiquity/models/filesystem.py index 9becc0c4..f949d08a 100644 --- a/subiquity/models/filesystem.py +++ b/subiquity/models/filesystem.py @@ -1041,6 +1041,16 @@ class FilesystemModel(object): self.grub = None self.guided_configuration = None + def get_orig_model(self): + # The purpose of this is to be able to answer arbitrary questions about + # the original state. _orig_config plays a similar role, but is + # expressed in terms of curtin actions, which are not what we want to + # use on the V2 storage API. + orig_model = FilesystemModel(self.bootloader) + orig_model.target = self.target + orig_model.load_probe_data(self._probe_data) + return orig_model + def load_server_data(self, status): log.debug('load_server_data %s', status) self._all_ids = set() diff --git a/subiquity/server/controllers/filesystem.py b/subiquity/server/controllers/filesystem.py index 74ed90a2..8267174f 100644 --- a/subiquity/server/controllers/filesystem.py +++ b/subiquity/server/controllers/filesystem.py @@ -373,19 +373,26 @@ class FilesystemController(SubiquityController, FilesystemManipulator): for pa in self.model._partition_alignment_data.values())) return sizes.calculate_suggested_install_min(source_min, align) - async def v2_GET(self) -> StorageResponseV2: - disks = self.model._all(type='disk') + def get_v2_storage_response(self, model): + disks = model._all(type='disk') + minsize = self.calculate_suggested_install_min() return StorageResponseV2( disks=[labels.for_client(d) for d in disks], - need_root=not self.model.is_root_mounted(), - need_boot=self.model.needs_bootloader_partition(), - install_minimum_size=self.calculate_suggested_install_min(), + need_root=not model.is_root_mounted(), + need_boot=model.needs_bootloader_partition(), + install_minimum_size=minsize, ) + async def v2_GET(self) -> StorageResponseV2: + return self.get_v2_storage_response(self.model) + async def v2_POST(self) -> StorageResponseV2: await self.configured() return await self.v2_GET() + async def v2_orig_config_GET(self) -> StorageResponseV2: + return self.get_v2_storage_response(self.model.get_orig_model()) + async def v2_reset_POST(self) -> StorageResponseV2: log.info("Resetting Filesystem model") self.model.reset() diff --git a/subiquity/tests/api/test_api.py b/subiquity/tests/api/test_api.py index e1854c05..a9acdd5d 100755 --- a/subiquity/tests/api/test_api.py +++ b/subiquity/tests/api/test_api.py @@ -1101,6 +1101,22 @@ class TestPartitionTableEditing(TestAPI): self.assertEqual(-1, p3['estimated_min_size']) self.assertEqual(2 << 20, p4['estimated_min_size']) + @timeout() + async def test_v2_orig_config(self): + cfg = 'examples/win10-along-ubuntu.json' + extra = ['--storage-version', '2'] + async with start_server(cfg, extra_args=extra) as inst: + start_resp = await inst.get('/storage/v2') + resp = await inst.get('/storage/v2/guided') + resize = match(resp['possible'], + _type='GuidedStorageTargetResize')[0] + resize['new_size'] = 30 << 30 + await inst.post('/storage/v2/guided', {'target': resize}) + orig_config = await inst.get('/storage/v2/orig_config') + end_resp = await inst.get('/storage/v2') + self.assertEqual(start_resp, orig_config) + self.assertNotEqual(start_resp, end_resp) + class TestGap(TestAPI): async def test_blank_disk_is_one_big_gap(self):