installer script: work in progress (10)

This commit is contained in:
Daniel Langbein 2021-05-02 14:28:28 +02:00
parent 28719ce647
commit eaf7fb138e
5 changed files with 103 additions and 78 deletions

View File

@ -32,7 +32,7 @@ function increase_cow_space() {
} }
function get_user_input() { function get_user_input() {
# return: the following variables: # @post
# BIOS_TYPE (uefi or bios) # BIOS_TYPE (uefi or bios)
# KERNEL (linux or linux-lts) # KERNEL (linux or linux-lts)
# FS (BTRFS, EXT4, F2FS) # FS (BTRFS, EXT4, F2FS)
@ -74,7 +74,7 @@ function get_user_input() {
} }
function get_cpu_vendor() { function get_cpu_vendor() {
# return: the following variables: # @post
# CPU_VENDOR ("amd", "intel", "none") # CPU_VENDOR ("amd", "intel", "none")
if [ -z "${CPU_VENDOR}" ]; then if [ -z "${CPU_VENDOR}" ]; then
@ -95,7 +95,9 @@ function get_cpu_vendor() {
} }
function get_default_mount_options() { function get_default_mount_options() {
# return: the following variables: # @pre
# FS
# @post
# FS_DEFAULT_MOUNT_OPTIONS (array) # FS_DEFAULT_MOUNT_OPTIONS (array)
FS_DEFAULT_MOUNT_OPTIONS=() FS_DEFAULT_MOUNT_OPTIONS=()
@ -124,7 +126,9 @@ function get_default_mount_options() {
} }
function choose_mount_options() { function choose_mount_options() {
# return: the following variables: # @pre
# FS
# @post
# FS_CHOSEN_MOUNT_OPTIONS (array) # FS_CHOSEN_MOUNT_OPTIONS (array)
case "${FS}" in case "${FS}" in
@ -153,6 +157,11 @@ function choose_mount_options() {
} }
function run_pacstrap() { function run_pacstrap() {
# @pre
# BIOS_TYPE
# KERNEL
# CPU_VENDOR
# TODO: intel/amd/none CPU_VENDOR # TODO: intel/amd/none CPU_VENDOR
case "${BIOS_TYPE}" in case "${BIOS_TYPE}" in
@ -171,6 +180,9 @@ function run_pacstrap() {
} }
function run_genfstab() { function run_genfstab() {
# @pre
# FS
local fstab local fstab
fstab="$(genfstab -U /mnt)" fstab="$(genfstab -U /mnt)"
@ -200,15 +212,30 @@ function run_genfstab() {
} }
function main() { function main() {
check_network || return $? # @pre
get_user_input || return $? # bash libraries imported
get_cpu_vendor || return $? # @post
# installation finished
check_network || return $?
# out: BIOS_TYPE, KERNEL, FS, HOSTNAME, USERNAME, USER_PWD, LUKS_PWD
get_user_input || return $?
# out: CPU_VENDOR
get_cpu_vendor || return $?
# in: FS
# out: FS_DEFAULT_MOUNT_OPTIONS
get_default_mount_options || return $? get_default_mount_options || return $?
# in: FS
# out: FS_CHOSEN_MOUNT_OPTIONS
choose_mount_options || return $? choose_mount_options || return $?
partition "${TARGET_BLOCK_DEVICE}" "$BIOS_TYPE" || return $? # in: TARGET_BLOCK_DEVICE, BIOS_TYPE
format "$BIOS_TYPE" "${BOOT_PART}" "${LUKS_PART}" "${LUKS_PWD}" "${FS}" DATA_PART || return $? # out: BOOT_PART, LUKS_PART
partition || return $?
# in: BIOS_TYPE, BOOT_PART, LUKS_PART, LUKS_PWD, FS
# out: DATA_PART
format || return $?
# Combine default and chosen mount options # Combine default and chosen mount options
TMP1=("${FS_DEFAULT_MOUNT_OPTIONS[@]}" "${FS_CHOSEN_MOUNT_OPTIONS[@]}") || return $? TMP1=("${FS_DEFAULT_MOUNT_OPTIONS[@]}" "${FS_CHOSEN_MOUNT_OPTIONS[@]}") || return $?
@ -224,6 +251,7 @@ function main() {
run_pacstrap || return $? run_pacstrap || return $?
run_genfstab || return $? run_genfstab || return $?
echo "${HOSTNAME}" >/mnt/etc/hostname || return $? echo "${HOSTNAME}" >/mnt/etc/hostname || return $?
} }

View File

@ -3,6 +3,8 @@
HOSTNAME=yodaTest HOSTNAME=yodaTest
USERNAME=arch USERNAME=arch
# one should rather enter these interactively than saving in this cfg
USER_PWD=test USER_PWD=test
LUKS_PWD=test LUKS_PWD=test

View File

@ -8,8 +8,8 @@
# -x, --sort column # -x, --sort column
function get_partitions(){ function get_partitions(){
# $1 block-device # arg $1: block-device
# return: the following variables: # @post
# PARTITIONS (array with one partition per entry) # PARTITIONS (array with one partition per entry)
# Remove first line of output (which is just the block device $1 itself) # Remove first line of output (which is just the block device $1 itself)
@ -20,7 +20,7 @@ function get_partitions(){
} }
function get_block_devices() { function get_block_devices() {
# return: the following variables: # @post
# BLOCK_DEVICES (array with one entry for each block device) # BLOCK_DEVICES (array with one entry for each block device)
# Get list of devices, one per line # Get list of devices, one per line
@ -30,7 +30,7 @@ function get_block_devices() {
} }
function get_block_devices_with_size() { function get_block_devices_with_size() {
# return: the following variables: # @post
# BLOCK_DEVICE_SIZES (array with two entries for each block device: device path and device size) # 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 # Get list of devices and their sizes, one pair per line
@ -43,18 +43,12 @@ function get_block_devices_with_size() {
function partition() { function partition() {
# $1: target block device # @pre
# $2: uefi or bios # TARGET_BLOCK_DEVICE
if [ "$#" -ne 2 ]; then # BIOS_TYPE
echo "partition requires two args!"; # @post
return 1 # BOOT_PART
fi # LUKS_PART
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 # if BOOT_PART_SIZE not given, set to default value
BOOT_PART_SIZE="${BOOT_PART_SIZE:='261'}" BOOT_PART_SIZE="${BOOT_PART_SIZE:='261'}"
@ -66,20 +60,20 @@ function partition() {
# As our data partition is encrypted, # As our data partition is encrypted,
# we need a separate boot partition! # we need a separate boot partition!
case "$2" in case "${BIOS_TYPE}" in
uefi) uefi)
# EFI boot partition # EFI boot partition
# #
# Create a partition with fat32 as the file system type and set the # Create a partition with fat32 as the file system type and set the
# esp flag on it. # esp flag on it.
parted --script "$1" -- mklabel gpt \ parted --script "${TARGET_BLOCK_DEVICE}" -- mklabel gpt \
mkpart ESP fat32 2Mib "${BOOT_PART_SIZE}MiB" \ mkpart ESP fat32 2Mib "${BOOT_PART_SIZE}MiB" \
set 1 esp on \ set 1 esp on \
mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $? mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $?
get_partitions "$1" || return $? get_partitions "${TARGET_BLOCK_DEVICE}" || return $?
BOOT_PART="${PARTITIONS[0]}" BOOT_PART="${PARTITIONS[0]}"
LUKS_PART="${PARTITIONS[1]}" LUKS_PART="${PARTITIONS[1]}"
;; ;;
bios) bios)
# > On a BIOS/GPT configuration, a BIOS boot partition is required. GRUB embeds its `core.img` # > On a BIOS/GPT configuration, a BIOS boot partition is required. GRUB embeds its `core.img`
@ -88,18 +82,18 @@ function partition() {
# #
# archwiki -> GRUB#GUID_Partition_Table_(GPT)_specific_instructions # archwiki -> GRUB#GUID_Partition_Table_(GPT)_specific_instructions
# https://www.gnu.org/software/grub/manual/grub/html_node/BIOS-installation.html#BIOS-installation # https://www.gnu.org/software/grub/manual/grub/html_node/BIOS-installation.html#BIOS-installation
parted --script "$1" -- mklabel gpt \ parted --script "${TARGET_BLOCK_DEVICE}" -- mklabel gpt \
mkpart primary 1MiB 2MiB \ mkpart primary 1MiB 2MiB \
set 1 bios_grub on \ set 1 bios_grub on \
mkpart primary 2MiB "${BOOT_PART_SIZE}MiB" \ mkpart primary 2MiB "${BOOT_PART_SIZE}MiB" \
mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $? mkpart primary "${BOOT_PART_SIZE}MiB" 100% || return $?
get_partitions "$1" || return $? get_partitions "${TARGET_BLOCK_DEVICE}" || return $?
BOOT_PART="${PARTITIONS[2]}" BOOT_PART="${PARTITIONS[2]}"
LUKS_PART="${PARTITIONS[3]}" LUKS_PART="${PARTITIONS[3]}"
;; ;;
*) *)
echo "Expected uefi or bios but got $2 instead!" echo "Expected uefi or bios but got ${BIOS_TYPE} instead!"
return 1 return 1
;; ;;
esac esac
@ -109,54 +103,53 @@ function partition() {
} }
function format() { function format() {
# $1: uefi or bios # @pre
# $2: boot partition # BIOS_TYPE
# $3: luks partition # BOOT_PART
# $4: luks passphrase # LUKS_PART
# $5: FS for data partition (opened luks partition): BTRFS, EXT4 or F2FS # LUKS_PWD
# $6: name of variable to store path to data partition (/dev/mapper/$(basename "$3")) # FS
# return: # @post
# -> boot partition formatted # DATA_PART (variable set with value /dev/mapper/$(basename "${LUKS_PART}")
# -> luks partition formatted and opened at /dev/mapper/$(basename "$3") # boot partition formatted
# -> variable with name $6 assigned to path to data partition # luks partition formatted and opened at DATA_PART
echo "Wiping old signatures from partitions ..." echo "Wiping old signatures from partitions ..."
wipefs "${2}" || return $? wipefs "${BOOT_PART}" || return $?
wipefs "${3}" || return $? wipefs "${LUKS_PART}" || return $?
echo "Formatting boot partition $2 ..." echo "Formatting boot partition ${BOOT_PART} ..."
mkfs.fat -F32 "$2" || return $? mkfs.fat -F32 "${BOOT_PART}" || return $?
echo "Creating encrypted luks partition $3 ..." echo "Creating encrypted luks partition ${LUKS_PART} ..."
printf "%s" "$4" | cryptsetup luksFormat --type luks1 \ printf "%s" "${LUKS_PWD}" | cryptsetup luksFormat --type luks1 \
--cipher aes-xts-plain64 --key-size 512 --hash sha512 \ --cipher aes-xts-plain64 --key-size 512 --hash sha512 \
--iter-time 3500 --use-random "$3" || return $? --iter-time 10000 --use-random "${LUKS_PART}" || return $?
local luks_name local luks_name
luks_name=$(basename "$3") luks_name=$(basename "${LUKS_PART}")
local -n data_part=$6 || return $? DATA_PART="/dev/mapper/${luks_name}"
data_part="/dev/mapper/${luks_name}"
# open luks partition # open luks partition
printf "%s" "$4" | cryptsetup luksOpen "$3" "${luks_name}" || return $? printf "%s" "${LUKS_PWD}" | cryptsetup luksOpen "${LUKS_PART}" "${luks_name}" || return $?
echo "Formatting the data partition ${data_part} ..." echo "Formatting the data partition ${DATA_PART} ..."
case "$5" in case "${FS}" in
BTRFS) BTRFS)
mkfs.btrfs "${data_part}" || return $? mkfs.btrfs "${DATA_PART}" || return $?
;; ;;
EXT4) EXT4)
# archwiki -> Ext4#Enabling_metadata_checksums # archwiki -> Ext4#Enabling_metadata_checksums
mkfs.ext4 -O metadata_csum "${data_part}" || return $? mkfs.ext4 -O metadata_csum "${DATA_PART}" || return $?
;; ;;
F2FS) F2FS)
# archwiki -> F2FS#Creating_a_F2FS_file_system # archwiki -> F2FS#Creating_a_F2FS_file_system
# - requires f2fs-tools # - requires f2fs-tools
# - compression: "-O compression" and when mounting the filesystem, specify compress_algorithm=(lzo|lz4|zstd|lzo-rle) # - 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 $? mkfs.f2fs -O extra_attr,inode_checksum,sb_checksum,compression "${DATA_PART}" || return $?
;; ;;
*) *)
echo "Filesystem $5 is not yet supported!" echo "Filesystem ${FS} is not yet supported!"
return 1 return 1
;; ;;
esac esac

View File

@ -3,8 +3,8 @@ function get_text_input {
# Only one line user input is allowed. # Only one line user input is allowed.
# User input must not be empty. # User input must not be empty.
# #
# $1: name of variable to store user input # arg $1: name of variable to store user input
# $2: text to display (e.g. "Enter hostname:") # arg $2: text to display (e.g. "Enter hostname:")
if [ "$#" -ne 2 ]; then if [ "$#" -ne 2 ]; then
echo "get_text_input requires two args!"; echo "get_text_input requires two args!";
return 1 return 1
@ -33,9 +33,9 @@ function get_text_input {
function get_single_choice { function get_single_choice {
# If variable with name $1 is zero, then ask user to select one option. # If variable with name $1 is zero, then ask user to select one option.
# #
# $1: name of variable to store the selected option # arg $1: name of variable to store the selected option
# $2: text to display # arg $2: text to display
# $3: name of variable with array of options to display (for each option there must be two entries in the array: Item and description) # arg $3: name of variable with array of options to display (for each option there must be two entries in the array: Item and description)
if [ "$#" -ne 3 ]; then if [ "$#" -ne 3 ]; then
echo "get_single_choice requires three args!"; echo "get_single_choice requires three args!";
return 1 return 1
@ -64,9 +64,9 @@ function get_single_choice {
function get_multi_choice { function get_multi_choice {
# If variable with name $1 is zero, then ask user to select one ore more options. # If variable with name $1 is zero, then ask user to select one ore more options.
# #
# $1: name of variable to store array of selected options # arg $1: name of variable to store array of selected options
# $2: text to display # arg $2: text to display
# $3: name of variable with array of options to display (for each option there must be three entries in the array: Item, description, on/off) # arg $3: name of variable with array of options to display (for each option there must be three entries in the array: Item, description, on/off)
if [ "$#" -ne 3 ]; then if [ "$#" -ne 3 ]; then
echo "get_multi_choice requires three args!"; echo "get_multi_choice requires three args!";
return 1 return 1

View File

@ -1,8 +1,9 @@
function join_by() { function join_by() {
# Join array elements with character $1 # Join array elements with character $1
# $1: delimiter #
# $2: name of source array # arg $1: delimiter
# $3: variable name to store result # arg $2: name of source array
# arg $3: variable name to store result
local -n ptr=$2 || return $? local -n ptr=$2 || return $?
local -n ptr2=$3 || return $? local -n ptr2=$3 || return $?
@ -12,7 +13,8 @@ function join_by() {
function newline_to_space() { function newline_to_space() {
# Replaces all newlines with spaces # Replaces all newlines with spaces
# $1: name of variable #
# arg $1: name of variable
local -n ptr=$1 || return $? local -n ptr=$1 || return $?
# Replace newlines with spaces # Replace newlines with spaces
@ -27,8 +29,8 @@ function newline_separated_to_array() {
# Watch out for tailing newlines as these will get an empty array entry at the end. # Watch out for tailing newlines as these will get an empty array entry at the end.
# $1 and $2 can be equal (if the result shall be written to the input variable) # $1 and $2 can be equal (if the result shall be written to the input variable)
# #
# $1: name of variable with newline separated list # arg $1: name of variable with newline separated list
# $2: name of array to store values into # arg $2: name of array to store values into
local -n ptr=$1 || return $? local -n ptr=$1 || return $?
local -n ptr2=$2 || return $? local -n ptr2=$2 || return $?
@ -38,8 +40,8 @@ function newline_separated_to_array() {
} }
function space_separated_to_array() { function space_separated_to_array() {
# $1: name of variable with space separated list # arg $1: name of variable with space separated list
# $2: name of array to store values into # arg $2: name of array to store values into
local -n ptr=$1 || return $? local -n ptr=$1 || return $?
local -n ptr2=$2 || return $? local -n ptr2=$2 || return $?