replace free_for_paritions with largest_gap_size
This commit is contained in:
parent
5429e97854
commit
83cfdbdfea
|
@ -88,3 +88,10 @@ def largest_gap(device):
|
||||||
largest = pg
|
largest = pg
|
||||||
largest_size = pg.size
|
largest_size = pg.size
|
||||||
return largest
|
return largest
|
||||||
|
|
||||||
|
|
||||||
|
def largest_gap_size(device):
|
||||||
|
largest = largest_gap(device)
|
||||||
|
if largest is not None:
|
||||||
|
return largest.size
|
||||||
|
return 0
|
||||||
|
|
|
@ -292,7 +292,7 @@ def _for_client_disk(disk, *, min_size=0):
|
||||||
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 disk._partitions],
|
||||||
free_for_partitions=disk.free_for_partitions,
|
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,
|
||||||
model=getattr(disk, 'model', None),
|
model=getattr(disk, 'model', None),
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from subiquity.common.filesystem import boot
|
from subiquity.common.filesystem import boot, gaps
|
||||||
from subiquity.common.types import Bootloader
|
from subiquity.common.types import Bootloader
|
||||||
from subiquity.models.filesystem import (
|
from subiquity.models.filesystem import (
|
||||||
align_up,
|
align_up,
|
||||||
|
@ -199,12 +199,12 @@ class FilesystemManipulator:
|
||||||
|
|
||||||
def partition_disk_handler(self, disk, partition, spec):
|
def partition_disk_handler(self, disk, partition, spec):
|
||||||
log.debug('partition_disk_handler: %s %s %s', disk, partition, spec)
|
log.debug('partition_disk_handler: %s %s %s', disk, partition, spec)
|
||||||
log.debug('disk.freespace: {}'.format(disk.free_for_partitions))
|
log.debug('disk.freespace: {}'.format(gaps.largest_gap_size(disk)))
|
||||||
|
|
||||||
if partition is not None:
|
if partition is not None:
|
||||||
if 'size' in spec:
|
if 'size' in spec:
|
||||||
partition.size = align_up(spec['size'])
|
partition.size = align_up(spec['size'])
|
||||||
if disk.free_for_partitions < 0:
|
if gaps.largest_gap_size(disk) < 0:
|
||||||
raise Exception("partition size too large")
|
raise Exception("partition size too large")
|
||||||
self.delete_filesystem(partition.fs())
|
self.delete_filesystem(partition.fs())
|
||||||
self.create_filesystem(partition, spec)
|
self.create_filesystem(partition, spec)
|
||||||
|
@ -225,11 +225,11 @@ class FilesystemManipulator:
|
||||||
|
|
||||||
# adjust downward the partition size (if necessary) to accommodate
|
# adjust downward the partition size (if necessary) to accommodate
|
||||||
# bios/grub partition
|
# bios/grub partition
|
||||||
if spec['size'] > disk.free_for_partitions:
|
if spec['size'] > gaps.largest_gap_size(disk):
|
||||||
log.debug(
|
log.debug(
|
||||||
"Adjusting request down: %s - %s = %s",
|
"Adjusting request down: %s - %s = %s",
|
||||||
spec['size'], part.size, disk.free_for_partitions)
|
spec['size'], part.size, gaps.largest_gap_size(disk))
|
||||||
spec['size'] = disk.free_for_partitions
|
spec['size'] = gaps.largest_gap_size(disk)
|
||||||
|
|
||||||
self.create_partition(disk, spec)
|
self.create_partition(disk, spec)
|
||||||
|
|
||||||
|
@ -237,14 +237,14 @@ class FilesystemManipulator:
|
||||||
|
|
||||||
def logical_volume_handler(self, vg, lv, spec):
|
def logical_volume_handler(self, vg, lv, spec):
|
||||||
log.debug('logical_volume_handler: %s %s %s', vg, lv, spec)
|
log.debug('logical_volume_handler: %s %s %s', vg, lv, spec)
|
||||||
log.debug('vg.freespace: {}'.format(vg.free_for_partitions))
|
log.debug('vg.freespace: {}'.format(gaps.largest_gap_size(vg)))
|
||||||
|
|
||||||
if lv is not None:
|
if lv is not None:
|
||||||
if 'name' in spec:
|
if 'name' in spec:
|
||||||
lv.name = spec['name']
|
lv.name = spec['name']
|
||||||
if 'size' in spec:
|
if 'size' in spec:
|
||||||
lv.size = align_up(spec['size'])
|
lv.size = align_up(spec['size'])
|
||||||
if vg.free_for_partitions < 0:
|
if gaps.largest_gap_size(vg) < 0:
|
||||||
raise Exception("lv size too large")
|
raise Exception("lv size too large")
|
||||||
self.delete_filesystem(lv.fs())
|
self.delete_filesystem(lv.fs())
|
||||||
self.create_filesystem(lv, spec)
|
self.create_filesystem(lv, spec)
|
||||||
|
@ -322,7 +322,7 @@ class FilesystemManipulator:
|
||||||
self.model.add_filesystem(
|
self.model.add_filesystem(
|
||||||
p, p.original_fstype(), preserve=True)
|
p, p.original_fstype(), preserve=True)
|
||||||
else:
|
else:
|
||||||
full = boot_disk.free_for_partitions == 0
|
full = gaps.largest_gap_size(boot_disk) == 0
|
||||||
tot_size = 0
|
tot_size = 0
|
||||||
for p in partitions:
|
for p in partitions:
|
||||||
tot_size += p.size
|
tot_size += p.size
|
||||||
|
@ -371,9 +371,9 @@ class FilesystemManipulator:
|
||||||
elif bootloader == Bootloader.BIOS:
|
elif bootloader == Bootloader.BIOS:
|
||||||
part_size = BIOS_GRUB_SIZE_BYTES
|
part_size = BIOS_GRUB_SIZE_BYTES
|
||||||
log.debug("bootloader %s", bootloader)
|
log.debug("bootloader %s", bootloader)
|
||||||
if part_size > new_boot_disk.free_for_partitions:
|
if part_size > gaps.largest_gap_size(new_boot_disk):
|
||||||
largest_part = max(
|
largest_part = max(
|
||||||
new_boot_disk.partitions(), key=lambda p: p.size)
|
new_boot_disk.partitions(), key=lambda p: p.size)
|
||||||
largest_part.size -= (
|
largest_part.size -= (
|
||||||
part_size - new_boot_disk.free_for_partitions)
|
part_size - gaps.largest_gap_size(new_boot_disk))
|
||||||
self._create_boot_partition(new_boot_disk)
|
self._create_boot_partition(new_boot_disk)
|
||||||
|
|
|
@ -142,7 +142,8 @@ class TestActions(unittest.TestCase):
|
||||||
self.assertActionPossible(dos_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(dos_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
# Even if they have existing partitions
|
# Even if they have existing partitions
|
||||||
make_partition(
|
make_partition(
|
||||||
model, dos_disk, size=dos_disk.free_for_partitions, preserve=True)
|
model, dos_disk, size=gaps.largest_gap_size(dos_disk),
|
||||||
|
preserve=True)
|
||||||
self.assertActionPossible(dos_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(dos_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
# (we never create dos partition tables so no need to test
|
# (we never create dos partition tables so no need to test
|
||||||
# preserve=False case).
|
# preserve=False case).
|
||||||
|
@ -151,7 +152,7 @@ class TestActions(unittest.TestCase):
|
||||||
gpt_disk = make_disk(model, ptable='gpt', preserve=False)
|
gpt_disk = make_disk(model, ptable='gpt', preserve=False)
|
||||||
self.assertActionPossible(gpt_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(gpt_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
# Even if they are filled with partitions (we resize partitions to fit)
|
# Even if they are filled with partitions (we resize partitions to fit)
|
||||||
make_partition(model, gpt_disk, size=dos_disk.free_for_partitions)
|
make_partition(model, gpt_disk, size=gaps.largest_gap_size(dos_disk))
|
||||||
self.assertActionPossible(gpt_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(gpt_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
|
|
||||||
# GPT disks with existing partition tables but no partitions can be the
|
# GPT disks with existing partition tables but no partitions can be the
|
||||||
|
@ -187,7 +188,8 @@ class TestActions(unittest.TestCase):
|
||||||
new_disk = make_disk(model, preserve=False)
|
new_disk = make_disk(model, preserve=False)
|
||||||
self.assertActionPossible(new_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(new_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
# Even if they are filled with partitions (we resize partitions to fit)
|
# Even if they are filled with partitions (we resize partitions to fit)
|
||||||
make_partition(model, new_disk, size=new_disk.free_for_partitions)
|
make_partition(
|
||||||
|
model, new_disk, size=gaps.largest_gap_size(new_disk))
|
||||||
self.assertActionPossible(new_disk, DeviceAction.TOGGLE_BOOT)
|
self.assertActionPossible(new_disk, DeviceAction.TOGGLE_BOOT)
|
||||||
|
|
||||||
# A disk with an existing but empty partitions can also be the
|
# A disk with an existing but empty partitions can also be the
|
||||||
|
@ -363,7 +365,7 @@ class TestActions(unittest.TestCase):
|
||||||
def test_vg_action_EDIT(self):
|
def test_vg_action_EDIT(self):
|
||||||
model, vg = make_model_and_vg()
|
model, vg = make_model_and_vg()
|
||||||
self.assertActionPossible(vg, DeviceAction.EDIT)
|
self.assertActionPossible(vg, DeviceAction.EDIT)
|
||||||
model.add_logical_volume(vg, 'lv1', size=vg.free_for_partitions//2)
|
model.add_logical_volume(vg, 'lv1', size=gaps.largest_gap_size(vg))
|
||||||
self.assertActionNotPossible(vg, DeviceAction.EDIT)
|
self.assertActionNotPossible(vg, DeviceAction.EDIT)
|
||||||
|
|
||||||
vg2 = make_vg(model)
|
vg2 = make_vg(model)
|
||||||
|
@ -391,7 +393,7 @@ class TestActions(unittest.TestCase):
|
||||||
self.assertActionPossible(vg, DeviceAction.DELETE)
|
self.assertActionPossible(vg, DeviceAction.DELETE)
|
||||||
self.assertActionPossible(vg, DeviceAction.DELETE)
|
self.assertActionPossible(vg, DeviceAction.DELETE)
|
||||||
lv = model.add_logical_volume(
|
lv = model.add_logical_volume(
|
||||||
vg, 'lv0', size=vg.free_for_partitions//2)
|
vg, 'lv0', size=gaps.largest_gap_size(vg)//2)
|
||||||
self.assertActionPossible(vg, DeviceAction.DELETE)
|
self.assertActionPossible(vg, DeviceAction.DELETE)
|
||||||
fs = model.add_filesystem(lv, 'ext4')
|
fs = model.add_filesystem(lv, 'ext4')
|
||||||
self.assertActionPossible(vg, DeviceAction.DELETE)
|
self.assertActionPossible(vg, DeviceAction.DELETE)
|
||||||
|
|
|
@ -18,6 +18,7 @@ import unittest
|
||||||
from subiquity.common.filesystem.actions import (
|
from subiquity.common.filesystem.actions import (
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
)
|
)
|
||||||
|
from subiquity.common.filesystem import gaps
|
||||||
from subiquity.common.filesystem.manipulator import (
|
from subiquity.common.filesystem.manipulator import (
|
||||||
FilesystemManipulator,
|
FilesystemManipulator,
|
||||||
)
|
)
|
||||||
|
@ -130,7 +131,7 @@ class TestFilesystemManipulator(unittest.TestCase):
|
||||||
disk1 = make_disk(manipulator.model, preserve=False)
|
disk1 = make_disk(manipulator.model, preserve=False)
|
||||||
disk2 = make_disk(manipulator.model, preserve=False)
|
disk2 = make_disk(manipulator.model, preserve=False)
|
||||||
disk2p1 = manipulator.model.add_partition(
|
disk2p1 = manipulator.model.add_partition(
|
||||||
disk2, size=disk2.free_for_partitions)
|
disk2, size=gaps.largest_gap_size(disk2))
|
||||||
|
|
||||||
manipulator.add_boot_disk(disk1)
|
manipulator.add_boot_disk(disk1)
|
||||||
self.assertIsBootDisk(manipulator, disk1)
|
self.assertIsBootDisk(manipulator, disk1)
|
||||||
|
@ -171,7 +172,7 @@ class TestFilesystemManipulator(unittest.TestCase):
|
||||||
disk1 = make_disk(manipulator.model, preserve=False)
|
disk1 = make_disk(manipulator.model, preserve=False)
|
||||||
disk2 = make_disk(manipulator.model, preserve=False)
|
disk2 = make_disk(manipulator.model, preserve=False)
|
||||||
disk2p1 = manipulator.model.add_partition(
|
disk2p1 = manipulator.model.add_partition(
|
||||||
disk2, size=disk2.free_for_partitions)
|
disk2, size=gaps.largest_gap_size(disk2))
|
||||||
|
|
||||||
manipulator.add_boot_disk(disk1)
|
manipulator.add_boot_disk(disk1)
|
||||||
self.assertIsBootDisk(manipulator, disk1)
|
self.assertIsBootDisk(manipulator, disk1)
|
||||||
|
@ -218,7 +219,7 @@ class TestFilesystemManipulator(unittest.TestCase):
|
||||||
disk1, size=512 << 20, flag="boot")
|
disk1, size=512 << 20, flag="boot")
|
||||||
disk1p1.preserve = True
|
disk1p1.preserve = True
|
||||||
disk1p2 = manipulator.model.add_partition(
|
disk1p2 = manipulator.model.add_partition(
|
||||||
disk1, size=disk1.free_for_partitions)
|
disk1, size=gaps.largest_gap_size(disk1))
|
||||||
disk1p2.preserve = True
|
disk1p2.preserve = True
|
||||||
manipulator.partition_disk_handler(
|
manipulator.partition_disk_handler(
|
||||||
disk1, disk1p2, {'fstype': 'ext4', 'mount': '/'})
|
disk1, disk1p2, {'fstype': 'ext4', 'mount': '/'})
|
||||||
|
|
|
@ -524,10 +524,6 @@ class _Device(_Formattable, ABC):
|
||||||
def available_for_partitions(self):
|
def available_for_partitions(self):
|
||||||
return align_down(self.size, 1 << 20) - GPT_OVERHEAD
|
return align_down(self.size, 1 << 20) - GPT_OVERHEAD
|
||||||
|
|
||||||
@property
|
|
||||||
def free_for_partitions(self):
|
|
||||||
return self.available_for_partitions - self.used
|
|
||||||
|
|
||||||
def available(self):
|
def available(self):
|
||||||
# A _Device is available if:
|
# A _Device is available if:
|
||||||
# 1) it is not part of a device like a RAID or LVM or zpool or ...
|
# 1) it is not part of a device like a RAID or LVM or zpool or ...
|
||||||
|
@ -540,9 +536,11 @@ class _Device(_Formattable, ABC):
|
||||||
return False
|
return False
|
||||||
if self._fs is not None:
|
if self._fs is not None:
|
||||||
return self._fs._available()
|
return self._fs._available()
|
||||||
if self.free_for_partitions > 0:
|
from subiquity.common.filesystem.gaps import (
|
||||||
if not self._has_preexisting_partition():
|
largest_gap_size,
|
||||||
return True
|
)
|
||||||
|
if largest_gap_size(self) > 0:
|
||||||
|
return True
|
||||||
return any(p.available() for p in self._partitions)
|
return any(p.available() for p in self._partitions)
|
||||||
|
|
||||||
def has_unavailable_partition(self):
|
def has_unavailable_partition(self):
|
||||||
|
@ -803,11 +801,6 @@ class LVM_VolGroup(_Device):
|
||||||
def available_for_partitions(self):
|
def available_for_partitions(self):
|
||||||
return self.size
|
return self.size
|
||||||
|
|
||||||
@property
|
|
||||||
def free_for_partitions(self):
|
|
||||||
return align_down(
|
|
||||||
self.available_for_partitions - self.used, LVM_CHUNK_SIZE)
|
|
||||||
|
|
||||||
ok_for_raid = False
|
ok_for_raid = False
|
||||||
ok_for_lvm_vg = False
|
ok_for_lvm_vg = False
|
||||||
|
|
||||||
|
@ -1083,10 +1076,10 @@ class FilesystemModel(object):
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"{} has negative size but is not final partition "
|
"{} has negative size but is not final partition "
|
||||||
"of {}".format(p, parent))
|
"of {}".format(p, parent))
|
||||||
p.size = 0
|
from subiquity.common.filesystem.gaps import (
|
||||||
p.size = parent.free_for_partitions
|
largest_gap_size,
|
||||||
if p.type == 'lvm_partition':
|
)
|
||||||
p.size = align_down(p.size, LVM_CHUNK_SIZE)
|
p.size = largest_gap_size(parent)
|
||||||
elif isinstance(p.size, str):
|
elif isinstance(p.size, str):
|
||||||
if p.size.endswith("%"):
|
if p.size.endswith("%"):
|
||||||
percentage = int(p.size[:-1])
|
percentage = int(p.size[:-1])
|
||||||
|
@ -1346,8 +1339,6 @@ class FilesystemModel(object):
|
||||||
def add_partition(self, device, size, flag="", wipe=None,
|
def add_partition(self, device, size, flag="", wipe=None,
|
||||||
grub_device=None):
|
grub_device=None):
|
||||||
from subiquity.common.filesystem import boot
|
from subiquity.common.filesystem import boot
|
||||||
if size > device.free_for_partitions:
|
|
||||||
raise Exception("%s > %s", size, device.free_for_partitions)
|
|
||||||
real_size = align_up(size)
|
real_size = align_up(size)
|
||||||
log.debug("add_partition: rounded size from %s to %s", size, real_size)
|
log.debug("add_partition: rounded size from %s to %s", size, real_size)
|
||||||
if device._fs is not None:
|
if device._fs is not None:
|
||||||
|
|
|
@ -28,6 +28,7 @@ from subiquity.models.filesystem import (
|
||||||
align_down,
|
align_down,
|
||||||
LVM_CHUNK_SIZE,
|
LVM_CHUNK_SIZE,
|
||||||
)
|
)
|
||||||
|
from subiquity.common.filesystem import gaps
|
||||||
|
|
||||||
|
|
||||||
class TestHumanizeSize(unittest.TestCase):
|
class TestHumanizeSize(unittest.TestCase):
|
||||||
|
@ -164,7 +165,7 @@ def make_partition(model, device=None, *, preserve=False, size=None, **kw):
|
||||||
if device is None:
|
if device is None:
|
||||||
device = make_disk(model)
|
device = make_disk(model)
|
||||||
if size is None:
|
if size is None:
|
||||||
size = device.free_for_partitions//2
|
size = gaps.largest_gap_size(device)//2
|
||||||
partition = Partition(
|
partition = Partition(
|
||||||
m=model, device=device, size=size, preserve=preserve, **kw)
|
m=model, device=device, size=size, preserve=preserve, **kw)
|
||||||
if preserve:
|
if preserve:
|
||||||
|
@ -203,7 +204,7 @@ def make_model_and_vg(bootloader=None):
|
||||||
def make_lv(model):
|
def make_lv(model):
|
||||||
vg = make_vg(model)
|
vg = make_vg(model)
|
||||||
name = 'lv%s' % len(model._actions)
|
name = 'lv%s' % len(model._actions)
|
||||||
return model.add_logical_volume(vg, name, vg.free_for_partitions//2)
|
return model.add_logical_volume(vg, name, gaps.largest_gap_size(vg))
|
||||||
|
|
||||||
|
|
||||||
def make_model_and_lv(bootloader=None):
|
def make_model_and_lv(bootloader=None):
|
||||||
|
|
|
@ -40,7 +40,7 @@ from subiquity.common.errorreport import ErrorReportKind
|
||||||
from subiquity.common.filesystem.actions import (
|
from subiquity.common.filesystem.actions import (
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
)
|
)
|
||||||
from subiquity.common.filesystem import boot, labels
|
from subiquity.common.filesystem import boot, gaps, labels
|
||||||
from subiquity.common.filesystem.manipulator import FilesystemManipulator
|
from subiquity.common.filesystem.manipulator import FilesystemManipulator
|
||||||
from subiquity.common.types import (
|
from subiquity.common.types import (
|
||||||
Bootloader,
|
Bootloader,
|
||||||
|
@ -126,7 +126,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
||||||
def guided_direct(self, disk):
|
def guided_direct(self, disk):
|
||||||
self.reformat(disk)
|
self.reformat(disk)
|
||||||
result = {
|
result = {
|
||||||
"size": disk.free_for_partitions,
|
"size": gaps.largest_gap_size(disk),
|
||||||
"fstype": "ext4",
|
"fstype": "ext4",
|
||||||
"mount": "/",
|
"mount": "/",
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
||||||
))
|
))
|
||||||
part = self.create_partition(
|
part = self.create_partition(
|
||||||
device=disk, spec=dict(
|
device=disk, spec=dict(
|
||||||
size=disk.free_for_partitions,
|
size=gaps.largest_gap_size(disk),
|
||||||
fstype=None,
|
fstype=None,
|
||||||
))
|
))
|
||||||
vg_name = 'ubuntu-vg'
|
vg_name = 'ubuntu-vg'
|
||||||
|
@ -348,7 +348,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
||||||
disk = self.model._one(id=data.disk_id)
|
disk = self.model._one(id=data.disk_id)
|
||||||
size = data.partition.size
|
size = data.partition.size
|
||||||
if size is None or size < 0:
|
if size is None or size < 0:
|
||||||
size = disk.free_for_partitions
|
size = gaps.largest_gap_size(disk)
|
||||||
spec = {
|
spec = {
|
||||||
'size': size,
|
'size': size,
|
||||||
'fstype': data.partition.format,
|
'fstype': data.partition.format,
|
||||||
|
|
|
@ -37,7 +37,7 @@ from subiquitycore.ui.container import Pile
|
||||||
from subiquitycore.ui.stretchy import Stretchy
|
from subiquitycore.ui.stretchy import Stretchy
|
||||||
from subiquitycore.ui.utils import rewrap
|
from subiquitycore.ui.utils import rewrap
|
||||||
|
|
||||||
from subiquity.common.filesystem import boot, labels
|
from subiquity.common.filesystem import boot, gaps, labels
|
||||||
from subiquity.models.filesystem import (
|
from subiquity.models.filesystem import (
|
||||||
align_up,
|
align_up,
|
||||||
Disk,
|
Disk,
|
||||||
|
@ -375,7 +375,7 @@ class PartitionStretchy(Stretchy):
|
||||||
self.model = parent.model
|
self.model = parent.model
|
||||||
self.controller = parent.controller
|
self.controller = parent.controller
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
max_size = disk.free_for_partitions
|
max_size = gaps.largest_gap_size(disk)
|
||||||
|
|
||||||
initial = {}
|
initial = {}
|
||||||
label = _("Create")
|
label = _("Create")
|
||||||
|
|
Loading…
Reference in New Issue