move from use_lvm flag on guided fs things to more generic capabilities

This commit is contained in:
Michael Hudson-Doyle 2023-03-20 12:49:06 +13:00
parent cf9946a45d
commit 43ae143e17
4 changed files with 160 additions and 61 deletions

View File

@ -386,6 +386,12 @@ class StorageResponseV2:
install_minimum_size: Optional[int] = None install_minimum_size: Optional[int] = None
class GuidedCapability(enum.Enum):
DIRECT = enum.auto()
LVM = enum.auto()
LVM_LUKS = enum.auto()
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class GuidedResizeValues: class GuidedResizeValues:
install_max: int install_max: int
@ -397,6 +403,7 @@ class GuidedResizeValues:
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class GuidedStorageTargetReformat: class GuidedStorageTargetReformat:
disk_id: str disk_id: str
capabilities: List[GuidedCapability]
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
@ -407,9 +414,10 @@ class GuidedStorageTargetResize:
minimum: Optional[int] minimum: Optional[int]
recommended: Optional[int] recommended: Optional[int]
maximum: Optional[int] maximum: Optional[int]
capabilities: List[GuidedCapability]
@staticmethod @staticmethod
def from_recommendations(part, resize_vals): def from_recommendations(part, resize_vals, capabilities):
return GuidedStorageTargetResize( return GuidedStorageTargetResize(
disk_id=part.device.id, disk_id=part.device.id,
partition_number=part.number, partition_number=part.number,
@ -417,6 +425,7 @@ class GuidedStorageTargetResize:
minimum=resize_vals.minimum, minimum=resize_vals.minimum,
recommended=resize_vals.recommended, recommended=resize_vals.recommended,
maximum=resize_vals.maximum, maximum=resize_vals.maximum,
capabilities=capabilities,
) )
@ -424,6 +433,7 @@ class GuidedStorageTargetResize:
class GuidedStorageTargetUseGap: class GuidedStorageTargetUseGap:
disk_id: str disk_id: str
gap: Gap gap: Gap
capabilities: List[GuidedCapability]
GuidedStorageTarget = Union[GuidedStorageTargetReformat, GuidedStorageTarget = Union[GuidedStorageTargetReformat,
@ -434,14 +444,22 @@ GuidedStorageTarget = Union[GuidedStorageTargetReformat,
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class GuidedChoiceV2: class GuidedChoiceV2:
target: GuidedStorageTarget target: GuidedStorageTarget
use_lvm: bool = False capability: GuidedCapability
password: Optional[str] = attr.ib(default=None, repr=False) password: Optional[str] = attr.ib(default=None, repr=False)
@staticmethod @staticmethod
def from_guided_choice(choice: GuidedChoice): def from_guided_choice(choice: GuidedChoice):
if choice.use_lvm:
if choice.password is not None:
capability = GuidedCapability.LVM_LUKS
else:
capability = GuidedCapability.LVM
else:
capability = GuidedCapability.DIRECT
return GuidedChoiceV2( return GuidedChoiceV2(
target=GuidedStorageTargetReformat(disk_id=choice.disk_id), target=GuidedStorageTargetReformat(
use_lvm=choice.use_lvm, disk_id=choice.disk_id, capabilities=[capability]),
capability=capability,
password=choice.password, password=choice.password,
) )

View File

@ -58,6 +58,7 @@ from subiquity.common.types import (
AddPartitionV2, AddPartitionV2,
Bootloader, Bootloader,
Disk, Disk,
GuidedCapability,
GuidedChoice, GuidedChoice,
GuidedChoiceV2, GuidedChoiceV2,
GuidedStorageResponse, GuidedStorageResponse,
@ -355,9 +356,6 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
return gap return gap
def build_lvm_options(self, passphrase): def build_lvm_options(self, passphrase):
if passphrase is None:
return None
else:
return { return {
'encrypt': True, 'encrypt': True,
'luks_options': { 'luks_options': {
@ -377,11 +375,15 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
if gap is None: if gap is None:
raise Exception('failed to locate gap after adding boot') raise Exception('failed to locate gap after adding boot')
if choice.use_lvm: if choice.capability == GuidedCapability.LVM:
self.guided_lvm(gap, lvm_options=None)
elif choice.capability == GuidedCapability.LVM_LUKS:
lvm_options = self.build_lvm_options(choice.password) lvm_options = self.build_lvm_options(choice.password)
self.guided_lvm(gap, lvm_options=lvm_options) self.guided_lvm(gap, lvm_options=lvm_options)
else: elif choice.capability == GuidedCapability.DIRECT:
self.guided_direct(gap) self.guided_direct(gap)
else:
raise ValueError('cannot process capability')
async def _probe_response(self, wait, resp_cls): async def _probe_response(self, wait, resp_cls):
if not self._probe_task.done(): if not self._probe_task.done():
@ -683,9 +685,16 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
scenarios = [] scenarios = []
install_min = self.calculate_suggested_install_min() install_min = self.calculate_suggested_install_min()
capabilities = [
GuidedCapability.DIRECT,
GuidedCapability.LVM,
GuidedCapability.LVM_LUKS
]
for disk in self.potential_boot_disks(with_reformatting=True): for disk in self.potential_boot_disks(with_reformatting=True):
if disk.size >= install_min: if disk.size >= install_min:
reformat = GuidedStorageTargetReformat(disk_id=disk.id) reformat = GuidedStorageTargetReformat(
disk_id=disk.id, capabilities=capabilities)
scenarios.append((disk.size, reformat)) scenarios.append((disk.size, reformat))
for disk in self.potential_boot_disks(with_reformatting=False): for disk in self.potential_boot_disks(with_reformatting=False):
@ -697,8 +706,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
if gap is not None and gap.size >= install_min: if gap is not None and gap.size >= install_min:
api_gap = labels.for_client(gap) api_gap = labels.for_client(gap)
use_gap = GuidedStorageTargetUseGap( use_gap = GuidedStorageTargetUseGap(
disk_id=disk.id, disk_id=disk.id, gap=api_gap, capabilities=capabilities)
gap=api_gap)
scenarios.append((gap.size, use_gap)) scenarios.append((gap.size, use_gap))
for disk in self.potential_boot_disks(check_boot=False): for disk in self.potential_boot_disks(check_boot=False):
@ -714,14 +722,14 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
with_reformatting=False): with_reformatting=False):
continue continue
resize = GuidedStorageTargetResize.from_recommendations( resize = GuidedStorageTargetResize.from_recommendations(
partition, vals) partition, vals, capabilities=capabilities)
scenarios.append((vals.install_max, resize)) scenarios.append((vals.install_max, resize))
scenarios.sort(reverse=True, key=lambda x: x[0]) scenarios.sort(reverse=True, key=lambda x: x[0])
return GuidedStorageResponseV2( return GuidedStorageResponseV2(
status=ProbeStatus.DONE, status=ProbeStatus.DONE,
configured=self.model.guided_configuration, configured=self.model.guided_configuration,
possible=[s[1] for s in scenarios]) possible=[s[1] for s in scenarios if s[1].capabilities])
async def v2_guided_POST(self, data: GuidedChoiceV2) \ async def v2_guided_POST(self, data: GuidedChoiceV2) \
-> GuidedStorageResponseV2: -> GuidedStorageResponseV2:
@ -907,7 +915,8 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
if mode == 'reformat_disk': if mode == 'reformat_disk':
match = layout.get("match", {'size': 'largest'}) match = layout.get("match", {'size': 'largest'})
disk = self.model.disk_for_match(self.model.all_disks(), match) disk = self.model.disk_for_match(self.model.all_disks(), match)
target = GuidedStorageTargetReformat(disk_id=disk.id) target = GuidedStorageTargetReformat(
disk_id=disk.id, capabilities=[])
elif mode == 'use_gap': elif mode == 'use_gap':
bootable = [d for d in self.model.all_disks() bootable = [d for d in self.model.all_disks()
if boot.can_be_boot_device(d, with_reformatting=False)] if boot.can_be_boot_device(d, with_reformatting=False)]
@ -915,13 +924,21 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
if not gap: if not gap:
raise Exception("autoinstall cannot configure storage " raise Exception("autoinstall cannot configure storage "
"- no gap found large enough for install") "- no gap found large enough for install")
target = GuidedStorageTargetUseGap(disk_id=gap.device.id, gap=gap) target = GuidedStorageTargetUseGap(
disk_id=gap.device.id, gap=gap, capabilities=[])
log.info(f'autoinstall: running guided {name} install in mode {mode} ' log.info(f'autoinstall: running guided {name} install in mode {mode} '
f'using {target}') f'using {target}')
use_lvm = name == 'lvm'
password = layout.get('password', None) password = layout.get('password', None)
self.guided(GuidedChoiceV2(target=target, use_lvm=use_lvm, if name == 'lvm':
if password is not None:
capability = GuidedCapability.LVM_LUKS
else:
capability = GuidedCapability.LVM
else:
capability = GuidedCapability.DIRECT
password = layout.get('password', None)
self.guided(GuidedChoiceV2(target=target, capability=capability,
password=password)) password=password))
def validate_layout_mode(self, mode): def validate_layout_mode(self, mode):

View File

@ -26,6 +26,7 @@ from subiquitycore.tests.util import random_string
from subiquity.common.filesystem import gaps from subiquity.common.filesystem import gaps
from subiquity.common.types import ( from subiquity.common.types import (
Bootloader, Bootloader,
GuidedCapability,
GuidedChoiceV2, GuidedChoiceV2,
GuidedStorageTargetReformat, GuidedStorageTargetReformat,
GuidedStorageTargetResize, GuidedStorageTargetResize,
@ -47,6 +48,13 @@ bootloaders_and_ptables = [(bl, pt)
for pt in ('gpt', 'msdos', 'vtoc')] for pt in ('gpt', 'msdos', 'vtoc')]
default_capabilities = [
GuidedCapability.DIRECT,
GuidedCapability.LVM,
GuidedCapability.LVM_LUKS,
]
class TestSubiquityControllerFilesystem(IsolatedAsyncioTestCase): class TestSubiquityControllerFilesystem(IsolatedAsyncioTestCase):
def setUp(self): def setUp(self):
self.app = make_app() self.app = make_app()
@ -98,8 +106,10 @@ class TestGuided(IsolatedAsyncioTestCase):
@parameterized.expand(boot_expectations) @parameterized.expand(boot_expectations)
async def test_guided_direct(self, bootloader, ptable, p1mnt): async def test_guided_direct(self, bootloader, ptable, p1mnt):
self._guided_setup(bootloader, ptable) self._guided_setup(bootloader, ptable)
target = GuidedStorageTargetReformat(disk_id=self.d1.id) target = GuidedStorageTargetReformat(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=False)) disk_id=self.d1.id, capabilities=default_capabilities)
self.controller.guided(
GuidedChoiceV2(target=target, capability=GuidedCapability.DIRECT))
[d1p1, d1p2] = self.d1.partitions() [d1p1, d1p2] = self.d1.partitions()
self.assertEqual(p1mnt, d1p1.mount) self.assertEqual(p1mnt, d1p1.mount)
self.assertEqual('/', d1p2.mount) self.assertEqual('/', d1p2.mount)
@ -109,8 +119,10 @@ class TestGuided(IsolatedAsyncioTestCase):
async def test_guided_direct_BIOS_MSDOS(self): async def test_guided_direct_BIOS_MSDOS(self):
self._guided_setup(Bootloader.BIOS, 'msdos') self._guided_setup(Bootloader.BIOS, 'msdos')
target = GuidedStorageTargetReformat(disk_id=self.d1.id) target = GuidedStorageTargetReformat(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=False)) disk_id=self.d1.id, capabilities=default_capabilities)
self.controller.guided(
GuidedChoiceV2(target=target, capability=GuidedCapability.DIRECT))
[d1p1] = self.d1.partitions() [d1p1] = self.d1.partitions()
self.assertEqual('/', d1p1.mount) self.assertEqual('/', d1p1.mount)
self.assertFalse(d1p1.preserve) self.assertFalse(d1p1.preserve)
@ -119,8 +131,10 @@ class TestGuided(IsolatedAsyncioTestCase):
@parameterized.expand(boot_expectations) @parameterized.expand(boot_expectations)
async def test_guided_lvm(self, bootloader, ptable, p1mnt): async def test_guided_lvm(self, bootloader, ptable, p1mnt):
self._guided_setup(bootloader, ptable) self._guided_setup(bootloader, ptable)
target = GuidedStorageTargetReformat(disk_id=self.d1.id) target = GuidedStorageTargetReformat(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=True)) disk_id=self.d1.id, capabilities=default_capabilities)
self.controller.guided(GuidedChoiceV2(
target=target, capability=GuidedCapability.LVM))
[d1p1, d1p2, d1p3] = self.d1.partitions() [d1p1, d1p2, d1p3] = self.d1.partitions()
self.assertEqual(p1mnt, d1p1.mount) self.assertEqual(p1mnt, d1p1.mount)
self.assertEqual('/boot', d1p2.mount) self.assertEqual('/boot', d1p2.mount)
@ -135,8 +149,10 @@ class TestGuided(IsolatedAsyncioTestCase):
async def test_guided_lvm_BIOS_MSDOS(self): async def test_guided_lvm_BIOS_MSDOS(self):
self._guided_setup(Bootloader.BIOS, 'msdos') self._guided_setup(Bootloader.BIOS, 'msdos')
target = GuidedStorageTargetReformat(disk_id=self.d1.id) target = GuidedStorageTargetReformat(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=True)) disk_id=self.d1.id, capabilities=default_capabilities)
self.controller.guided(
GuidedChoiceV2(target=target, capability=GuidedCapability.LVM))
[d1p1, d1p2] = self.d1.partitions() [d1p1, d1p2] = self.d1.partitions()
self.assertEqual('/boot', d1p1.mount) self.assertEqual('/boot', d1p1.mount)
[vg] = self.model._all(type='lvm_volgroup') [vg] = self.model._all(type='lvm_volgroup')
@ -182,8 +198,10 @@ class TestGuided(IsolatedAsyncioTestCase):
self._guided_side_by_side(bl, pt) self._guided_side_by_side(bl, pt)
parts_before = self.d1._partitions.copy() parts_before = self.d1._partitions.copy()
gap = gaps.largest_gap(self.d1) gap = gaps.largest_gap(self.d1)
target = GuidedStorageTargetUseGap(disk_id=self.d1.id, gap=gap) target = GuidedStorageTargetUseGap(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=False)) disk_id=self.d1.id, gap=gap, capabilities=default_capabilities)
self.controller.guided(
GuidedChoiceV2(target=target, capability=GuidedCapability.DIRECT))
parts_after = gaps.parts_and_gaps(self.d1)[:-1] parts_after = gaps.parts_and_gaps(self.d1)[:-1]
self.assertEqual(parts_before, parts_after) self.assertEqual(parts_before, parts_after)
p = gaps.parts_and_gaps(self.d1)[-1] p = gaps.parts_and_gaps(self.d1)[-1]
@ -202,8 +220,10 @@ class TestGuided(IsolatedAsyncioTestCase):
self._guided_side_by_side(bl, pt) self._guided_side_by_side(bl, pt)
parts_before = self.d1._partitions.copy() parts_before = self.d1._partitions.copy()
gap = gaps.largest_gap(self.d1) gap = gaps.largest_gap(self.d1)
target = GuidedStorageTargetUseGap(disk_id=self.d1.id, gap=gap) target = GuidedStorageTargetUseGap(
self.controller.guided(GuidedChoiceV2(target=target, use_lvm=True)) disk_id=self.d1.id, gap=gap, capabilities=default_capabilities)
self.controller.guided(
GuidedChoiceV2(target=target, capability=GuidedCapability.LVM))
parts_after = gaps.parts_and_gaps(self.d1)[:-2] parts_after = gaps.parts_and_gaps(self.d1)[:-2]
self.assertEqual(parts_before, parts_after) self.assertEqual(parts_before, parts_after)
p_boot, p_data = gaps.parts_and_gaps(self.d1)[-2:] p_boot, p_data = gaps.parts_and_gaps(self.d1)[-2:]
@ -254,7 +274,10 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
async def test_blank_disk(self, bootloader, ptable): async def test_blank_disk(self, bootloader, ptable):
# blank disks should not report a UseGap case # blank disks should not report a UseGap case
self._setup(bootloader, ptable, fix_bios=False) self._setup(bootloader, ptable, fix_bios=False)
expected = [GuidedStorageTargetReformat(disk_id=self.disk.id)] expected = [
GuidedStorageTargetReformat(
disk_id=self.disk.id, capabilities=default_capabilities),
]
resp = await self.fsc.v2_guided_GET() resp = await self.fsc.v2_guided_GET()
self.assertEqual(expected, resp.possible) self.assertEqual(expected, resp.possible)
self.assertEqual(ProbeStatus.DONE, resp.status) self.assertEqual(ProbeStatus.DONE, resp.status)
@ -282,7 +305,9 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
resp = await self.fsc.v2_guided_GET() resp = await self.fsc.v2_guided_GET()
reformat = resp.possible.pop(0) reformat = resp.possible.pop(0)
self.assertEqual(GuidedStorageTargetReformat(disk_id=self.disk.id), self.assertEqual(
GuidedStorageTargetReformat(
disk_id=self.disk.id, capabilities=default_capabilities),
reformat) reformat)
use_gap = resp.possible.pop(0) use_gap = resp.possible.pop(0)
@ -303,7 +328,9 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
self.fs_probe[p._path()] = {'ESTIMATED_MIN_SIZE': 1 << 20} self.fs_probe[p._path()] = {'ESTIMATED_MIN_SIZE': 1 << 20}
resp = await self.fsc.v2_guided_GET() resp = await self.fsc.v2_guided_GET()
reformat = resp.possible.pop(0) reformat = resp.possible.pop(0)
self.assertEqual(GuidedStorageTargetReformat(disk_id=self.disk.id), self.assertEqual(
GuidedStorageTargetReformat(
disk_id=self.disk.id, capabilities=default_capabilities),
reformat) reformat)
resize = resp.possible.pop(0) resize = resp.possible.pop(0)
@ -323,7 +350,9 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
self.fsc.calculate_suggested_install_min.return_value = 10 << 30 self.fsc.calculate_suggested_install_min.return_value = 10 << 30
resp = await self.fsc.v2_guided_GET() resp = await self.fsc.v2_guided_GET()
reformat = resp.possible.pop(0) reformat = resp.possible.pop(0)
self.assertEqual(GuidedStorageTargetReformat(disk_id=self.disk.id), self.assertEqual(
GuidedStorageTargetReformat(
disk_id=self.disk.id, capabilities=default_capabilities),
reformat) reformat)
resize = resp.possible.pop(0) resize = resp.possible.pop(0)
@ -333,7 +362,8 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
new_size=200 << 30, new_size=200 << 30,
minimum=50 << 30, minimum=50 << 30,
recommended=200 << 30, recommended=200 << 30,
maximum=230 << 30) maximum=230 << 30,
capabilities=default_capabilities)
self.assertEqual(expected, resize) self.assertEqual(expected, resize)
self.assertEqual(0, len(resp.possible)) self.assertEqual(0, len(resp.possible))
@ -353,7 +383,8 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
resize = guided_get_resp.possible.pop(0) resize = guided_get_resp.possible.pop(0)
self.assertTrue(isinstance(resize, GuidedStorageTargetResize)) self.assertTrue(isinstance(resize, GuidedStorageTargetResize))
data = GuidedChoiceV2(target=reformat) data = GuidedChoiceV2(
target=reformat, capability=GuidedCapability.DIRECT)
expected_config = copy.copy(data) expected_config = copy.copy(data)
resp = await self.fsc.v2_guided_POST(data=data) resp = await self.fsc.v2_guided_POST(data=data)
self.assertEqual(expected_config, resp.configured) self.assertEqual(expected_config, resp.configured)
@ -379,7 +410,8 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
use_gap = guided_get_resp.possible.pop(0) use_gap = guided_get_resp.possible.pop(0)
self.assertTrue(isinstance(use_gap, GuidedStorageTargetUseGap)) self.assertTrue(isinstance(use_gap, GuidedStorageTargetUseGap))
self.assertEqual(g, use_gap.gap) self.assertEqual(g, use_gap.gap)
data = GuidedChoiceV2(target=use_gap) data = GuidedChoiceV2(
target=use_gap, capability=GuidedCapability.DIRECT)
expected_config = copy.copy(data) expected_config = copy.copy(data)
resp = await self.fsc.v2_guided_POST(data=data) resp = await self.fsc.v2_guided_POST(data=data)
self.assertEqual(expected_config, resp.configured) self.assertEqual(expected_config, resp.configured)
@ -416,7 +448,8 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
p_expected = copy.copy(orig_p) p_expected = copy.copy(orig_p)
p_expected.size = resize.new_size = 20 << 30 p_expected.size = resize.new_size = 20 << 30
p_expected.resize = True p_expected.resize = True
data = GuidedChoiceV2(target=resize) data = GuidedChoiceV2(
target=resize, capability=GuidedCapability.DIRECT)
expected_config = copy.copy(data) expected_config = copy.copy(data)
resp = await self.fsc.v2_guided_POST(data=data) resp = await self.fsc.v2_guided_POST(data=data)
self.assertEqual(expected_config, resp.configured) self.assertEqual(expected_config, resp.configured)
@ -442,7 +475,7 @@ class TestGuidedV2(IsolatedAsyncioTestCase):
reformat = guided_get_resp.possible.pop(0) reformat = guided_get_resp.possible.pop(0)
self.assertTrue(isinstance(reformat, GuidedStorageTargetReformat)) self.assertTrue(isinstance(reformat, GuidedStorageTargetReformat))
data = GuidedChoiceV2(target=reformat, use_lvm=True) data = GuidedChoiceV2(target=reformat, capability=GuidedCapability.LVM)
expected_config = copy.copy(data) expected_config = copy.copy(data)
resp = await self.fsc.v2_guided_POST(data=data) resp = await self.fsc.v2_guided_POST(data=data)

View File

@ -330,7 +330,12 @@ class TestFlow(TestAPI):
resp = await inst.get('/storage/v2/guided?wait=true') resp = await inst.get('/storage/v2/guided?wait=true')
[reformat] = resp['possible'] [reformat] = resp['possible']
await inst.post('/storage/v2/guided', {'target': reformat}) await inst.post(
'/storage/v2/guided',
{
'target': reformat,
'capability': reformat['capabilities'][0],
})
await inst.post('/storage/v2') await inst.post('/storage/v2')
await inst.get('/meta/status', cur='WAITING') await inst.get('/meta/status', cur='WAITING')
await inst.post('/meta/confirm', tty='/dev/tty1') await inst.post('/meta/confirm', tty='/dev/tty1')
@ -418,7 +423,11 @@ class TestFlow(TestAPI):
resp = await inst.get('/storage/v2/guided') resp = await inst.get('/storage/v2/guided')
[reformat] = match(resp['possible'], [reformat] = match(resp['possible'],
_type='GuidedStorageTargetReformat') _type='GuidedStorageTargetReformat')
await inst.post('/storage/v2/guided', {'target': reformat}) data = {
'target': reformat,
'capability': reformat['capabilities'][0],
}
await inst.post('/storage/v2/guided', data)
after_guided_resp = await inst.get('/storage/v2') after_guided_resp = await inst.get('/storage/v2')
post_resp = await inst.post('/storage/v2') post_resp = await inst.post('/storage/v2')
# posting to the endpoint shouldn't change the answer # posting to the endpoint shouldn't change the answer
@ -433,7 +442,12 @@ class TestGuided(TestAPI):
resp = await inst.get('/storage/v2/guided') resp = await inst.get('/storage/v2/guided')
[reformat] = match(resp['possible'], [reformat] = match(resp['possible'],
_type='GuidedStorageTargetReformat') _type='GuidedStorageTargetReformat')
resp = await inst.post('/storage/v2/guided', {'target': reformat}) resp = await inst.post(
'/storage/v2/guided',
{
'target': reformat,
'capability': reformat['capabilities'][0],
})
self.assertEqual(reformat, resp['configured']['target']) self.assertEqual(reformat, resp['configured']['target'])
resp = await inst.get('/storage/v2') resp = await inst.get('/storage/v2')
[p1, p2] = resp['disks'][0]['partitions'] [p1, p2] = resp['disks'][0]['partitions']
@ -475,7 +489,10 @@ class TestGuided(TestAPI):
[resize_ntfs, resize_ext4] = match( [resize_ntfs, resize_ext4] = match(
resp['possible'], _type='GuidedStorageTargetResize') resp['possible'], _type='GuidedStorageTargetResize')
resize_ntfs['new_size'] = 30 << 30 resize_ntfs['new_size'] = 30 << 30
data = {'target': resize_ntfs} data = {
'target': resize_ntfs,
'capability': resize_ntfs['capabilities'][0],
}
resp = await inst.post('/storage/v2/guided', data) resp = await inst.post('/storage/v2/guided', data)
self.assertEqual(resize_ntfs, resp['configured']['target']) self.assertEqual(resize_ntfs, resp['configured']['target'])
resp = await inst.get('/storage/v2') resp = await inst.get('/storage/v2')
@ -519,7 +536,10 @@ class TestGuided(TestAPI):
resp = await inst.get('/storage/v2/guided') resp = await inst.get('/storage/v2/guided')
[use_gap] = match(resp['possible'], [use_gap] = match(resp['possible'],
_type='GuidedStorageTargetUseGap') _type='GuidedStorageTargetUseGap')
data = {'target': use_gap} data = {
'target': use_gap,
'capability': use_gap['capabilities'][0],
}
resp = await inst.post('/storage/v2/guided', data) resp = await inst.post('/storage/v2/guided', data)
self.assertEqual(use_gap, resp['configured']['target']) self.assertEqual(use_gap, resp['configured']['target'])
resp = await inst.get('/storage/v2') resp = await inst.get('/storage/v2')
@ -555,7 +575,10 @@ class TestGuided(TestAPI):
[resize] = match( [resize] = match(
resp['possible'], _type='GuidedStorageTargetResize', resp['possible'], _type='GuidedStorageTargetResize',
partition_number=6) partition_number=6)
data = {'target': resize} data = {
'target': resize,
'capability': resize['capabilities'][0],
}
resp = await inst.post('/storage/v2/guided', data) resp = await inst.post('/storage/v2/guided', data)
self.assertEqual(resize, resp['configured']['target']) self.assertEqual(resize, resp['configured']['target'])
# should not throw a Gap Not Found exception # should not throw a Gap Not Found exception
@ -980,7 +1003,11 @@ class TestTodos(TestAPI): # server indicators of required client actions
resp = await inst.get('/storage/v2/guided') resp = await inst.get('/storage/v2/guided')
[reformat] = resp['possible'] [reformat] = resp['possible']
await inst.post('/storage/v2/guided', {'target': reformat}) data = {
'target': reformat,
'capability': reformat['capabilities'][0],
}
await inst.post('/storage/v2/guided', data)
resp = await inst.get('/storage/v2') resp = await inst.get('/storage/v2')
self.assertFalse(resp['need_root']) self.assertFalse(resp['need_root'])
self.assertFalse(resp['need_boot']) self.assertFalse(resp['need_boot'])
@ -1181,7 +1208,11 @@ class TestPartitionTableEditing(TestAPI):
resize = match(resp['possible'], resize = match(resp['possible'],
_type='GuidedStorageTargetResize')[0] _type='GuidedStorageTargetResize')[0]
resize['new_size'] = 30 << 30 resize['new_size'] = 30 << 30
await inst.post('/storage/v2/guided', {'target': resize}) data = {
'target': resize,
'capability': resize['capabilities'][0],
}
await inst.post('/storage/v2/guided', data)
orig_config = await inst.get('/storage/v2/orig_config') orig_config = await inst.get('/storage/v2/orig_config')
end_resp = await inst.get('/storage/v2') end_resp = await inst.get('/storage/v2')
self.assertEqual(start_resp, orig_config) self.assertEqual(start_resp, orig_config)