support imsm volumes as boot devices

This commit is contained in:
Michael Hudson-Doyle 2021-06-25 15:52:12 +12:00
parent 7cfd5e42ab
commit dfe36d7617
5 changed files with 39 additions and 4 deletions

View File

@ -111,7 +111,7 @@ def _raid_actions(raid):
DeviceAction.DELETE, DeviceAction.DELETE,
] ]
else: else:
return [ actions = [
DeviceAction.EDIT, DeviceAction.EDIT,
DeviceAction.PARTITION, DeviceAction.PARTITION,
DeviceAction.FORMAT, DeviceAction.FORMAT,
@ -119,6 +119,10 @@ def _raid_actions(raid):
DeviceAction.DELETE, DeviceAction.DELETE,
DeviceAction.REFORMAT, DeviceAction.REFORMAT,
] ]
if raid._m.bootloader == Bootloader.UEFI:
if raid.container and raid.container.metadata == 'imsm':
actions.append(DeviceAction.TOGGLE_BOOT)
return actions
@_supported_actions.register(LVM_VolGroup) @_supported_actions.register(LVM_VolGroup)
@ -346,6 +350,7 @@ _can_toggle_boot = make_checker(DeviceAction.TOGGLE_BOOT)
@_can_toggle_boot.register(Disk) @_can_toggle_boot.register(Disk)
@_can_toggle_boot.register(Raid)
def _can_toggle_boot_disk(disk): def _can_toggle_boot_disk(disk):
if boot.is_boot_device(disk): if boot.is_boot_device(disk):
for disk2 in boot.all_boot_devices(disk._m): for disk2 in boot.all_boot_devices(disk._m):

View File

@ -17,6 +17,7 @@ import functools
from subiquity.models.filesystem import ( from subiquity.models.filesystem import (
Disk, Disk,
Raid,
Bootloader, Bootloader,
Partition, Partition,
) )
@ -39,6 +40,16 @@ def _is_boot_device_disk(disk):
return any(p.grub_device for p in disk._partitions) return any(p.grub_device for p in disk._partitions)
@is_boot_device.register(Raid)
def _is_boot_device_raid(raid):
bl = raid._m.bootloader
if bl != Bootloader.UEFI:
return False
if not raid.container or raid.container.metadata != 'imsm':
return False
return any(p.grub_device for p in raid._partitions)
@functools.singledispatch @functools.singledispatch
def can_be_boot_device(device, *, with_reformatting=False): def can_be_boot_device(device, *, with_reformatting=False):
"""Can `device` be made into a boot device? """Can `device` be made into a boot device?
@ -66,6 +77,19 @@ def _can_be_boot_device_disk(disk, *, with_reformatting=False):
return True return True
@can_be_boot_device.register(Raid)
def _can_be_boot_device_raid(raid, *, with_reformatting=False):
bl = raid._m.bootloader
if bl != Bootloader.UEFI:
return False
if not raid.container or raid.container.metadata != 'imsm':
return False
if raid._has_preexisting_partition() and not with_reformatting:
return any(is_esp(p) for p in raid._partitions)
else:
return True
@functools.singledispatch @functools.singledispatch
def is_esp(device): def is_esp(device):
"""Is `device` a UEFI ESP?""" """Is `device` a UEFI ESP?"""
@ -78,7 +102,7 @@ def _is_esp_partition(partition):
return False return False
if partition.device.ptable == "gpt": if partition.device.ptable == "gpt":
return partition.flag == "boot" return partition.flag == "boot"
else: elif isinstance(partition.device, Disk):
blockdev_raw = partition._m._probe_data['blockdev'].get( blockdev_raw = partition._m._probe_data['blockdev'].get(
partition._path()) partition._path())
if blockdev_raw is None: if blockdev_raw is None:
@ -91,11 +115,14 @@ def _is_esp_partition(partition):
except ValueError: except ValueError:
# In case there was garbage in the udev entry... # In case there was garbage in the udev entry...
return False return False
else:
return False
def all_boot_devices(model): def all_boot_devices(model):
"""Return all current boot devices for `model`.""" """Return all current boot devices for `model`."""
return [disk for disk in model.all_disks() if is_boot_device(disk)] candidates = model.all_disks() + model.all_raids()
return [cand for cand in candidates if is_boot_device(cand)]
def is_bootloader_partition(partition): def is_bootloader_partition(partition):

View File

@ -256,6 +256,7 @@ def for_client(device, *, min_size=0):
@for_client.register(Disk) @for_client.register(Disk)
@for_client.register(Raid)
def _for_client_disk(disk, *, min_size=0): def _for_client_disk(disk, *, min_size=0):
return types.Disk( return types.Disk(
id=disk.id, id=disk.id,

View File

@ -356,6 +356,7 @@ class FilesystemManipulator:
p.wipe = 'zero' p.wipe = 'zero'
p.grub_device = True p.grub_device = True
else: else:
if new_boot_disk.type == "disk":
new_boot_disk.preserve = False new_boot_disk.preserve = False
if bootloader == Bootloader.UEFI: if bootloader == Bootloader.UEFI:
part_size = UEFI_GRUB_SIZE_BYTES part_size = UEFI_GRUB_SIZE_BYTES

View File

@ -303,6 +303,7 @@ class DeviceList(WidgetWrap):
_raid_REFORMAT = _disk_REFORMAT _raid_REFORMAT = _disk_REFORMAT
_raid_REMOVE = _disk_REMOVE _raid_REMOVE = _disk_REMOVE
_raid_DELETE = _partition_DELETE _raid_DELETE = _partition_DELETE
_raid_TOGGLE_BOOT = _disk_TOGGLE_BOOT
_lvm_volgroup_EDIT = _stretchy_shower(VolGroupStretchy) _lvm_volgroup_EDIT = _stretchy_shower(VolGroupStretchy)
_lvm_volgroup_CREATE_LV = _disk_PARTITION _lvm_volgroup_CREATE_LV = _disk_PARTITION