convert AddPartitionView and add_disk_partition_handler to new world order

This commit is contained in:
Michael Hudson-Doyle 2017-03-10 12:55:59 +13:00
parent 2a250effef
commit f9ebcb3e25
5 changed files with 84 additions and 76 deletions

View File

@ -125,62 +125,38 @@ class FilesystemController(BaseController):
self.ui.set_body(adp_view)
def add_disk_partition_handler(self, disk, spec):
current_disk = self.model.get_disk(disk)
log.debug('spec: {}'.format(spec))
log.debug('disk.freespace: {}'.format(current_disk.freespace))
try:
''' create a gpt boot partition if one doesn't exist, only
one one disk'''
log.debug('disk.freespace: {}'.format(disk.free))
system_bootable = self.model.bootable()
log.debug('model has bootable device? {}'.format(system_bootable))
if system_bootable is False and \
current_disk.parttype == 'gpt' and \
len(current_disk.disk.partitions) == 0:
if not system_bootable and len(disk._partitions) == 0:
if self.is_uefi():
log.debug('Adding EFI partition first')
size_added = \
current_disk.add_partition(partnum=1,
size=UEFI_GRUB_SIZE_BYTES,
flag='bios_grub',
fstype='fat32',
mountpoint='/boot/efi')
part = self.model.add_partition(disk=disk, partnum=1, size=UEFI_GRUB_SIZE_BYTES, flag='bios_grub')
fs = self.model.add_filesystem(part, 'fat32')
self.model.add_mount(fs, '/boot/efi')
else:
log.debug('Adding grub_bios gpt partition first')
size_added = \
current_disk.add_partition(partnum=1,
size=BIOS_GRUB_SIZE_BYTES,
fstype=None,
flag='bios_grub')
current_disk.set_tag('(boot)')
part = self.model.add_partition(disk=disk, partnum=1, size=BIOS_GRUB_SIZE_BYTES, flag='bios_grub')
disk.grub_device = True
# adjust downward the partition size to accommodate
# the offset and bios/grub partition
# XXX should probably only do this if the partition is now too big to fit on the disk?
log.debug("Adjusting request down:" +
"{} - {} = {}".format(spec['bytes'], size_added,
spec['bytes'] - size_added))
spec['bytes'] -= size_added
"{} - {} = {}".format(spec['bytes'], part.size,
spec['bytes'] - part.size))
spec['bytes'] -= part.size
spec['partnum'] = 2
if spec["fstype"] in ["swap"]:
current_disk.add_partition(partnum=spec["partnum"],
size=spec["bytes"],
fstype=spec["fstype"])
else:
current_disk.add_partition(partnum=spec["partnum"],
size=spec["bytes"],
fstype=spec["fstype"],
mountpoint=spec["mountpoint"])
except Exception:
log.exception('Failed to add disk partition')
log.debug('Returning to add-disk-partition')
# FIXME: on failure, we should repopulate input values
self.add_disk_partition(disk)
part = self.model.add_partition(disk=disk, partnum=spec["partnum"], size=spec["bytes"])
if spec['fstype'] is not None:
fs = self.model.add_filesystem(part, spec['fstype'])
if spec['mountpoint']:
self.model.add_mount(fs, spec['mountpoint'])
log.info("Successfully added partition")
log.debug("FS Table: {}".format(current_disk.get_fs_table()))
self.prev_view()
def add_disk_format_handler(self, disk, spec):

View File

@ -659,7 +659,7 @@ class Disk:
@property
def next_partnum(self):
return len(self._partitions)
return len(self._partitions) + 1
@property
def size(self):
@ -698,7 +698,7 @@ class Partition:
@property
def path(self):
return "%s%s"(self.device.path, self.number)
return "%s%s"%(self.device.path, self.number)
def render(self):
r = asdict(self)
@ -731,6 +731,18 @@ class Mount:
class FilesystemModel(object):
supported_filesystems = [
('ext4', True, FS('ext4', True)),
('xfs', True, FS('xfs', True)),
('btrfs', True, FS('btrfs', True)),
('---', False),
('swap', True, FS('swap', False)),
('bcache cache', True, FS('bcache cache', False)),
('bcache store', True, FS('bcache store', False)),
('---', False),
('leave unformatted', True, FS('leave unformatted', False)),
]
def __init__(self, prober, opts):
self.prober = prober
self.opts = opts
@ -796,9 +808,10 @@ class FilesystemModel(object):
def get_disk(self, path):
return self._available_disks.get(path)
def add_partition(self, disk, partnum, size):
def add_partition(self, disk, partnum, size, flag=""):
## XXX check, round, maybe adjust size?
self._use_disk(disk)
p = Partition(device=disk, number=partnum, size=size)
p = Partition(device=disk, number=partnum, size=size, flag=flag)
disk._partitions.append(p)
self._partitions.append(p)
return p
@ -830,3 +843,21 @@ class FilesystemModel(object):
def can_install(self):
# Need to figure out stuff to do with grub & a boot partition
return '/' in self.get_mountpoint_to_devpath_mapping()
def validate_mount(self, mountpoint):
if mountpoint is None:
return
# /usr/include/linux/limits.h:PATH_MAX
if len(mountpoint) > 4095:
return 'Path exceeds PATH_MAX'
mnts = self.get_mountpoint_to_devpath_mapping()
dev = mnts.get(mountpoint)
if dev is not None:
return "%s is already mounted at %s"%(dev, mountpoint)
def bootable(self):
''' true if one disk has a boot partition '''
for p in self._partitions:
if p.flag == 'bios_grub':
return True
return False

View File

@ -37,7 +37,7 @@ LEAVE_UNMOUNTED = object()
class MountSelector(WidgetWrap):
def __init__(self, model):
mounts = model.get_mounts()
mounts = model.get_mountpoint_to_devpath_mapping()
opts = []
first_opt = None
max_len = max(map(len, common_mountpoints))

View File

@ -54,13 +54,17 @@ class FSTypeField(FormField):
class AddPartitionForm(Form):
def __init__(self, model, disk_obj):
def __init__(self, model, disk):
self.model = model
self.disk_obj = disk_obj
self.size_str = _humanize_size(disk_obj.freespace)
self.disk = disk
self.size_str = _humanize_size(disk.free)
super().__init__()
self.size.caption = "Size (max {})".format(self.size_str)
self.partnum.value = str(self.disk_obj.lastpartnumber + 1)
self.partnum.value = self.disk.next_partnum
connect_signal(self.fstype.widget, 'select', self.select_fstype)
def select_fstype(self, sender, fs):
self.mount.enabled = fs.is_mounted
partnum = IntegerField("Partition number")
size = StringField()
@ -81,7 +85,7 @@ class AddPartitionForm(Form):
v += unit
self.size.value = v
sz = _dehumanize_size(v)
if sz > self.disk_obj.freespace:
if sz > self.disk.free:
self.size.value = self.size_str
self.size.show_extra(Color.info_minor(Text("Capped partition size at %s"%(self.size_str,), align="center")))
@ -91,24 +95,22 @@ class AddPartitionForm(Form):
class AddPartitionView(BaseView):
def __init__(self, model, controller, selected_disk):
log.debug('AddPartitionView: selected_disk=[{}]'.format(selected_disk))
def __init__(self, model, controller, disk):
log.debug('AddPartitionView: selected_disk=[{}]'.format(disk.path))
self.model = model
self.controller = controller
self.selected_disk = selected_disk
self.disk_obj = self.model.get_disk(selected_disk)
self.disk = disk
self.form = AddPartitionForm(model, self.disk_obj)
self.form = AddPartitionForm(model, self.disk)
connect_signal(self.form, 'submit', self.done)
connect_signal(self.form, 'cancel', self.cancel)
connect_signal(self.form.fstype.widget, 'select', self.select_fstype)
body = [
Columns(
[
("weight", 0.2, Text("Adding partition to {}".format(
self.disk_obj.devpath), align="right")),
self.disk.path), align="right")),
("weight", 0.3, Text(""))
]
),
@ -120,9 +122,6 @@ class AddPartitionView(BaseView):
partition_box = Padding.center_50(ListBox(body))
super().__init__(partition_box)
def select_fstype(self, sender, fs):
self.form.mount.enabled = fs.is_mounted
def cancel(self, button):
self.controller.prev_view()
@ -137,10 +136,10 @@ class AddPartitionView(BaseView):
if self.form.size.value:
size = _dehumanize_size(self.form.size.value)
if size > self.disk_obj.freespace:
size = self.disk_obj.freespace
if size > self.disk.free:
size = self.disk.free
else:
size = self.disk_obj.freespace
size = self.disk.free
result = {
"partnum": self.form.partnum.value,
@ -151,4 +150,4 @@ class AddPartitionView(BaseView):
}
log.debug("Add Partition Result: {}".format(result))
self.controller.add_disk_partition_handler(self.disk_obj.devpath, result)
self.controller.add_disk_partition_handler(self.disk, result)

View File

@ -67,7 +67,7 @@ class DiskPartitionView(BaseView):
mountpoint = '-'
else:
fstype = part._fs.fstype
mountpoint = part._fs.path
mountpoint = part._fs._mount.path
partition_column = Columns([
(15, Text(path)),
Text(size),
@ -124,6 +124,8 @@ class DiskPartitionView(BaseView):
""" Handles presenting the add partition widget button
depending on if partitions exist already or not.
"""
if not self.disk.available:
return None
text = "Add first partition"
if len(self.disk._partitions) > 0:
text = "Add partition (max size {})".format(