From a6537b5f53593f96a6193d2670cf82be32609bae Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Sat, 7 Jul 2018 20:39:35 +1200 Subject: [PATCH] allow creating a vg --- subiquity/models/filesystem.py | 62 ++++++++++++++++----- subiquity/ui/views/__init__.py | 2 - subiquity/ui/views/filesystem/filesystem.py | 19 ++++++- subiquity/ui/views/filesystem/lvm.py | 7 +-- 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/subiquity/models/filesystem.py b/subiquity/models/filesystem.py index f88555f9..b82c4cca 100644 --- a/subiquity/models/filesystem.py +++ b/subiquity/models/filesystem.py @@ -207,18 +207,25 @@ def _generic_can_REMOVE(obj): cd = obj.constructed_device() if cd is None: return False - assert isinstance(cd, Raid) - if obj in cd.spare_devices: - return True - min_devices = raidlevels_by_value[cd.raidlevel].min_devices - if len(cd.devices) == min_devices: + if isinstance(cd, Raid): + if obj in cd.spare_devices: + return True + min_devices = raidlevels_by_value[cd.raidlevel].min_devices + if len(cd.devices) == min_devices: + return _( + "Removing {selflabel} would leave the {cdtype} {cdlabel} with less" + " than {min_devices} devices.").format( + selflabel=obj.label, + cdtype=cd.desc(), + cdlabel=cd.label, + min_devices=min_devices) + elif isinstance(cd, LVM_VolGroup): return _( - "Removing {selflabel} would leave the {cdtype} {cdlabel} with less" - " than {min_devices} devices.").format( + "Removing {selflabel} would leave the {cdtype} {cdlabel} with no " + "devices.").format( selflabel=obj.label, cdtype=cd.desc(), - cdlabel=cd.label, - min_devices=min_devices) + cdlabel=cd.label) return True @@ -275,7 +282,7 @@ class _Formattable(ABC): @property @abstractmethod - def ok_for_lvm(self): + def ok_for_lvm_vg(self): pass @@ -441,7 +448,7 @@ class Disk(_Device): not self.grub_device and self._fs is None and self._constructed_device is None) - ok_for_raid = ok_for_lvm = _can_FORMAT + ok_for_raid = ok_for_lvm_vg = _can_FORMAT @attr.s(cmp=False) @@ -504,7 +511,7 @@ class Partition(_Formattable): return False return True - ok_for_lvm = ok_for_raid + ok_for_lvm_vg = ok_for_raid @attr.s(cmp=False) @@ -569,7 +576,7 @@ class Raid(_Device): if self._fs is not None: return False - ok_for_lvm = ok_for_raid + ok_for_lvm_vg = ok_for_raid # What is a device that makes up this device referred to as? component_name = "component" @@ -583,9 +590,15 @@ class LVM_VolGroup(_Device): name = attr.ib(default=None) devices = attr.ib(default=attr.Factory(set)) # set([_Formattable]) + @property def size(self): return get_lvm_size(self.devices) + @property + def free_for_partitions(self): + return self.size - self.used - GPT_OVERHEAD + + @property def label(self): return self.name @@ -598,7 +611,28 @@ class LVM_VolGroup(_Device): DeviceAction.DELETE, ] + @property + def _can_EDIT(self): + if len(self._partitions) > 0: + return _( + "Cannot edit {selflabel} because it has logical volumes.").format( + selflabel=self.label) + else: + return _generic_can_EDIT(self) + + _can_CREATE_LV = Disk._can_PARTITION + + @property + def _can_DELETE(self): + if len(self._partitions) > 0: + return _( + "Cannot delete {selflabel} because it has logical volumes.").format( + selflabel=self.label) + else: + return _generic_can_DELETE(self) + ok_for_raid = False + ok_for_lvm_vg = False # What is a device that makes up this device referred to as? component_name = "PV" @@ -639,7 +673,7 @@ class LVM_LogicalVolume(_Formattable): return self.volgroup.path + '/' + self.name ok_for_raid = False - ok_for_lvm = False + ok_for_lvm_vg = False @attr.s(cmp=False) diff --git a/subiquity/ui/views/__init__.py b/subiquity/ui/views/__init__.py index b11fb72b..9bf32b27 100644 --- a/subiquity/ui/views/__init__.py +++ b/subiquity/ui/views/__init__.py @@ -21,7 +21,6 @@ from .filesystem import ( from .bcache import BcacheView from .ceph import CephDiskView from .iscsi import IscsiDiskView -from .lvm import LVMVolumeGroupView from .identity import IdentityView from .installpath import InstallpathView, MAASView from .installprogress import ProgressView @@ -37,7 +36,6 @@ __all__ = [ 'InstallpathView', 'IscsiDiskView', 'KeyboardView', - 'LVMVolumeGroupView', 'MAASView', 'ProgressView', 'WelcomeView', diff --git a/subiquity/ui/views/filesystem/filesystem.py b/subiquity/ui/views/filesystem/filesystem.py index 391fa5f5..c05ac769 100644 --- a/subiquity/ui/views/filesystem/filesystem.py +++ b/subiquity/ui/views/filesystem/filesystem.py @@ -69,6 +69,7 @@ from subiquity.models.filesystem import ( from .delete import ConfirmDeleteStretchy from .disk_info import DiskInfoStretchy +from .lvm import VolGroupStretchy from .partition import PartitionStretchy, FormatEntireStretchy from .raid import RaidStretchy @@ -316,6 +317,10 @@ class DeviceList(WidgetWrap): _raid_REMOVE = _disk_REMOVE _raid_DELETE = _partition_DELETE + _lvm_volgroup_EDIT = _stretchy_shower(VolGroupStretchy) + _lvm_volgroup_CREATE_LV = _disk_PARTITION + _lvm_volgroup_DELETE = _partition_DELETE + def _action(self, sender, value, device): action, meth = value log.debug('_action %s %s', action, device.id) @@ -472,8 +477,11 @@ class FilesystemView(BaseView): self._create_raid_btn = Toggleable(menu_btn( label=_("Create software RAID (md)"), on_press=self.create_raid)) + self._create_vg_btn = Toggleable(menu_btn( + label=_("Create volume group (LVM)"), + on_press=self.create_vg)) - bp = button_pile([self._create_raid_btn]) + bp = button_pile([self._create_raid_btn, self._create_vg_btn]) bp.align = 'left' body = [ @@ -515,14 +523,20 @@ class FilesystemView(BaseView): ] def refresh_model_inputs(self): + lvm_devices = set() raid_devices = set() for d in self.model.all_devices(): if d.ok_for_raid: raid_devices.add(d) + if d.ok_for_lvm_vg: + lvm_devices.add(d) for p in d.partitions(): if p.ok_for_raid: raid_devices.add(p) + if p.ok_for_lvm_vg: + lvm_devices.add(p) self._create_raid_btn.enabled = len(raid_devices) > 1 + self._create_vg_btn.enabled = len(lvm_devices) > 0 self.mount_list.refresh_model_inputs() self.avail_list.refresh_model_inputs() self.used_list.refresh_model_inputs() @@ -547,6 +561,9 @@ class FilesystemView(BaseView): def create_raid(self, button=None): self.show_stretchy_overlay(RaidStretchy(self)) + def create_vg(self, button=None): + self.show_stretchy_overlay(VolGroupStretchy(self)) + def cancel(self, button=None): self.controller.default() diff --git a/subiquity/ui/views/filesystem/lvm.py b/subiquity/ui/views/filesystem/lvm.py index 5ac776f2..c70a0490 100644 --- a/subiquity/ui/views/filesystem/lvm.py +++ b/subiquity/ui/views/filesystem/lvm.py @@ -64,7 +64,7 @@ class VolGroupStretchy(Stretchy): def __init__(self, parent, existing=None): self.parent = parent self.existing = existing - vg_names = {vg.name for vg in parent.model.all_vgs()} + vg_names = {vg.name for vg in parent.model.all_volgroups()} if existing is None: title = _('Create LVM volume group') x = 0 @@ -89,7 +89,7 @@ class VolGroupStretchy(Stretchy): possible_components = get_possible_components( self.parent.model, existing, initial['devices'], - lambda dev: dev.ok_for_lvm) + lambda dev: dev.ok_for_lvm_vg) form = self.form = VolGroupForm( self.parent.model, possible_components, initial, vg_names) @@ -109,8 +109,7 @@ class VolGroupStretchy(Stretchy): def _change_devices(self, sender, new_devices): if len(sender.active_devices) >= 1: - self.form.size.value = humanize_size( - get_lvm_size(self.form.level.value.value, new_devices)) + self.form.size.value = humanize_size(get_lvm_size(new_devices)) else: self.form.size.value = '-'