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,
]
else:
return [
actions = [
DeviceAction.EDIT,
DeviceAction.PARTITION,
DeviceAction.FORMAT,
@ -119,6 +119,10 @@ def _raid_actions(raid):
DeviceAction.DELETE,
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)
@ -346,6 +350,7 @@ _can_toggle_boot = make_checker(DeviceAction.TOGGLE_BOOT)
@_can_toggle_boot.register(Disk)
@_can_toggle_boot.register(Raid)
def _can_toggle_boot_disk(disk):
if boot.is_boot_device(disk):
for disk2 in boot.all_boot_devices(disk._m):

View File

@ -17,6 +17,7 @@ import functools
from subiquity.models.filesystem import (
Disk,
Raid,
Bootloader,
Partition,
)
@ -39,6 +40,16 @@ def _is_boot_device_disk(disk):
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
def can_be_boot_device(device, *, with_reformatting=False):
"""Can `device` be made into a boot device?
@ -66,6 +77,19 @@ def _can_be_boot_device_disk(disk, *, with_reformatting=False):
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
def is_esp(device):
"""Is `device` a UEFI ESP?"""
@ -78,7 +102,7 @@ def _is_esp_partition(partition):
return False
if partition.device.ptable == "gpt":
return partition.flag == "boot"
else:
elif isinstance(partition.device, Disk):
blockdev_raw = partition._m._probe_data['blockdev'].get(
partition._path())
if blockdev_raw is None:
@ -91,11 +115,14 @@ def _is_esp_partition(partition):
except ValueError:
# In case there was garbage in the udev entry...
return False
else:
return False
def all_boot_devices(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):

View File

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

View File

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

View File

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