Merge pull request #1302 from dbungert/report-size-mins
filesystem: report estimated partition size minimums
This commit is contained in:
commit
3e0c91e34b
File diff suppressed because it is too large
Load Diff
|
@ -187,7 +187,7 @@ parts:
|
|||
- libnl-route-3-dev
|
||||
source: https://github.com/canonical/probert.git
|
||||
source-type: git
|
||||
source-commit: 0e52863cb0a1637c6268a74f224f5cc2653beb9d
|
||||
source-commit: 31778895be3002422e9e8758d42940f290dc70af
|
||||
requirements: [requirements.txt]
|
||||
stage:
|
||||
- "*"
|
||||
|
|
|
@ -319,6 +319,7 @@ def _for_client_partition(partition, *, min_size=0):
|
|||
offset=partition.offset,
|
||||
resize=partition.resize,
|
||||
path=partition._path(),
|
||||
estimated_min_size=partition.estimated_min_size,
|
||||
mount=partition.mount,
|
||||
format=partition.format)
|
||||
|
||||
|
|
|
@ -268,6 +268,7 @@ class Partition:
|
|||
boot: Optional[bool] = None
|
||||
os: Optional[OsProber] = None
|
||||
offset: Optional[int] = None
|
||||
estimated_min_size: Optional[int] = -1
|
||||
resize: Optional[bool] = None
|
||||
path: Optional[str] = None
|
||||
|
||||
|
|
|
@ -702,6 +702,18 @@ class Partition(_Formattable):
|
|||
from subiquity.common.filesystem import boot
|
||||
return boot.is_bootloader_partition(self)
|
||||
|
||||
@property
|
||||
def estimated_min_size(self):
|
||||
fs_data = self._m._probe_data.get('filesystem', {}).get(self._path())
|
||||
if fs_data is None:
|
||||
return -1
|
||||
val = fs_data.get('ESTIMATED_MIN_SIZE', -1)
|
||||
if val == 0:
|
||||
return self.device.alignment_data().part_align
|
||||
if val == -1:
|
||||
return -1
|
||||
return align_up(val, self.device.alignment_data().part_align)
|
||||
|
||||
@property
|
||||
def ok_for_raid(self):
|
||||
if self.boot:
|
||||
|
|
|
@ -414,7 +414,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
fname = 'probe-data-restricted.json'
|
||||
key = "ProbeDataRestricted"
|
||||
else:
|
||||
probe_types = {'defaults'}
|
||||
probe_types = {'defaults', 'filesystem_sizing'}
|
||||
if self.app.opts.use_os_prober:
|
||||
probe_types |= {'os'}
|
||||
fname = 'probe-data.json'
|
||||
|
|
|
@ -40,15 +40,18 @@ class TestSubiquityControllerFilesystem(TestCase):
|
|||
run_coro(self.fsc._probe_once(context=None, restricted=True))
|
||||
self.app.prober.get_storage.assert_called_with({'blockdev'})
|
||||
|
||||
def test_probe_defaults(self):
|
||||
def test_probe_os_prober_false(self):
|
||||
self.app.opts.use_os_prober = False
|
||||
run_coro(self.fsc._probe_once(context=None, restricted=False))
|
||||
self.app.prober.get_storage.assert_called_with({'defaults'})
|
||||
actual = self.app.prober.get_storage.call_args.args[0]
|
||||
self.assertTrue({'defaults'} <= actual)
|
||||
self.assertNotIn('os', actual)
|
||||
|
||||
def test_probe_defaults_and_os(self):
|
||||
def test_probe_os_prober_true(self):
|
||||
self.app.opts.use_os_prober = True
|
||||
run_coro(self.fsc._probe_once(context=None, restricted=False))
|
||||
self.app.prober.get_storage.assert_called_with({'defaults', 'os'})
|
||||
actual = self.app.prober.get_storage.call_args.args[0]
|
||||
self.assertTrue({'defaults', 'os'} <= actual)
|
||||
|
||||
|
||||
class TestGuided(TestCase):
|
||||
|
|
|
@ -135,6 +135,27 @@ class Server(Client):
|
|||
|
||||
|
||||
class TestAPI(unittest.IsolatedAsyncioTestCase, SubiTestCase):
|
||||
class _MachineConfig(os.PathLike):
|
||||
def __init__(self, outer, path):
|
||||
self.outer = outer
|
||||
self.orig_path = path
|
||||
self.path = None
|
||||
|
||||
def __fspath__(self):
|
||||
return self.path or self.orig_path
|
||||
|
||||
@contextlib.contextmanager
|
||||
def edit(self):
|
||||
with open(self.orig_path, 'r') as fp:
|
||||
data = json.load(fp)
|
||||
yield data
|
||||
self.path = self.outer.tmp_path('machine-config.json')
|
||||
with open(self.path, 'w') as fp:
|
||||
json.dump(data, fp)
|
||||
|
||||
def machineConfig(self, path):
|
||||
return self._MachineConfig(self, path)
|
||||
|
||||
def assertDictSubset(self, expected, actual):
|
||||
"""All keys in dictionary expected, and matching values, must match
|
||||
keys and values in actual. Actual may contain additional keys and
|
||||
|
@ -853,23 +874,14 @@ class TestPartitionTableEditing(TestAPI):
|
|||
|
||||
@timeout()
|
||||
async def test_resize(self):
|
||||
# load config, edit size, use that for server
|
||||
with open('examples/ubuntu-and-free-space.json', 'r') as fp:
|
||||
data = json.load(fp)
|
||||
|
||||
cfg = self.machineConfig('examples/ubuntu-and-free-space.json')
|
||||
with cfg.edit() as data:
|
||||
blockdev = data['storage']['blockdev']
|
||||
sizes = {k: int(v['attrs']['size']) for k, v in blockdev.items()}
|
||||
# expand sda3 to use the rest of the disk
|
||||
def get_size(key):
|
||||
return int(data['storage']['blockdev'][key]['attrs']['size'])
|
||||
|
||||
sda_size = get_size('/dev/sda')
|
||||
sda1_size = get_size('/dev/sda1')
|
||||
sda2_size = get_size('/dev/sda2')
|
||||
sda3_size = sda_size - sda1_size - sda2_size - (2 << 20)
|
||||
data['storage']['blockdev']['/dev/sda3']['attrs']['size'] = \
|
||||
str(sda3_size)
|
||||
cfg = self.tmp_path('machine-config.json')
|
||||
with open(cfg, 'w') as fp:
|
||||
json.dump(data, fp)
|
||||
sda3_size = (sizes['/dev/sda'] - sizes['/dev/sda1']
|
||||
- sizes['/dev/sda2'] - (2 << 20))
|
||||
blockdev['/dev/sda3']['attrs']['size'] = str(sda3_size)
|
||||
|
||||
extra = ['--storage-version', '2']
|
||||
async with start_server(cfg, extra_args=extra) as inst:
|
||||
|
@ -922,6 +934,25 @@ class TestPartitionTableEditing(TestAPI):
|
|||
self.assertTrue(sda3['resize'])
|
||||
self.assertTrue(sda3_format['preserve'])
|
||||
|
||||
@timeout()
|
||||
async def test_est_min_size(self):
|
||||
cfg = self.machineConfig('examples/win10-along-ubuntu.json')
|
||||
with cfg.edit() as data:
|
||||
fs = data['storage']['filesystem']
|
||||
fs['/dev/sda1']['ESTIMATED_MIN_SIZE'] = 0
|
||||
# data file has no sda2 in filesystem
|
||||
fs['/dev/sda3']['ESTIMATED_MIN_SIZE'] = -1
|
||||
fs['/dev/sda4']['ESTIMATED_MIN_SIZE'] = (1 << 20) + 1
|
||||
|
||||
extra = ['--storage-version', '2']
|
||||
async with start_server(cfg, extra_args=extra) as inst:
|
||||
resp = await inst.get('/storage/v2')
|
||||
[sda] = resp['disks']
|
||||
[p1, _, p3, p4, _] = sda['partitions']
|
||||
self.assertEqual(1 << 20, p1['estimated_min_size'])
|
||||
self.assertEqual(-1, p3['estimated_min_size'])
|
||||
self.assertEqual(2 << 20, p4['estimated_min_size'])
|
||||
|
||||
|
||||
class TestGap(TestAPI):
|
||||
async def test_blank_disk_is_one_big_gap(self):
|
||||
|
|
Loading…
Reference in New Issue