commit
ab31a3b206
|
@ -70,7 +70,7 @@ parts:
|
|||
|
||||
source: https://git.launchpad.net/curtin
|
||||
source-type: git
|
||||
source-commit: a349105809af6188cb394e300a99846df3d117f0
|
||||
source-commit: 1997a1614e774cbd152fa33059d53417a641dbd6
|
||||
|
||||
override-pull: |
|
||||
craftctl default
|
||||
|
|
|
@ -145,7 +145,7 @@ class FilesystemManipulator:
|
|||
if key:
|
||||
device = self.model.add_dm_crypt(
|
||||
device,
|
||||
key,
|
||||
key=key,
|
||||
recovery_key=spec.get("recovery-key"),
|
||||
)
|
||||
devices.add(device)
|
||||
|
@ -177,6 +177,15 @@ class FilesystemManipulator:
|
|||
|
||||
delete_lvm_partition = delete_logical_volume
|
||||
|
||||
def create_cryptoswap(self, device):
|
||||
dmc = self.model.add_dm_crypt(
|
||||
device,
|
||||
keyfile="/dev/urandom",
|
||||
options=["swap", "initramfs"],
|
||||
)
|
||||
self.create_filesystem(dmc, dict(fstype="swap"))
|
||||
return dmc
|
||||
|
||||
def create_zpool(self, device, pool, mountpoint, boot=False, canmount="on"):
|
||||
fs_properties = dict(
|
||||
atime=None,
|
||||
|
@ -341,7 +350,7 @@ class FilesystemManipulator:
|
|||
if key:
|
||||
d = self.model.add_dm_crypt(
|
||||
d,
|
||||
key,
|
||||
key=key,
|
||||
recovery_key=spec.get("recovery-key"),
|
||||
)
|
||||
d._constructed_device = existing
|
||||
|
|
|
@ -347,6 +347,7 @@ class GuidedCapability(enum.Enum):
|
|||
LVM = enum.auto()
|
||||
LVM_LUKS = enum.auto()
|
||||
ZFS = enum.auto()
|
||||
ZFS_LUKS = enum.auto()
|
||||
|
||||
CORE_BOOT_ENCRYPTED = enum.auto()
|
||||
CORE_BOOT_UNENCRYPTED = enum.auto()
|
||||
|
@ -381,7 +382,10 @@ class GuidedCapability(enum.Enum):
|
|||
]
|
||||
|
||||
def is_zfs(self) -> bool:
|
||||
return self in [GuidedCapability.ZFS]
|
||||
return self in [
|
||||
GuidedCapability.ZFS,
|
||||
GuidedCapability.ZFS_LUKS,
|
||||
]
|
||||
|
||||
|
||||
class GuidedDisallowedCapabilityReason(enum.Enum):
|
||||
|
|
|
@ -1068,10 +1068,11 @@ LUKS_OVERHEAD = 16 * (2**20)
|
|||
|
||||
|
||||
@fsobj("dm_crypt")
|
||||
class DM_Crypt:
|
||||
class DM_Crypt(_Formattable):
|
||||
volume: _Formattable = attributes.ref(backlink="_constructed_device")
|
||||
key: Optional[str] = attr.ib(metadata={"redact": True}, default=None)
|
||||
keyfile: Optional[str] = None
|
||||
options: Optional[List[str]] = None
|
||||
recovery_key: Optional[RecoveryKeyHandler] = None
|
||||
_recovery_keyfile: Optional[str] = None
|
||||
_recovery_live_location: Optional[str] = None
|
||||
|
@ -1142,6 +1143,29 @@ class DM_Crypt:
|
|||
def size(self):
|
||||
return self.volume.size - LUKS_OVERHEAD
|
||||
|
||||
def available(self):
|
||||
if self._is_in_use:
|
||||
return False
|
||||
if self._constructed_device is not None:
|
||||
return False
|
||||
if self._fs is None:
|
||||
return True
|
||||
return self._fs._available()
|
||||
|
||||
@property
|
||||
def ok_for_raid(self):
|
||||
if self._fs is not None:
|
||||
if self._fs.preserve:
|
||||
return self._fs._mount is None
|
||||
return False
|
||||
if self._constructed_device is not None:
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def ok_for_lvm_vg(self):
|
||||
return self.ok_for_raid and self.size > LVM_OVERHEAD
|
||||
|
||||
|
||||
@fsobj("device")
|
||||
class ArbitraryDevice(_Device):
|
||||
|
@ -2081,9 +2105,11 @@ class FilesystemModel:
|
|||
def add_dm_crypt(
|
||||
self,
|
||||
volume,
|
||||
key,
|
||||
*,
|
||||
recovery_key: Optional[RecoveryKeyHandler],
|
||||
key: Optional[str] = None,
|
||||
keyfile: Optional[str] = None,
|
||||
options: Optional[List[str]] = None,
|
||||
recovery_key: Optional[RecoveryKeyHandler] = None,
|
||||
root: Optional[pathlib.Path] = None,
|
||||
):
|
||||
if not volume.available:
|
||||
|
@ -2093,6 +2119,8 @@ class FilesystemModel:
|
|||
m=self,
|
||||
volume=volume,
|
||||
key=key,
|
||||
keyfile=keyfile,
|
||||
options=options,
|
||||
recovery_key=recovery_key,
|
||||
)
|
||||
self._actions.append(dm_crypt)
|
||||
|
|
|
@ -216,6 +216,7 @@ class VariationInfo:
|
|||
GuidedCapability.LVM,
|
||||
GuidedCapability.LVM_LUKS,
|
||||
GuidedCapability.ZFS,
|
||||
GuidedCapability.ZFS_LUKS,
|
||||
]
|
||||
),
|
||||
)
|
||||
|
@ -563,13 +564,17 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
bootfs_size = align_up(sizes.get_bootfs_size(gap.size), part_align)
|
||||
gap_boot, gap_rest = gap.split(bootfs_size)
|
||||
bpart = self.create_partition(device, gap_boot, dict(fstype=None))
|
||||
encrypted = choice.password is not None
|
||||
|
||||
avail = gap_rest.size - self._info.min_size
|
||||
swap_size = align_down(swap.suggested_swapsize(avail=avail), part_align)
|
||||
if swap_size > 0:
|
||||
gap_swap, gap_rootfs = gap_rest.split(swap_size)
|
||||
self.create_partition(device, gap_swap, dict(fstype="swap"))
|
||||
gap = gap_rootfs
|
||||
gap_swap, gap = gap_rest.split(swap_size)
|
||||
if encrypted:
|
||||
part = self.create_partition(device, gap_swap, {})
|
||||
self.create_cryptoswap(part)
|
||||
else:
|
||||
self.create_partition(device, gap_swap, dict(fstype="swap"))
|
||||
else:
|
||||
gap = gap_rest
|
||||
rpart = self.create_partition(device, gap, dict(fstype=None))
|
||||
|
@ -1386,7 +1391,10 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
capability = GuidedCapability.DD
|
||||
assert mode == "reformat_disk"
|
||||
elif name == "zfs":
|
||||
capability = GuidedCapability.ZFS
|
||||
if password is not None:
|
||||
capability = GuidedCapability.ZFS_LUKS
|
||||
else:
|
||||
capability = GuidedCapability.ZFS
|
||||
else:
|
||||
capability = GuidedCapability.DIRECT
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ default_capabilities = [
|
|||
GuidedCapability.LVM,
|
||||
GuidedCapability.LVM_LUKS,
|
||||
GuidedCapability.ZFS,
|
||||
GuidedCapability.ZFS_LUKS,
|
||||
]
|
||||
|
||||
|
||||
|
@ -567,6 +568,43 @@ class TestGuided(IsolatedAsyncioTestCase):
|
|||
zfs_boot = self.model._mount_for_path("/boot")
|
||||
self.assertEqual("zfs", zfs_boot.type)
|
||||
|
||||
@parameterized.expand(boot_expectations)
|
||||
async def test_guided_zfs_luks(self, bootloader, ptable, p1mnt):
|
||||
await self._guided_setup(bootloader, ptable)
|
||||
target = GuidedStorageTargetReformat(
|
||||
disk_id=self.d1.id, allowed=default_capabilities
|
||||
)
|
||||
await self.controller.guided(
|
||||
GuidedChoiceV2(
|
||||
target=target,
|
||||
capability=GuidedCapability.ZFS_LUKS,
|
||||
password="passw0rd",
|
||||
)
|
||||
)
|
||||
[firmware, boot, swap, root] = self.d1.partitions()
|
||||
self.assertEqual(p1mnt, firmware.mount)
|
||||
self.assertIsNone(boot.mount)
|
||||
self.assertIsNone(root.mount)
|
||||
self.assertFalse(firmware.preserve)
|
||||
self.assertFalse(boot.preserve)
|
||||
self.assertFalse(swap.preserve)
|
||||
self.assertFalse(root.preserve)
|
||||
self.assertIsNone(swap.fs())
|
||||
[dmc] = self.model.all_dm_crypts()
|
||||
self.assertEqual("/dev/urandom", dmc.keyfile)
|
||||
self.assertEqual(["swap", "initramfs"], dmc.options)
|
||||
self.assertEqual("swap", dmc.fs().fstype)
|
||||
[rpool] = self.model._all(type="zpool", pool="rpool")
|
||||
self.assertIsNone(rpool.path)
|
||||
self.assertEqual([root], rpool.vdevs)
|
||||
[bpool] = self.model._all(type="zpool", pool="bpool")
|
||||
self.assertIsNone(bpool.path)
|
||||
self.assertEqual([boot], bpool.vdevs)
|
||||
zfs_rootfs = self.model._mount_for_path("/")
|
||||
self.assertEqual("zfs", zfs_rootfs.type)
|
||||
zfs_boot = self.model._mount_for_path("/boot")
|
||||
self.assertEqual("zfs", zfs_boot.type)
|
||||
|
||||
async def test_guided_zfs_BIOS_MSDOS(self):
|
||||
await self._guided_setup(Bootloader.BIOS, "msdos")
|
||||
target = GuidedStorageTargetReformat(
|
||||
|
|
Loading…
Reference in New Issue