# # lsblk # # -d, --nodeps Do not print holder devices or slaves. # -p, --paths Print full device paths. # -l, --list Produce output in the form of a list. # -n, --noheadings # -x, --sort column function get_partitions(){ # $1 block-device # return: the following variables: # PARTITIONS (array with one partition per entry) # Remove first line of output (which is just the block device $1 itself) # with sed: sed 1d PARTITIONS="$(lsblk -pln -o name "$1" | sed 1d)" || return $? newline_separated_to_array PARTITIONS PARTITIONS || return $? } function get_block_devices() { # return: the following variables: # BLOCK_DEVICES (array with one entry for each block device) # Get list of devices, one per line BLOCK_DEVICES="$(lsblk -dplnx size -o name | grep -Ev "boot|rpmb|loop" | tac)" || return $? newline_separated_to_array BLOCK_DEVICES BLOCK_DEVICES || return $? } function get_block_devices_with_size() { # return: the following variables: # BLOCK_DEVICE_SIZES (array with two entries for each block device: device path and device size) # Get list of devices and their sizes, one pair per line # Use sed to remove multiple white spaces: sed 's|\s\s*| |' BLOCK_DEVICE_SIZES="$(lsblk -dplnx size -o name,size | grep -Ev "boot|rpmb|loop" | sed 's|\s\s*| |' | tac)" || return $? newline_to_space BLOCK_DEVICE_SIZES || return $? space_separated_to_array BLOCK_DEVICE_SIZES BLOCK_DEVICE_SIZES || return $? } function partition() { # $1: target block device # $2: uefi or bios if [ "$#" -ne 2 ]; then echo "partition requires two args!"; return 1 fi for i in "$@"; do if [ -z "$i" ]; then echo "partition: all given args must not be empty"; return 1; fi done # if BOOT_PART_SIZE not given, set to default value BOOT_PART_SIZE="${BOOT_PART_SIZE:='261'}" # if too small, print warning and exit if [ "${BOOT_PART_SIZE}" -lt "261" ]; then echo "BOOT_PART_SIZE should be larger than 260!"; return 1; fi # As our data partition is encrypted, # we need a separate boot partition! case "$2" in uefi) # EFI boot partition # # Create a partition with fat32 as the file system type and set the # esp flag on it. parted --script "$1" -- mklabel gpt \ mkpart ESP fat32 2Mib "${BOOT_PART_SIZE}MiB" \ set 1 esp on \ mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $? get_partitions "$1" || return $? BOOT_PART="${PARTITIONS[0]}" LUKS_PART="${PARTITIONS[1]}" ;; bios) # > On a BIOS/GPT configuration, a BIOS boot partition is required. GRUB embeds its `core.img` # > into this partition. # > For parted set/activate the flag bios_grub on the partition. # # archwiki -> GRUB#GUID_Partition_Table_(GPT)_specific_instructions # https://www.gnu.org/software/grub/manual/grub/html_node/BIOS-installation.html#BIOS-installation parted --script "$1" -- mklabel gpt \ mkpart primary 1MiB 2MiB \ set 1 bios_grub on \ mkpart primary 2MiB "${BOOT_PART_SIZE}MiB" \ mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $? get_partitions "$1" || return $? BOOT_PART="${PARTITIONS[2]}" LUKS_PART="${PARTITIONS[3]}" ;; *) echo "Expected uefi or bios but got $2 instead!" return 1 ;; esac echo "boot partition: ${BOOT_PART}" echo "luks partition: ${LUKS_PART}" } function format() { # $1: uefi or bios # $2: boot partition # $3: luks partition # $4: luks passphrase # $5: FS for data partition (opened luks partition): BTRFS, EXT4 or F2FS # $6: name of variable to store path to data partition (/dev/mapper/$(basename "$3")) # return: # -> boot partition formatted # -> luks partition formatted and opened at /dev/mapper/$(basename "$3") # -> variable with name $6 assigned to path to data partition echo "Wiping old signatures from partitions ..." wipefs "${2}" || return $? wipefs "${3}" || return $? echo "Formatting boot partition $2 ..." mkfs.fat -F32 "$2" || return $? echo "Creating encrypted luks partition $3 ..." printf "%s" "$4" | cryptsetup luksFormat --type luks1 \ --cipher aes-xts-plain64 --key-size 512 --hash sha512 \ --iter-time 3500 --use-random "$3" || return $? local luks_name luks_name=$(basename "$3") local -n data_part=$6 || return $? data_part="/dev/mapper/${luks_name}" # open luks partition printf "%s" "$4" | cryptsetup luksOpen "$3" "${luks_name}" || return $? echo "Formatting the data partition ${data_part} ..." case "$5" in BTRFS) mkfs.btrfs "${data_part}" || return $? ;; EXT4) # archwiki -> Ext4#Enabling_metadata_checksums mkfs.ext4 -O metadata_csum "${data_part}" || return $? ;; F2FS) # archwiki -> F2FS#Creating_a_F2FS_file_system # - requires f2fs-tools # - compression: "-O compression" and when mounting the filesystem, specify compress_algorithm=(lzo|lz4|zstd|lzo-rle) mkfs.f2fs -O extra_attr,inode_checksum,sb_checksum,compression "${data_part}" || return $? ;; *) echo "Filesystem $5 is not yet supported!" return 1 ;; esac }