move to a model where different types of fs device get different menus
This commit is contained in:
parent
51f0a3561c
commit
3a2d7a8899
|
@ -280,7 +280,7 @@ class FilesystemController(BaseController):
|
|||
|
||||
bootable = self.model.bootable()
|
||||
log.debug('model has bootable device? {}'.format(bootable))
|
||||
can_be_boot = disk.supports_action(DeviceAction.MAKE_BOOT)
|
||||
can_be_boot = DeviceAction.MAKE_BOOT in disk.supported_actions
|
||||
if not bootable and len(disk.partitions()) == 0 and can_be_boot:
|
||||
part = self._create_boot_partition(disk)
|
||||
|
||||
|
|
|
@ -162,16 +162,17 @@ def asdict(inst):
|
|||
|
||||
|
||||
class DeviceAction(enum.Enum):
|
||||
INFO = enum.auto()
|
||||
EDIT = enum.auto()
|
||||
PARTITION = enum.auto()
|
||||
FORMAT = enum.auto()
|
||||
DELETE = enum.auto()
|
||||
MAKE_BOOT = enum.auto()
|
||||
INFO = _("Info")
|
||||
EDIT = _("Edit")
|
||||
PARTITION = _("Add Partition")
|
||||
CREATE_LV = _("Create Logical Volume")
|
||||
FORMAT = _("Format")
|
||||
DELETE = _("Delete")
|
||||
MAKE_BOOT = _("Make Boot Device")
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
class _Formattable:
|
||||
class _Formattable(ABC):
|
||||
# Base class for anything that can be formatted and mounted,
|
||||
# e.g. a disk or a RAID or a partition.
|
||||
|
||||
|
@ -189,8 +190,14 @@ class _Formattable:
|
|||
def constructed_device(self):
|
||||
return self._constructed_device
|
||||
|
||||
def supports_action(self, action):
|
||||
return getattr(self, "_supports_" + action.name)
|
||||
@property
|
||||
@abstractmethod
|
||||
def supported_actions(self):
|
||||
pass
|
||||
|
||||
def action_possible(self, action):
|
||||
assert action in self.supported_actions
|
||||
return getattr(self, "_can_" + action.name)
|
||||
|
||||
|
||||
# Nothing is put in the first and last megabytes of the disk to allow
|
||||
|
@ -337,14 +344,18 @@ class Disk(_Device):
|
|||
return self.serial
|
||||
return self.path
|
||||
|
||||
_supports_INFO = True
|
||||
_supports_EDIT = False
|
||||
_supports_PARTITION = property(lambda self: self.free_for_partitions > 0)
|
||||
_supports_FORMAT = property(
|
||||
supported_actions = [
|
||||
DeviceAction.INFO,
|
||||
DeviceAction.PARTITION,
|
||||
DeviceAction.FORMAT,
|
||||
DeviceAction.MAKE_BOOT,
|
||||
]
|
||||
_can_INFO = True
|
||||
_can_PARTITION = property(lambda self: self.free_for_partitions > 0)
|
||||
_can_FORMAT = property(
|
||||
lambda self: len(self._partitions) == 0 and
|
||||
self._constructed_device is None)
|
||||
_supports_DELETE = False
|
||||
_supports_MAKE_BOOT = property(
|
||||
_can_MAKE_BOOT = property(
|
||||
lambda self:
|
||||
not self.grub_device and self._fs is None
|
||||
and self._constructed_device is None)
|
||||
|
@ -385,15 +396,14 @@ class Partition(_Formattable):
|
|||
def path(self):
|
||||
return "%s%s" % (self.device.path, self._number)
|
||||
|
||||
_supports_INFO = False
|
||||
_supports_EDIT = True
|
||||
_supports_PARTITION = False
|
||||
_supports_FORMAT = property(
|
||||
lambda self: self.flag not in ('boot', 'bios_grub') and
|
||||
self._constructed_device is None)
|
||||
_supports_DELETE = property(
|
||||
supported_actions = [
|
||||
DeviceAction.EDIT,
|
||||
DeviceAction.DELETE,
|
||||
]
|
||||
|
||||
_can_EDIT = True
|
||||
_can_DELETE = property(
|
||||
lambda self: self.flag not in ('boot', 'bios_grub'))
|
||||
_supports_MAKE_BOOT = False
|
||||
|
||||
|
||||
@attr.s(cmp=False)
|
||||
|
@ -417,14 +427,19 @@ class Raid(_Device):
|
|||
def desc(self):
|
||||
return _("software RAID {}").format(self.raidlevel)
|
||||
|
||||
_supports_INFO = False
|
||||
_supports_EDIT = True
|
||||
_supports_PARTITION = Disk._supports_PARTITION
|
||||
_supports_FORMAT = property(
|
||||
supported_actions = [
|
||||
DeviceAction.EDIT,
|
||||
DeviceAction.PARTITION,
|
||||
DeviceAction.FORMAT,
|
||||
DeviceAction.DELETE,
|
||||
]
|
||||
|
||||
_can_EDIT = True
|
||||
_can_PARTITION = Disk._can_PARTITION
|
||||
_can_FORMAT = property(
|
||||
lambda self: len(self._partitions) == 0 and
|
||||
self._constructed_device is None)
|
||||
_supports_DELETE = True
|
||||
_supports_MAKE_BOOT = False
|
||||
_can_DELETE = True
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
|
|
|
@ -32,7 +32,7 @@ from urwid import (
|
|||
from subiquitycore.ui.actionmenu import (
|
||||
Action,
|
||||
ActionMenu,
|
||||
ActionMenuButton,
|
||||
ActionMenuOpenButton,
|
||||
)
|
||||
from subiquitycore.ui.buttons import (
|
||||
back_btn,
|
||||
|
@ -62,7 +62,10 @@ from subiquitycore.ui.utils import (
|
|||
)
|
||||
from subiquitycore.view import BaseView
|
||||
|
||||
from subiquity.models.filesystem import DeviceAction, humanize_size
|
||||
from subiquity.models.filesystem import (
|
||||
DeviceAction,
|
||||
humanize_size,
|
||||
)
|
||||
|
||||
from .delete import can_delete, ConfirmDeleteStretchy
|
||||
from .disk_info import DiskInfoStretchy
|
||||
|
@ -251,6 +254,7 @@ class MountList(WidgetWrap):
|
|||
def _stretchy_shower(cls):
|
||||
def impl(self, device):
|
||||
self.parent.show_stretchy_overlay(cls(self.parent, device))
|
||||
impl.opens_dialog = True
|
||||
return impl
|
||||
|
||||
|
||||
|
@ -287,7 +291,6 @@ class DeviceList(WidgetWrap):
|
|||
_partition_EDIT = _stretchy_shower(
|
||||
lambda parent, part: PartitionStretchy(parent, part.device, part))
|
||||
_partition_DELETE = _stretchy_shower(ConfirmDeleteStretchy)
|
||||
_partition_FORMAT = _disk_FORMAT
|
||||
|
||||
_raid_EDIT = _stretchy_shower(RaidStretchy)
|
||||
_raid_PARTITION = _disk_PARTITION
|
||||
|
@ -300,26 +303,29 @@ class DeviceList(WidgetWrap):
|
|||
getattr(self, meth_name)(device)
|
||||
|
||||
def _action_menu_for_device(self, device):
|
||||
if can_delete(device)[0]:
|
||||
delete_btn = Color.danger_button(ActionMenuButton(_("Delete")))
|
||||
else:
|
||||
delete_btn = _("Delete *")
|
||||
device_actions = [
|
||||
(_("Information"), DeviceAction.INFO),
|
||||
(_("Edit"), DeviceAction.EDIT),
|
||||
(_("Add Partition"), DeviceAction.PARTITION),
|
||||
(_("Format / Mount"), DeviceAction.FORMAT),
|
||||
(delete_btn, DeviceAction.DELETE),
|
||||
(_("Make boot device"), DeviceAction.MAKE_BOOT),
|
||||
]
|
||||
actions = []
|
||||
for label, action in device_actions:
|
||||
actions.append(Action(
|
||||
device_actions = []
|
||||
can_delete_device = can_delete(device)[0]
|
||||
for action in device.supported_actions:
|
||||
if action == DeviceAction.DELETE:
|
||||
enabled = True
|
||||
if can_delete_device:
|
||||
label = Color.danger_button(
|
||||
ActionMenuOpenButton(_("Delete")))
|
||||
else:
|
||||
label = _("Delete *")
|
||||
else:
|
||||
label = _(action.value)
|
||||
enabled = device.action_possible(action)
|
||||
meth_name = '_{}_{}'.format(device.type, action.name)
|
||||
meth = getattr(self, meth_name)
|
||||
opens_dialog = getattr(meth, 'opens_dialog', False)
|
||||
device_actions.append(Action(
|
||||
label=label,
|
||||
enabled=device.supports_action(action),
|
||||
enabled=enabled,
|
||||
value=action,
|
||||
opens_dialog=action != DeviceAction.MAKE_BOOT))
|
||||
menu = ActionMenu(actions, "\N{BLACK RIGHT-POINTING SMALL TRIANGLE}")
|
||||
opens_dialog=opens_dialog))
|
||||
menu = ActionMenu(
|
||||
device_actions, "\N{BLACK RIGHT-POINTING SMALL TRIANGLE}")
|
||||
connect_signal(menu, 'action', self._action, device)
|
||||
return menu
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ from subiquity.models.filesystem import (
|
|||
DeviceAction,
|
||||
get_raid_size,
|
||||
humanize_size,
|
||||
Partition,
|
||||
raidlevels,
|
||||
raidlevels_by_value,
|
||||
)
|
||||
|
@ -341,9 +342,19 @@ class RaidStretchy(Stretchy):
|
|||
cur_devices = existing.devices | existing.spare_devices
|
||||
|
||||
def device_ok(dev):
|
||||
return (dev not in omits
|
||||
and (dev.supports_action(DeviceAction.FORMAT)
|
||||
or dev in cur_devices))
|
||||
if dev in omits:
|
||||
return False
|
||||
if dev in cur_devices:
|
||||
return True
|
||||
if dev.fs():
|
||||
return False
|
||||
if dev in cur_devices:
|
||||
return True
|
||||
if dev.constructed_device() is not None:
|
||||
return False
|
||||
if isinstance(dev, Partition):
|
||||
return not dev.flag
|
||||
return dev.action_possible(DeviceAction.FORMAT)
|
||||
|
||||
for dev in self.parent.model.all_devices():
|
||||
if device_ok(dev):
|
||||
|
|
Loading…
Reference in New Issue