Merge pull request #1918 from dbungert/use-zfs-keystore

Use zfs keystore
This commit is contained in:
Dan Bungert 2024-02-27 15:37:19 -07:00 committed by GitHub
commit 0aaade5c53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 8 deletions

View File

@ -20,6 +20,7 @@ from curtin.block import get_resize_fstypes
from subiquity.common.filesystem import boot, gaps
from subiquity.common.types import Bootloader
from subiquity.models.filesystem import Partition, align_up
from subiquitycore.utils import write_named_tempfile
log = logging.getLogger("subiquity.common.filesystem.manipulator")
@ -188,7 +189,16 @@ class FilesystemManipulator:
self.create_filesystem(dmc, dict(fstype="swap"))
return dmc
def create_zpool(self, device, pool, mountpoint, boot=False, canmount="on"):
def create_zpool(
self,
device,
pool,
mountpoint,
boot=False,
canmount="on",
encryption_style=None,
key=None,
):
fs_properties = dict(
atime=None,
acltype="posixacl",
@ -201,6 +211,10 @@ class FilesystemManipulator:
xattr="sa",
)
keyfile = None
if key is not None:
keyfile = write_named_tempfile("zpool-key-", key)
pool_properties = dict(ashift=12, autotrim="on", version=None)
default_features = True
if boot:
@ -217,6 +231,8 @@ class FilesystemManipulator:
default_features=default_features,
fs_properties=fs_properties,
pool_properties=pool_properties,
encryption_style=encryption_style,
keyfile=keyfile,
)
def delete(self, obj):

View File

@ -36,6 +36,7 @@ from curtin.util import human2bytes
from probert.storage import StorageInfo
from subiquity.common.types import Bootloader, OsProber, RecoveryKey
from subiquitycore.utils import write_named_tempfile
log = logging.getLogger("subiquity.models.filesystem")
@ -1135,10 +1136,7 @@ class DM_Crypt(_Formattable):
def serialize_key(self):
if self.key and not self.keyfile:
f = tempfile.NamedTemporaryFile(prefix="luks-key-", mode="w", delete=False)
f.write(self.key)
f.close()
return {"keyfile": f.name}
return {"keyfile": write_named_tempfile("luks-key-", self.key)}
else:
return {}
@ -1312,6 +1310,8 @@ class ZPool:
fs_properties: Optional[dict] = None
default_features: Optional[bool] = True
encryption_style: Optional[str] = None
keyfile: Optional[str] = None
component_name = "vdev"
@ -2257,6 +2257,8 @@ class FilesystemModel:
default_features=True,
fs_properties=None,
pool_properties=None,
encryption_style=None,
keyfile=None,
):
zpool = ZPool(
m=self,
@ -2266,6 +2268,8 @@ class FilesystemModel:
default_features=default_features,
pool_properties=pool_properties,
fs_properties=fs_properties,
encryption_style=encryption_style,
keyfile=keyfile,
)
self._actions.append(zpool)
return zpool

View File

@ -565,7 +565,9 @@ 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
encryption_style = None
if encrypted := choice.password is not None:
encryption_style = "luks_keystore"
avail = gap_rest.size - self._info.min_size
swap_size = align_down(swap.suggested_swapsize(avail=avail), part_align)
@ -586,7 +588,14 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
bpool.create_zfs("BOOT", canmount="off", mountpoint="none")
bpool.create_zfs(f"BOOT/ubuntu_{uuid}", mountpoint="/boot")
rpool = self.create_zpool(rpart, "rpool", "/", canmount="off")
rpool = self.create_zpool(
rpart,
"rpool",
"/",
canmount="off",
encryption_style=encryption_style,
key=choice.password,
)
rpool.create_zfs("ROOT", canmount="off", mountpoint="none")
rpool.create_zfs(f"ROOT/ubuntu_{uuid}", mountpoint="/")
rpool.create_zfs(f"ROOT/ubuntu_{uuid}/var", canmount="off")
@ -1396,7 +1405,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
assert mode == "reformat_disk"
elif name == "zfs":
if password is not None:
capability = GuidedCapability.ZFS_LUKS
capability = GuidedCapability.ZFS_LUKS_KEYSTORE
else:
capability = GuidedCapability.ZFS
else:

View File

@ -581,6 +581,8 @@ class TestGuided(IsolatedAsyncioTestCase):
[rpool] = self.model._all(type="zpool", pool="rpool")
self.assertIsNone(rpool.path)
self.assertEqual([root], rpool.vdevs)
self.assertIsNone(rpool.encryption_style)
self.assertIsNone(rpool.keyfile)
[bpool] = self.model._all(type="zpool", pool="bpool")
self.assertIsNone(bpool.path)
self.assertEqual([boot], bpool.vdevs)
@ -618,6 +620,9 @@ class TestGuided(IsolatedAsyncioTestCase):
[rpool] = self.model._all(type="zpool", pool="rpool")
self.assertIsNone(rpool.path)
self.assertEqual([root], rpool.vdevs)
self.assertEqual("luks_keystore", rpool.encryption_style)
with open(rpool.keyfile) as fp:
self.assertEqual("passw0rd", fp.read())
[bpool] = self.model._all(type="zpool", pool="bpool")
self.assertIsNone(bpool.path)
self.assertEqual([boot], bpool.vdevs)

View File

@ -19,6 +19,7 @@ import logging
import os
import random
import subprocess
import tempfile
from typing import Any, Dict, List, Sequence
log = logging.getLogger("subiquitycore.utils")
@ -282,3 +283,10 @@ def gen_zsys_uuid():
"""Create a 6 character identifier. Functionally equivalent to
`head -100 /dev/urandom | tr -dc 'a-z0-9' | head -c6`"""
return "".join([random.choice(_zsys_uuid_charset()) for i in range(6)])
def write_named_tempfile(prefix, contents):
f = tempfile.NamedTemporaryFile(prefix=prefix, mode="w", delete=False)
with f:
f.write(contents)
return f.name