storage/v2: start showing Gaps on the v2 api

This commit is contained in:
Dan Bungert 2022-01-25 13:54:14 -07:00
parent 16d0325cf8
commit e5770f029a
3 changed files with 49 additions and 8 deletions

View File

@ -291,7 +291,7 @@ def _for_client_disk(disk, *, min_size=0):
ptable=disk.ptable, ptable=disk.ptable,
preserve=disk.preserve, preserve=disk.preserve,
usage_labels=usage_labels(disk), usage_labels=usage_labels(disk),
partitions=[for_client(p) for p in disk._partitions], partitions=[for_client(p) for p in gaps.parts_and_gaps(disk)],
free_for_partitions=gaps.largest_gap_size(disk), free_for_partitions=gaps.largest_gap_size(disk),
boot_device=boot.is_boot_device(disk), boot_device=boot.is_boot_device(disk),
ok_for_guided=disk.size >= min_size, ok_for_guided=disk.size >= min_size,
@ -312,3 +312,8 @@ def _for_client_partition(partition, *, min_size=0):
os=partition.os, os=partition.os,
mount=partition.mount, mount=partition.mount,
format=partition.format) format=partition.format)
@for_client.register(gaps.Gap)
def _for_client_gap(gap, *, min_size=0):
return types.Gap(offset=0, size=gap.size)

View File

@ -268,6 +268,12 @@ class Partition:
os: Optional[OsProber] = None os: Optional[OsProber] = None
@attr.s(auto_attribs=True)
class Gap:
offset: int
size: int
@attr.s(auto_attribs=True) @attr.s(auto_attribs=True)
class Disk: class Disk:
id: str id: str
@ -275,7 +281,7 @@ class Disk:
type: str type: str
size: int size: int
usage_labels: List[str] usage_labels: List[str]
partitions: List[Partition] partitions: List[Union[Partition, Gap]]
ok_for_guided: bool ok_for_guided: bool
ptable: Optional[str] ptable: Optional[str]
preserve: bool preserve: bool

View File

@ -1,5 +1,3 @@
#!/usr/bin/env python3
import aiohttp import aiohttp
from aiohttp.client_exceptions import ClientResponseError from aiohttp.client_exceptions import ClientResponseError
import async_timeout import async_timeout
@ -19,7 +17,7 @@ default_timeout = 10
def find(items, key, value): def find(items, key, value):
for item in items: for item in items:
if item[key] == value: if key in item and item[key] == value:
yield item yield item
@ -53,7 +51,7 @@ class Client:
def dumps(self, data): def dumps(self, data):
# if the data we're dumping is literally False, # if the data we're dumping is literally False,
# we want that to be 'false' # we want that to be 'false'
if data or type(data) is bool: if data or isinstance(data, bool):
return json.dumps(data, separators=(',', ':')) return json.dumps(data, separators=(',', ':'))
elif data is not None: elif data is not None:
return '""' return '""'
@ -235,7 +233,8 @@ class TestFlow(TestAPI):
resp = await inst.post('/storage/v2/reformat_disk', resp = await inst.post('/storage/v2/reformat_disk',
disk_id=disk_id) disk_id=disk_id)
sda = first(resp['disks'], 'id', disk_id) sda = first(resp['disks'], 'id', disk_id)
self.assertEqual(0, len(sda['partitions'])) self.assertEqual(1, len(sda['partitions']))
self.assertEqual('Gap', sda['partitions'][0]['$type'])
data = { data = {
'disk_id': disk_id, 'disk_id': disk_id,
@ -265,7 +264,10 @@ class TestFlow(TestAPI):
resp['disks'][0]['partitions'][1]['format']) resp['disks'][0]['partitions'][1]['format'])
resp = await inst.post('/storage/v2/delete_partition', data) resp = await inst.post('/storage/v2/delete_partition', data)
self.assertEqual(1, len(resp['disks'][0]['partitions'])) sda = first(resp['disks'], 'id', disk_id)
self.assertEqual(2, len(sda['partitions']))
self.assertEqual('Partition', sda['partitions'][0]['$type'])
self.assertEqual('Gap', sda['partitions'][1]['$type'])
resp = await inst.post('/storage/v2/reset') resp = await inst.post('/storage/v2/reset')
self.assertEqual(orig_resp, resp) self.assertEqual(orig_resp, resp)
@ -753,6 +755,34 @@ class TestPartitionTableEditing(TestAPI):
data['partition']['mount'] = '/usr' data['partition']['mount'] = '/usr'
await inst.post('/storage/v2/add_partition', data) await inst.post('/storage/v2/add_partition', data)
class TestGap(TestAPI):
async def test_blank_disk_is_one_big_gap(self):
async with start_server('examples/simple.json') as inst:
resp = await inst.get('/storage/v2')
sda = first(resp['disks'], 'id', 'disk-sda')
gap = sda['partitions'][0]
expected = (10 << 30) - (2 << 20)
self.assertEqual(expected, gap['size'])
async def test_gap_at_end(self):
async with start_server('examples/simple.json') as inst:
data = {
'disk_id': 'disk-sda',
'partition': {
'format': 'ext4',
'mount': '/',
'size': 4 << 30,
}
}
resp = await inst.post('/storage/v2/add_partition', data)
sda = first(resp['disks'], 'id', 'disk-sda')
boot = first(sda['partitions'], 'number', 1)
gap = sda['partitions'][2]
expected = (10 << 30) - boot['size'] - (4 << 30) - (2 << 20)
self.assertEqual(expected, gap['size'])
class TestRegression(TestAPI): class TestRegression(TestAPI):
@timeout() @timeout()
async def test_edit_not_trigger_boot_device(self): async def test_edit_not_trigger_boot_device(self):