Added zfs pool creation

This commit is contained in:
oddlama 2021-05-27 20:35:28 +02:00
parent d229d5bdea
commit a5cfe872a3
No known key found for this signature in database
GPG Key ID: 14EFE510775FE39A
7 changed files with 137 additions and 52 deletions

16
configure vendored
View File

@ -167,7 +167,7 @@ ALL_PARTITIONING_SCHEMES=(
PARTITIONING_BOOT_TYPES=("efi" "bios") PARTITIONING_BOOT_TYPES=("efi" "bios")
PARTITIONING_ROOT_FS_TYPES=("ext4" "btrfs") PARTITIONING_ROOT_FS_TYPES=("ext4" "btrfs")
PARTITIONING_BTRFS_RAID_TYPES=("raid0" "raid1") PARTITIONING_BTRFS_RAID_TYPES=("raid0" "raid1")
PARTITIONING_ZFS_POOL_TYPES=("stripe" "mirror") PARTITIONING_ZFS_POOL_TYPES=("standard" "custom")
function create_single_disk_layout() { function create_single_disk_layout() {
create_classic_single_disk_layout create_classic_single_disk_layout
@ -220,7 +220,7 @@ function create_zfs_centric_layout() {
PARTITIONING_DEVICES=("${extra_arguments[@]}") PARTITIONING_DEVICES=("${extra_arguments[@]}")
parse_swap "${arguments[swap]}" parse_swap "${arguments[swap]}"
PARTITIONING_BOOT_TYPE="${arguments[type]}" PARTITIONING_BOOT_TYPE="${arguments[type]}"
PARTITIONING_ZFS_POOL_TYPE="${arguments[pool_type]:-stripe}" PARTITIONING_ZFS_POOL_TYPE="${arguments[pool_type]:-standard}"
PARTITIONING_ZFS_ENCRYPTION="${arguments[encrypt]:-false}" PARTITIONING_ZFS_ENCRYPTION="${arguments[encrypt]:-false}"
} }
@ -319,7 +319,7 @@ function load_default_config() {
LOCALE="C.utf8" LOCALE="C.utf8"
function disk_configuration() { function disk_configuration() {
create_zfs_centric_layout swap=8GiB type=efi encrypt=true pool_type=stripe /dev/sdX create_zfs_centric_layout swap=8GiB type=efi encrypt=true pool_type=standard /dev/sdX
} }
SYSTEMD=true SYSTEMD=true
@ -682,8 +682,8 @@ MENU_ITEMS=(
"PARTITIONING_SWAP" "PARTITIONING_SWAP"
"PARTITIONING_ROOT_FS" "PARTITIONING_ROOT_FS"
"PARTITIONING_USE_LUKS" "PARTITIONING_USE_LUKS"
"PARTITIONING_ZFS_ENCRYPTION"
"PARTITIONING_ZFS_POOL_TYPE" "PARTITIONING_ZFS_POOL_TYPE"
"PARTITIONING_ZFS_ENCRYPTION"
"PARTITIONING_BTRFS_RAID_TYPE" "PARTITIONING_BTRFS_RAID_TYPE"
"PARTITIONING_DEVICE" "PARTITIONING_DEVICE"
"PARTITIONING_DEVICES" "PARTITIONING_DEVICES"
@ -727,7 +727,7 @@ function PARTITIONING_SCHEME_menu() {
# Set disk scheme # Set disk scheme
case "$dialog_out" in case "$dialog_out" in
"classic_single_disk") create_classic_single_disk_layout swap=8GiB type=efi luks=false root_fs=ext4 /dev/sdX ;; "classic_single_disk") create_classic_single_disk_layout swap=8GiB type=efi luks=false root_fs=ext4 /dev/sdX ;;
"zfs_centric") create_zfs_centric_layout swap=8GiB type=efi encrypt=true pool_type=stripe /dev/sdX ;; "zfs_centric") create_zfs_centric_layout swap=8GiB type=efi encrypt=true pool_type=standard /dev/sdX ;;
"btrfs_centric") create_btrfs_centric_layout swap=8GiB type=efi raid_type=raid0 luks=false /dev/sdX ;; "btrfs_centric") create_btrfs_centric_layout swap=8GiB type=efi raid_type=raid0 luks=false /dev/sdX ;;
"raid0_luks") create_raid0_luks_layout swap=8GiB type=efi root_fs=ext4 /dev/sdX /dev/sdY ;; "raid0_luks") create_raid0_luks_layout swap=8GiB type=efi root_fs=ext4 /dev/sdX /dev/sdY ;;
"custom") PARTITIONING_SCHEME="$dialog_out" ;; "custom") PARTITIONING_SCHEME="$dialog_out" ;;
@ -812,7 +812,7 @@ function PARTITIONING_USE_LUKS_menu() {
function PARTITIONING_ZFS_ENCRYPTION_tag() { echo " ├ ZFS Encryption"; } function PARTITIONING_ZFS_ENCRYPTION_tag() { echo " ├ ZFS Encryption"; }
function PARTITIONING_ZFS_ENCRYPTION_label() { on_off_label "$PARTITIONING_ZFS_ENCRYPTION" " ├ "; } function PARTITIONING_ZFS_ENCRYPTION_label() { on_off_label "$PARTITIONING_ZFS_ENCRYPTION" " ├ "; }
function PARTITIONING_ZFS_ENCRYPTION_show() { [[ $PARTITIONING_SCHEME != "custom" ]] && one_of "$PARTITIONING_SCHEME" "zfs_centric"; } function PARTITIONING_ZFS_ENCRYPTION_show() { [[ $PARTITIONING_SCHEME != "custom" ]] && one_of "$PARTITIONING_SCHEME" "zfs_centric" && one_of "$PARTITIONING_ZFS_POOL_TYPE" "standard"; }
function PARTITIONING_ZFS_ENCRYPTION_help() { echo "Determines if ZFS encryption will be used to encrypt your root partition."; } function PARTITIONING_ZFS_ENCRYPTION_help() { echo "Determines if ZFS encryption will be used to encrypt your root partition."; }
function PARTITIONING_ZFS_ENCRYPTION_menu() { function PARTITIONING_ZFS_ENCRYPTION_menu() {
on_off_toggle "PARTITIONING_ZFS_ENCRYPTION" on_off_toggle "PARTITIONING_ZFS_ENCRYPTION"
@ -822,11 +822,11 @@ function PARTITIONING_ZFS_ENCRYPTION_menu() {
function PARTITIONING_ZFS_POOL_TYPE_tag() { echo " ├ Pool type"; } function PARTITIONING_ZFS_POOL_TYPE_tag() { echo " ├ Pool type"; }
function PARTITIONING_ZFS_POOL_TYPE_label() { echo " ├ ($PARTITIONING_ZFS_POOL_TYPE)"; } function PARTITIONING_ZFS_POOL_TYPE_label() { echo " ├ ($PARTITIONING_ZFS_POOL_TYPE)"; }
function PARTITIONING_ZFS_POOL_TYPE_show() { [[ $PARTITIONING_SCHEME != "custom" ]] && one_of "$PARTITIONING_SCHEME" "zfs_centric"; } function PARTITIONING_ZFS_POOL_TYPE_show() { [[ $PARTITIONING_SCHEME != "custom" ]] && one_of "$PARTITIONING_SCHEME" "zfs_centric"; }
function PARTITIONING_ZFS_POOL_TYPE_help() { echo "Determines the pool type of the created zfs pool (stripe / mirror)."; } function PARTITIONING_ZFS_POOL_TYPE_help() { echo "Determines how the zfs pool will be initialized. Select 'standard' for a default pool setup that puts all given devices in one pool with ZSTD compression. Selecting 'custom' will require you to write your own pool creation function in the output config."; }
function PARTITIONING_ZFS_POOL_TYPE_menu() { function PARTITIONING_ZFS_POOL_TYPE_menu() {
if menu_radiolist \ if menu_radiolist \
"Select ZFS pool type" \ "Select ZFS pool type" \
"Select which ZFS pool type you want to use. By default pools are striping in ZFS." \ "Select 'standard' for a default pool setup that puts all given devices in one pool with ZSTD compression. Selecting 'custom' will require you to write your own pool creation function in the output config." \
"$PARTITIONING_ZFS_POOL_TYPE" \ "$PARTITIONING_ZFS_POOL_TYPE" \
"${PARTITIONING_ZFS_POOL_TYPES[@]}" "${PARTITIONING_ZFS_POOL_TYPES[@]}"
then then

View File

@ -15,6 +15,15 @@
# #
# Be sure to only define one layout! # Be sure to only define one layout!
# This function will be called when a custom zfs pool type has been chosen.
# $1: either 'true' or 'false' determining if the pool should be encrypted
# $2: a string describing all device paths (for error messages)
# $@: device paths
function format_zfs_custom() {
# See format_zfs_standard() function in scripts/functions.sh for an example!
die "You need to implement format_zfs_custom() in your .conf file!"
}
function disk_configuration() { function disk_configuration() {
create_classic_single_disk_layout swap=8GiB type=efi luks=true root_fs=ext4 /dev/sdX create_classic_single_disk_layout swap=8GiB type=efi luks=true root_fs=ext4 /dev/sdX

29
install
View File

@ -57,18 +57,17 @@ while [[ $# -gt 0 ]]; do
echo "be started instead." echo "be started instead."
echo "" echo ""
echo "Options:" echo "Options:"
echo " -c, --config <CONFIG> Use the given configuration file instead of the default" echo " -c, --config <CONFIG> Use the given configuration file instead of the default"
echo " location (gentoo.conf). Applies to installation as well" echo " location (gentoo.conf). Applies to installation as well"
echo " as initial configuration in case it doesn't exist." echo " as initial configuration in case it doesn't exist."
echo "" echo ""
echo "Actions:" echo "Actions:"
echo " -i, --install Installs gentoo as configured. (default if configuration exists)" echo " -i, --install Installs gentoo as configured. This is the default mode,"
echo " -R, --chroot Chroot into an existing system. The root filesystem" echo " if the given configuration file exists."
echo " is mounted automatically based on the partition" echo " -R, --chroot <DIR> [CMD...] Chroot into an existing system. The root filesystem"
echo " UUIDs (generated when installing for the first time)," echo " must already be mounted under DIR. All required special"
echo " and unmounted when the chroot exits" echo " filesystems will be mounted inside, and unmounted when"
echo " -u, --umount Try to unmount all associated mountpoints. (Only needed" echo " the chroot exits."
echo " if anything gets forcefully interrupted)"
exit 0 exit 0
;; ;;
"-c"|"--config") "-c"|"--config")
@ -80,15 +79,14 @@ while [[ $# -gt 0 ]]; do
"-R"|"--chroot") "-R"|"--chroot")
[[ -z $ACTION ]] || die "Multiple actions given" [[ -z $ACTION ]] || die "Multiple actions given"
ACTION="chroot" ACTION="chroot"
CHROOT_DIR="$2"
[[ -e "$CHROOT_DIR" ]] || die "Chroot directory not found: '$CHROOT_DIR'"
shift
;; ;;
"-i"|"--install") "-i"|"--install")
[[ -z $ACTION ]] || die "Multiple actions given" [[ -z $ACTION ]] || die "Multiple actions given"
ACTION="install" ACTION="install"
;; ;;
"-u"|"--umount"|"--unmount")
[[ -z $ACTION ]] || die "Multiple actions given"
ACTION="umount"
;;
"__install_gentoo_in_chroot") "__install_gentoo_in_chroot")
ACTION="__install_gentoo_in_chroot" ACTION="__install_gentoo_in_chroot"
;; ;;
@ -127,9 +125,8 @@ preprocess_config
mkdir_or_die 0755 "$TMP_DIR" mkdir_or_die 0755 "$TMP_DIR"
case "$ACTION" in case "$ACTION" in
"chroot") main_chroot "$@" ;; "chroot") main_chroot "$CHROOT_DIR" "$@" ;;
"install") main_install "$@" ;; "install") main_install "$@" ;;
"umount") main_umount "$@" ;;
"__install_gentoo_in_chroot") main_install_gentoo_in_chroot "$@" ;; "__install_gentoo_in_chroot") main_install_gentoo_in_chroot "$@" ;;
*) die "Invalid action '$ACTION'" ;; *) die "Invalid action '$ACTION'" ;;
esac esac

View File

@ -372,11 +372,53 @@ function disk_format() {
esac esac
} }
# This function will be called when a custom zfs pool type has been chosen.
# $1: either 'true' or 'false' determining if the pool should be encrypted
# $2: a string describing all device paths (for error messages)
# $@: device paths
function format_zfs_standard() {
local encrypt="$1"
local device_desc="$2"
shift 2
local devices=("$@")
einfo "Creating zfs pool on $devices_desc"
local extra_args=()
if [[ "$encrypt" == true ]]; then
extra_args+=(
"-O" "encryption=aes-256-gcm"
"-O" "keyformat=passphrase"
"-O" "keylocation=prompt"
)
fi
# dnodesize=legacy might be needed for GRUB2, but auto is preferred for xattr=sa.
zpool create \
-R /mnt \
-o ashift=12 \
-O acltype=posix \
-O atime=off \
-O xattr=sa \
-O dnodesize=auto \
-O mountpoint=none \
-O canmount=noauto \
-O devices=off \
-O compression=zstd \
"${extra_args[@]}" \
rpool \
"${devices[@]}" \
|| die "Could not create zfs pool on $devices_desc"
zfs create -o mountpoint=/ rpool/ROOT/default \
|| die "Could not create zfs default dataset"
zpool set bootfs=rpool/ROOT/default rpool \
|| die "Could not set zfs property bootfs on rpool"
}
function disk_format_zfs() { function disk_format_zfs() {
local ids="${arguments[ids]}" local ids="${arguments[ids]}"
local label="${arguments[label]}"
local pool_type="${arguments[pool_type]}" local pool_type="${arguments[pool_type]}"
local encrypt="${arguments[encrypt]}" local encrypt="${arguments[encrypt]-false}"
if [[ $disk_action_summarize_only == "true" ]]; then if [[ $disk_action_summarize_only == "true" ]]; then
local id local id
# Splitting is intentional here # Splitting is intentional here
@ -387,6 +429,25 @@ function disk_format_zfs() {
return 0 return 0
fi fi
local devices_desc=""
local devices=()
local id
local dev
# Splitting is intentional here
# shellcheck disable=SC2086
for id in ${ids//';'/ }; do
dev="$(resolve_device_by_id "$id")" \
|| die "Could not resolve device with id=$id"
devices+=("$dev")
devices_desc+="$dev ($id), "
done
devices_desc="${devices_desc:0:-2}"
if [[ "$pool_type" == "custom" ]]; then
format_zfs_custom "$encrypt" "$devices_desc" "${devices[@]}"
else
format_zfs_standard "$encrypt" "$devices_desc" "${devices[@]}"
fi
} }
function disk_format_btrfs() { function disk_format_btrfs() {
@ -617,7 +678,11 @@ function mount_by_id() {
} }
function mount_root() { function mount_root() {
mount_by_id "$DISK_ID_ROOT" "$ROOT_MOUNTPOINT" if [[ $USED_ZFS == "true" ]] && ! mountpoint -q -- "$ROOT_MOUNTPOINT"; then
die "Error: Expected zfs to be mounted under '$ROOT_MOUNTPOINT', but it isn't."
else
mount_by_id "$DISK_ID_ROOT" "$ROOT_MOUNTPOINT"
fi
} }
function bind_repo_dir() { function bind_repo_dir() {
@ -746,37 +811,41 @@ function touch_or_die() {
chmod "$1" "$2" chmod "$1" "$2"
} }
# $1: root directory
# $@: command...
function gentoo_chroot() { function gentoo_chroot() {
if [[ $# -eq 0 ]]; then if [[ $# -eq 1 ]]; then
gentoo_chroot /bin/bash --init-file <(echo 'init_bash') gentoo_chroot "$1" /bin/bash --init-file <(echo 'init_bash')
fi fi
[[ $EXECUTED_IN_CHROOT != "true" ]] \ [[ $EXECUTED_IN_CHROOT != "true" ]] \
|| die "Already in chroot" || die "Already in chroot"
gentoo_umount local chroot_dir="$1"
mount_root shift
# Bind repo directory to tmp
bind_repo_dir bind_repo_dir
# Copy resolv.conf # Copy resolv.conf
einfo "Preparing chroot environment" einfo "Preparing chroot environment"
install --mode=0644 /etc/resolv.conf "$ROOT_MOUNTPOINT/etc/resolv.conf" \ install --mode=0644 /etc/resolv.conf "$chroot_dir/etc/resolv.conf" \
|| die "Could not copy resolv.conf" || die "Could not copy resolv.conf"
# Mount virtual filesystems # Mount virtual filesystems
einfo "Mounting virtual filesystems" einfo "Mounting virtual filesystems"
( (
mountpoint -q -- "$ROOT_MOUNTPOINT/proc" || mount -t proc /proc "$ROOT_MOUNTPOINT/proc" || exit 1 mountpoint -q -- "$chroot_dir/proc" || mount -t proc /proc "$chroot_dir/proc" || exit 1
mountpoint -q -- "$ROOT_MOUNTPOINT/tmp" || mount --rbind /tmp "$ROOT_MOUNTPOINT/tmp" || exit 1 mountpoint -q -- "$chroot_dir/tmp" || mount --rbind /tmp "$chroot_dir/tmp" || exit 1
mountpoint -q -- "$ROOT_MOUNTPOINT/sys" || { mountpoint -q -- "$chroot_dir/sys" || {
mount --rbind /sys "$ROOT_MOUNTPOINT/sys" && mount --rbind /sys "$chroot_dir/sys" &&
mount --make-rslave "$ROOT_MOUNTPOINT/sys"; } || exit 1 mount --make-rslave "$chroot_dir/sys"; } || exit 1
mountpoint -q -- "$ROOT_MOUNTPOINT/dev" || { mountpoint -q -- "$chroot_dir/dev" || {
mount --rbind /dev "$ROOT_MOUNTPOINT/dev" && mount --rbind /dev "$chroot_dir/dev" &&
mount --make-rslave "$ROOT_MOUNTPOINT/dev"; } || exit 1 mount --make-rslave "$chroot_dir/dev"; } || exit 1
) || die "Could not mount virtual filesystems" ) || die "Could not mount virtual filesystems"
# Cache lsblk output, because apparently it doesn't work correctly in chroot (returns almost no info for devices, e.g. empty uuids) # Cache lsblk output, because it doesn't work correctly in chroot (returns almost no info for devices, e.g. empty uuids)
cache_lsblk_output cache_lsblk_output
# Execute command # Execute command
@ -784,8 +853,8 @@ function gentoo_chroot() {
EXECUTED_IN_CHROOT=true \ EXECUTED_IN_CHROOT=true \
TMP_DIR="$TMP_DIR" \ TMP_DIR="$TMP_DIR" \
CACHED_LSBLK_OUTPUT="$CACHED_LSBLK_OUTPUT" \ CACHED_LSBLK_OUTPUT="$CACHED_LSBLK_OUTPUT" \
exec chroot -- "$ROOT_MOUNTPOINT" "$GENTOO_INSTALL_REPO_DIR/scripts/dispatch_chroot.sh" "$@" \ exec chroot -- "$chroot_dir" "$GENTOO_INSTALL_REPO_DIR/scripts/dispatch_chroot.sh" "$@" \
|| die "Failed to chroot into '$ROOT_MOUNTPOINT'" || die "Failed to chroot into '$chroot_dir'"
} }
function enable_service() { function enable_service() {

View File

@ -369,15 +369,12 @@ function main_install() {
[[ $IS_EFI == "true" ]] \ [[ $IS_EFI == "true" ]] \
&& mount_efivars && mount_efivars
gentoo_chroot "$GENTOO_INSTALL_REPO_BIND/scripts/main.sh" __install_gentoo_in_chroot gentoo_chroot "$ROOT_MOUNTPOINT" "$GENTOO_INSTALL_REPO_BIND/scripts/main.sh" __install_gentoo_in_chroot
gentoo_umount gentoo_umount
} }
function main_chroot() { function main_chroot() {
gentoo_chroot "$@" gentoo_chroot "$@"
gentoo_umount einfo "Unmounting chroot environment"
}
function main_umount() {
gentoo_umount gentoo_umount
} }

View File

@ -1,4 +0,0 @@
#!/bin/bash
# virt-install
# virsh

17
tests/vm-gentoo-zfs.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
virt-install \
--connect=qemu:///system \
--name=vm-gentoo-zfs \
--vcpus=2 \
--memory=2048 \
--cdrom=/vm/images/archlinux-2021.05.01-x86_64.iso \
--disk path=/vm/disks/disk-vm-gentoo-zfs.disk,size=25 \
--graphics none \
--console pty,target.type=virtio \
--serial pty \
--extra-args 'console=ttyS0,115200n8 --- console=ttyS0,115200n8' \
--os-variant=gentoo \
--noautoconsole
# virsh