diff --git a/scripts/config.sh b/scripts/config.sh index 07de346..72a4ef8 100644 --- a/scripts/config.sh +++ b/scripts/config.sh @@ -9,20 +9,21 @@ source "$GENTOO_INSTALL_REPO_DIR/scripts/internal_config.sh" || exit 1 create_default_disk_layout() { local device="$1" - create_partition new_id=part_efi device="$device" size=128MiB type=efi - create_partition new_id=part_swap device="$device" size=8GiB type=raid - create_partition new_id=part_root device="$device" size=auto type=raid + create_gpt new_id=gpt device="$device" + create_partition new_id=part_efi id=gpt size=128MiB type=efi + create_partition new_id=part_swap id=gpt size=8GiB type=raid + create_partition new_id=part_root id=gpt size=auto type=raid format id=part_efi type=efi label=efi format id=part_swap type=swap label=swap format id=part_root type=ext4 label=ext4 - set_efi id=part_efi - set_swap id=part_swap - set_root id=part_root + DISK_ID_EFI=part_efi + DISK_ID_SWAP=part_raid + DISK_ID_ROOT=part_luks } -create_default_disk_layout +create_default_disk_layout /dev/sdX # Example 2: Multiple disks, with raid 0 and luks @@ -31,23 +32,23 @@ create_default_disk_layout # - root: raid 0 → luks → fs devices=(/dev/sd{X,Y}) for i in "${!devices[@]}"; do - device="${devices[$i]}" - create_partition new_id="part_efi_dev${i}" device="$device" size=128MiB type=efi - create_partition new_id="part_swap_dev${i}" device="$device" size=8GiB type=raid - create_partition new_id="part_root_dev${i}" device="$device" size=auto type=raid + create_gpt new_id="gpt_dev${i}" device="${devices[$i]}" + create_partition new_id="part_efi_dev${i}" id="gpt_dev${i}" size=128MiB type=efi + create_partition new_id="part_swap_dev${i}" id="gpt_dev${i}" size=8GiB type=raid + create_partition new_id="part_root_dev${i}" id="gpt_dev${i}" size=auto type=raid done -create_raid new_id=part_raid_swap level=0 ids="${part_swap_dev*}" -create_raid new_id=part_raid_root level=0 ids="${part_root_dev*}" +create_raid new_id=part_raid_swap level=0 ids="$(expand_ids '^part_swap_dev\d$')" +create_raid new_id=part_raid_root level=0 ids="$(expand_ids '^part_root_dev\d$')" create_luks new_id=part_luks_root id=part_raid_root format id=part_efi_dev0 type=efi label=efi format id=part_raid_swap type=swap label=swap format id=part_luks_root type=ext4 label=ext4 -set_efi id=part_efi_dev0 -set_swap id=part_raid_swap -set_root id=part_luks_root +DISK_ID_EFI=part_efi_dev0 +DISK_ID_SWAP=part_raid_swap +DISK_ID_ROOT=part_luks_root ################################################ diff --git a/scripts/functions.sh b/scripts/functions.sh index b32eb0a..7d71bf9 100644 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -21,18 +21,23 @@ sync_time() { } check_config() { - [[ "$KEYMAP" =~ ^[0-9A-Za-z-]*$ ]] \ + [[ $KEYMAP =~ ^[0-9A-Za-z-]*$ ]] \ || die "KEYMAP contains invalid characters" # Check hostname per RFC1123 local hostname_regex='^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$' - [[ "$HOSTNAME" =~ $hostname_regex ]] \ + [[ $HOSTNAME =~ $hostname_regex ]] \ || die "'$HOSTNAME' is not a valid hostname" - if [[ "$INSTALL_ANSIBLE" == true ]]; then - [[ "$INSTALL_SSHD" == true ]] \ + [[ -n $DISK_ID_ROOT ]] \ + || die "You must assign DISK_ID_ROOT" + [[ -n $DISK_ID_EFI ]] || [[ -n $DISK_ID_BOOT ]] \ + || die "You must assign DISK_ID_EFI or DISK_ID_BOOT" + + if [[ $INSTALL_ANSIBLE == true ]]; then + [[ $INSTALL_SSHD == true ]] \ || die "You must enable INSTALL_SSHD for ansible" - [[ -n "$ANSIBLE_SSH_AUTHORIZED_KEYS" ]] \ + [[ -n $ANSIBLE_SSH_AUTHORIZED_KEYS ]] \ || die "Missing pubkey for ansible user" fi } @@ -53,9 +58,224 @@ prepare_installation_environment() { check_has_program uuidgen check_has_program wget + [[ $USED_RAID == true ]] \ + && check_has_program mdadm + [[ $USED_LUKS == true ]] \ + && check_has_program cryptsetup + sync_time } +add_summary_entry() { + local parent="$1" + local id="$2" + local name="$3" + local hint="$4" + local desc="$5" + + local ptr + case "$id" in + "$DISK_ID_BOOT") ptr="← boot" ;; + "$DISK_ID_EFI") ptr="← efi" ;; + "$DISK_ID_SWAP") ptr="← swap" ;; + "$DISK_ID_ROOT") ptr="← root" ;; + # \x1f characters compensate for printf byte count and unicode character count mismatch due to '←' + *) ptr="$(echo -e "\x1f\x1f")" ;; + esac + + summary_tree[$parent]+=";$id" + summary_name[$id]="$name" + summary_hint[$id]="$hint" + summary_ptr[$id]="$ptr" + summary_desc[$id]="$desc" +} + +summary_color_args() { + for arg in "$@"; do + if [[ -v "arguments[$arg]" ]]; then + printf '%-28s ' "$arg=${arguments[$arg]}" + fi + done +} + +disk_create_gpt() { + if [[ $disk_action_summarize_only == true ]]; then + if [[ -v arguments[id] ]]; then + add_summary_entry "${arguments[id]}" "${arguments[new_id]}" "gpt" "" "" + else + add_summary_entry __root__ "${arguments[new_id]}" "${arguments[device]}" "(gpt)" "" + fi + return 0 + fi +} + +disk_create_partition() { + if [[ $disk_action_summarize_only == true ]]; then + add_summary_entry "${arguments[id]}" "${arguments[new_id]}" "part" "(${arguments[type]})" "$(summary_color_args size)" + return 0 + fi +} + +disk_create_raid() { + if [[ $disk_action_summarize_only == true ]]; then + local id + # Splitting is intentional here + # shellcheck disable=SC2086 + for id in ${arguments[ids]//';'/ }; do + add_summary_entry "$id" "_${arguments[new_id]}" "raid${arguments[level]}" "" "" + done + + add_summary_entry __root__ "${arguments[new_id]}" "raid${arguments[level]}" "" "" + return 0 + fi +} + +disk_create_luks() { + if [[ $disk_action_summarize_only == true ]]; then + add_summary_entry "${arguments[id]}" "${arguments[new_id]}" "luks" "" "" + return 0 + fi +} + +disk_format() { + if [[ $disk_action_summarize_only == true ]]; then + add_summary_entry "${arguments[id]}" "__fs__${arguments[id]}" "${arguments[type]}" "(fs)" "$(summary_color_args label)" + return 0 + fi +} + +apply_disk_action() { + unset known_arguments + unset arguments; declare -A arguments; parse_arguments "$@" + case "${arguments[action]}" in + 'create_gpt') disk_create_gpt ;; + 'create_partition') disk_create_partition ;; + 'create_raid') disk_create_raid ;; + 'create_luks') disk_create_luks ;; + 'format') disk_format ;; + *) echo "Ignoring invalid action: ${arguments[action]}" ;; + esac +} + +print_summary_tree_entry() { + local indent_chars="" + local indent="0" + local d="1" + local maxd="$((depth - 1))" + while [[ $d -lt $maxd ]]; do + if [[ ${summary_depth_continues[$d]} == true ]]; then + indent_chars+='│ ' + else + indent_chars+=' ' + fi + indent=$((indent + 2)) + d="$((d + 1))" + done + if [[ $maxd -gt 0 ]]; then + if [[ ${summary_depth_continues[$maxd]} == true ]]; then + indent_chars+='├─' + else + indent_chars+='└─' + fi + indent=$((indent + 2)) + fi + + local name="${summary_name[$root]}" + local hint="${summary_hint[$root]}" + local desc="${summary_desc[$root]}" + local ptr="${summary_ptr[$root]}" + local id_name="" + if [[ $root != __* ]]; then + if [[ $root == _* ]]; then + id_name="${root:1}" + else + id_name="${root}" + fi + fi + + local align=0 + if [[ $indent -lt 33 ]]; then + align="$((33 - indent))" + fi + + elog "$indent_chars$(printf "%-${align}s %-47s %s" \ + "$name $hint" \ + "$id_name $ptr" \ + "$desc")" +} + +print_summary_tree() { + local root="$1" + local depth="$((depth + 1))" + local has_children=false + + if [[ -v "summary_tree[$root]" ]]; then + local children="${summary_tree[$root]}" + has_children=true + summary_depth_continues[$depth]=true + else + summary_depth_continues[$depth]=false + fi + + if [[ $root != __root__ ]]; then + print_summary_tree_entry "$root" + fi + + if [[ $has_children == true ]]; then + local count="$(tr ';' '\n' <<< "$children" | grep -c '\S')" + local idx=0 + # Splitting is intentional here + # shellcheck disable=SC2086 + for id in ${children//';'/ }; do + idx="$((idx + 1))" + [[ $idx == "$count" ]] \ + && summary_depth_continues[$depth]=false + print_summary_tree "$id" + # separate blocks by newline + [[ ${summary_depth_continues[0]} == true ]] && [[ $depth == 1 ]] && [[ $idx == "$count" ]] \ + && elog + done + fi +} + +summarize_disk_actions() { + elog "Current lsblk output" + for_line_in <(lsblk \ + || die "Error in lsblk") elog + + disk_action_summarize_only=true + declare -A summary_tree + declare -A summary_name + declare -A summary_hint + declare -A summary_ptr + declare -A summary_desc + declare -A summary_depth_continues + apply_disk_actions + unset disk_action_summarize_only + + local depth=-1 + elog + elog "Configured disk layout" + elog ──────────────────────────────────────────────────────────────────────────────── + elog "$(printf '%-26s %-28s %s' NODE ID OPTIONS)" + elog ──────────────────────────────────────────────────────────────────────────────── + print_summary_tree __root__ + elog ──────────────────────────────────────────────────────────────────────────────── +} + +apply_disk_actions() { + local param + local current_params=() + for param in "${DISK_ACTIONS[@]}"; do + if [[ $param == ';' ]]; then + apply_disk_action "${current_params[@]}" + current_params=() + else + current_params+=("$param") + fi + done +} + partition_device_print_config_summary() { elog "-------- Partition configuration --------" elog "Device: $PARTITION_DEVICE" @@ -65,22 +285,22 @@ partition_device_print_config_summary() { elog "New partition table:" elog "$PARTITION_DEVICE" elog "├─efi size=$PARTITION_EFI_SIZE" - if [[ "$ENABLE_SWAP" == true ]]; then + if [[ $ENABLE_SWAP == true ]]; then elog "├─swap size=$PARTITION_SWAP_SIZE" fi elog "└─linux size=[remaining]" - if [[ "$ENABLE_SWAP" != true ]]; then + if [[ $ENABLE_SWAP != true ]]; then elog "swap: disabled" fi } partition_device() { - [[ "$ENABLE_PARTITIONING" == true ]] \ + [[ $ENABLE_PARTITIONING == true ]] \ || return 0 einfo "Preparing partitioning of device '$PARTITION_DEVICE'" - [[ -b "$PARTITION_DEVICE" ]] \ + [[ -b $PARTITION_DEVICE ]] \ || die "Selected device '$PARTITION_DEVICE' is not a block device" partition_device_print_config_summary @@ -99,7 +319,7 @@ partition_device() { || die "Could not create efi partition" # Create swap partition - if [[ "$ENABLE_SWAP" == true ]]; then + if [[ $ENABLE_SWAP == true ]]; then sgdisk -n "0:0:+$PARTITION_SWAP_SIZE" -t 0:8200 -c 0:"swap" -u 0:"$PARTITION_UUID_SWAP" "$PARTITION_DEVICE" >/dev/null \ || die "Could not create swap partition" fi @@ -119,15 +339,15 @@ partition_device() { } format_partitions() { - [[ "$ENABLE_FORMATTING" == true ]] \ + [[ $ENABLE_FORMATTING == true ]] \ || return 0 - if [[ "$ENABLE_PARTITIONING" != true ]]; then + if [[ $ENABLE_PARTITIONING != true ]]; then einfo "Preparing to format the following partitions:" blkid -t PARTUUID="$PARTITION_UUID_EFI" \ || die "Error while listing efi partition" - if [[ "$ENABLE_SWAP" == true ]]; then + if [[ $ENABLE_SWAP == true ]]; then blkid -t PARTUUID="$PARTITION_UUID_SWAP" \ || die "Error while listing swap partition" fi @@ -148,7 +368,7 @@ format_partitions() { mkfs.fat -F 32 -n "efi" "$dev" \ || die "Could not format EFI partition" - if [[ "$ENABLE_SWAP" == true ]]; then + if [[ $ENABLE_SWAP == true ]]; then dev="$(get_device_by_partuuid "$PARTITION_UUID_SWAP")" \ || die "Could not resolve partition UUID '$PARTITION_UUID_SWAP'" einfo " $dev (swap)" @@ -235,7 +455,7 @@ download_stage3() { CURRENT_STAGE3_VERIFIED="${CURRENT_STAGE3}.verified" # Download file if not already downloaded - if [[ -e "$CURRENT_STAGE3_VERIFIED" ]]; then + if [[ -e $CURRENT_STAGE3_VERIFIED ]]; then einfo "$STAGE3_BASENAME tarball already downloaded and verified" else einfo "Downloading $STAGE3_BASENAME tarball" @@ -312,6 +532,7 @@ env_update() { } mkdir_or_die() { + # shellcheck disable=SC2174 mkdir -m "$1" -p "$2" \ || die "Could not create directory '$2'" } diff --git a/scripts/internal_config.sh b/scripts/internal_config.sh index 3cb9103..150c4a6 100644 --- a/scripts/internal_config.sh +++ b/scripts/internal_config.sh @@ -17,6 +17,11 @@ UUID_STORAGE_DIR="$TMP_DIR/uuids" # The desired efi partition mountpoint for the actual system EFI_MOUNTPOINT="/boot/efi" +# Flag to track usage of raid (needed to check for mdadm existence) +USED_RAID=false +# Flag to track usage of luks (needed to check for cryptsetup existence) +USED_LUKS=false + # An array of disk related actions to perform DISK_ACTIONS=() # An associative set to check for existing ids @@ -26,8 +31,8 @@ only_one_of() { local previous="" local a for a in "$@"; do - if [[ -v "arguments[$a]" ]]; then - if [[ -z "$previous" ]]; then + if [[ -v arguments[$a] ]]; then + if [[ -z $previous ]]; then previous="$a" else die_trace 2 "Only one of the arguments ($*) can be given" @@ -38,30 +43,36 @@ only_one_of() { create_new_id() { local id="${arguments[$1]}" - [[ ! -v "DISK_KNOWN_IDS[$id]" ]] \ + [[ $id == *';'* ]] \ + && die_trace 2 "Identifier contains invalid character ';'" + [[ ! -v DISK_KNOWN_IDS[$id] ]] \ || die_trace 2 "Identifier '$id' already exists" DISK_KNOWN_IDS[$id]=true } verify_existing_id() { local id="${arguments[$1]}" - [[ -v "DISK_KNOWN_IDS[$id]" ]] \ + [[ -v DISK_KNOWN_IDS[$id] ]] \ || die_trace 2 "Identifier $1='$id' not found" } verify_existing_unique_ids() { - local ids="${arguments[$1]}" + local arg="$1" + local ids="${arguments[$arg]}" - count_orig="$(tr ' ' '\n' <<< "$ids" | wc -l)" - count_uniq="$(tr ' ' '\n' <<< "$ids" | sort -u | wc -l)" - [[ "$count_orig" -eq "$count_uniq" ]] \ - || die_trace 2 "$1=... contains duplicate identifiers" + count_orig="$(tr ';' '\n' <<< "$ids" | grep -c '\S')" + count_uniq="$(tr ';' '\n' <<< "$ids" | grep '\S' | sort -u | wc -l)" + [[ $count_orig -gt 0 ]] \ + || die_trace 2 "$arg=... must contain at least one entry" + [[ $count_orig -eq $count_uniq ]] \ + || die_trace 2 "$arg=... contains duplicate identifiers" - local i + local id # Splitting is intentional here - for i in $ids; do # shellcheck disable=SC2068 - [[ -v "DISK_KNOWN_IDS[$i]" ]] \ - || die_trace 2 "$1=... contains unknown identifier '$i'" + # shellcheck disable=SC2086 + for id in ${ids//';'/ }; do + [[ -v DISK_KNOWN_IDS[$id] ]] \ + || die_trace 2 "$arg=... contains unknown identifier '$id'" done } @@ -72,7 +83,7 @@ verify_option() { local arg="${arguments[$opt]}" local i for i in "$@"; do - [[ "$i" == "$arg" ]] \ + [[ $i == "$arg" ]] \ && return 0 done @@ -92,31 +103,43 @@ verify_option() { #} # Named arguments: -# new_id: Id for the new partition -# size: Size for the new partition, or auto to allocate the rest -# type: The parition type, either (efi, swap, raid, luks, linux) (or a 4 digit hex-code for gdisk). -# [one of] -# device: The operand block device -# id: The operand device id -create_partition() { - local known_arguments=('+new_id' '+device|id' '+size' '+type') +# new_id: Id for the new gpt table +# device: The operand block device +create_gpt() { + local known_arguments=('+new_id' '+device|id') unset arguments; declare -A arguments; parse_arguments "$@" only_one_of device id create_new_id new_id - verify_option type efi swap raid luks linux - - [[ -v "arguments[id]" ]] \ + [[ -v arguments[id] ]] \ && verify_existing_id id - DISK_ACTIONS+=("action=create_partition" "$@") + DISK_ACTIONS+=("action=create_gpt" "$@" ";") +} + +# Named arguments: +# new_id: Id for the new partition +# size: Size for the new partition, or auto to allocate the rest +# type: The parition type, either (boot, efi, swap, raid, luks, linux) (or a 4 digit hex-code for gdisk). +# id: The operand device id +create_partition() { + local known_arguments=('+new_id' '+id' '+size' '+type') + unset arguments; declare -A arguments; parse_arguments "$@" + + create_new_id new_id + verify_existing_id id + verify_option type boot efi swap raid luks linux + + DISK_ACTIONS+=("action=create_partition" "$@" ";") } # Named arguments: # new_id: Id for the new raid # level: Raid level -# ids: Ids of all member devices +# ids: Comma separated list of all member ids create_raid() { + USED_RAID=true + local known_arguments=('+new_id' '+level' '+ids') unset arguments; declare -A arguments; parse_arguments "$@" @@ -124,36 +147,43 @@ create_raid() { verify_option level 0 1 5 6 verify_existing_unique_ids ids - DISK_ACTIONS+=("action=create_raid" "$@") + DISK_ACTIONS+=("action=create_raid" "$@" ";") } # Named arguments: # new_id: Id for the new luks -# [one of] -# device: The operand block device -# id: The operand device id +# id: The operand device id create_luks() { - local known_arguments=('+new_id' '+device|id') + USED_LUKS=true + + local known_arguments=('+new_id' '+id') unset arguments; declare -A arguments; parse_arguments "$@" create_new_id new_id - only_one_of device id - [[ -v "arguments[id]" ]] \ - && verify_existing_id id + verify_existing_id id - DISK_ACTIONS+=("action=create_luks" "$@") + DISK_ACTIONS+=("action=create_luks" "$@" ";") } # Named arguments: # id: Id of the device / partition created earlier -# type: One of (efi, swap, ext4) +# type: One of (boot, efi, swap, ext4) # label: The label for the formatted disk format() { - local known_arguments=('+id' '+type') + local known_arguments=('+id' '+type' '?label') unset arguments; declare -A arguments; parse_arguments "$@" verify_existing_id id - verify_option type efi swap ext4 + verify_option type boot efi swap ext4 - DISK_ACTIONS+=("action=format" "$@") + DISK_ACTIONS+=("action=format" "$@" ";") +} + +# Returns a comma separated list of all registered ids matching the given regex. +expand_ids() { + local regex="$1" + for id in "${!DISK_KNOWN_IDS[@]}"; do + [[ $id =~ $regex ]] \ + && echo -n "$id;" + done } diff --git a/scripts/main.sh b/scripts/main.sh index 1415997..6f26718 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -7,11 +7,11 @@ set -uo pipefail # Find the directory this script is stored in. (from: http://stackoverflow.com/questions/59895) get_source_dir() { local source="${BASH_SOURCE[0]}" - while [[ -h "${source}" ]] + while [[ -h $source ]] do local tmp="$(cd -P "$(dirname "${source}")" && pwd)" source="$(readlink "${source}")" - [[ "${source}" != /* ]] && source="${tmp}/${source}" + [[ $source != /* ]] && source="${tmp}/${source}" done echo -n "$(realpath "$(dirname "${source}")")" @@ -128,7 +128,7 @@ install_ansible() { mkdir_or_die 0700 "$ANSIBLE_HOME" mkdir_or_die 0700 "$ANSIBLE_HOME/.ssh" - if [[ -n "$ANSIBLE_SSH_AUTHORIZED_KEYS" ]]; then + if [[ -n $ANSIBLE_SSH_AUTHORIZED_KEYS ]]; then einfo "Adding authorized keys for ansible" touch_or_die 0600 "$ANSIBLE_HOME/.ssh/authorized_keys" echo "$ANSIBLE_SSH_AUTHORIZED_KEYS" >> "$ANSIBLE_HOME/.ssh/authorized_keys" \ @@ -194,7 +194,7 @@ main_install_gentoo_in_chroot() { || die "Could not append entry to fstab" echo "PARTUUID=$PARTITION_UUID_EFI /boot/efi vfat defaults,noatime,fmask=0022,dmask=0022,noexec,nodev,nosuid,discard 0 2" >> /etc/fstab \ || die "Could not append entry to fstab" - if [[ "$ENABLE_SWAP" == true ]]; then + if [[ $ENABLE_SWAP == true ]]; then echo "PARTUUID=$PARTITION_UUID_SWAP none swap defaults,discard 0 0" >> /etc/fstab \ || die "Could not append entry to fstab" fi @@ -204,7 +204,7 @@ main_install_gentoo_in_chroot() { try emerge --verbose app-portage/gentoolkit # Install and enable sshd - if [[ "$INSTALL_SSHD" == true ]]; then + if [[ $INSTALL_SSHD == true ]]; then install_sshd fi @@ -215,13 +215,14 @@ main_install_gentoo_in_chroot() { || die "Could not add dhcpcd to default services" # Install ansible - if [[ "$INSTALL_ANSIBLE" == true ]]; then + if [[ $INSTALL_ANSIBLE == true ]]; then install_ansible fi # Install additional packages, if any. - if [[ -n "$ADDITIONAL_PACKAGES" ]]; then + if [[ -n $ADDITIONAL_PACKAGES ]]; then einfo "Installing additional packages" + # shellcheck disable=SC2086 try emerge --verbose --autounmask-continue=y -- $ADDITIONAL_PACKAGES fi @@ -264,7 +265,7 @@ main_umount() { trap 'kill "$GENTOO_INSTALL_REPO_SCRIPT_PID"' INT SCRIPT_ALIAS="$(basename "$0")" -if [[ "$SCRIPT_ALIAS" == "main.sh" ]]; then +if [[ $SCRIPT_ALIAS == main.sh ]]; then SCRIPT_ALIAS="$1" shift fi diff --git a/scripts/main_chroot.sh b/scripts/main_chroot.sh index 9de21cc..74e52d2 100755 --- a/scripts/main_chroot.sh +++ b/scripts/main_chroot.sh @@ -1,7 +1,7 @@ #!/bin/bash set -uo pipefail -[[ "${EXECUTED_IN_CHROOT}" != true ]] \ +[[ ${EXECUTED_IN_CHROOT} != true ]] \ && { echo "This script must not be executed directly!" >&2; exit 1; } # Source the systems profile @@ -12,7 +12,7 @@ umask 0077 # Export nproc variables export NPROC="$(nproc || echo 2)" -export NPROC_ONE="$(($NPROC + 1))" +export NPROC_ONE="$((NPROC + 1))" # Set default makeflags and emerge flags for parallel emerges export MAKEFLAGS="-j$NPROC" diff --git a/scripts/utils.sh b/scripts/utils.sh index 73963b2..b73770f 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -32,7 +32,7 @@ die_trace() { } for_line_in() { - while IFS="" read -r line || [[ -n "$line" ]]; do + while IFS="" read -r line || [[ -n $line ]]; do "$2" "$line" done <"$1" } @@ -68,7 +68,7 @@ try() { "$@" cmd_status="$?" - if [[ "$cmd_status" != 0 ]]; then + if [[ $cmd_status != 0 ]]; then echo " * Command failed: \$ $*" echo "Last command failed with exit code $cmd_status" @@ -132,7 +132,7 @@ load_or_generate_uuid() { local uuid local uuid_file="$UUID_STORAGE_DIR/$1" - if [[ -e "$uuid_file" ]]; then + if [[ -e $uuid_file ]]; then uuid="$(cat "$uuid_file")" else uuid="$(uuidgen -r)" @@ -144,10 +144,8 @@ load_or_generate_uuid() { } # Parses named arguments and stores them in the associative array `arguments`. -# The associative array `known_arguments` must contain a list of arguments -# prefixed with + (mandatory) or ? (optional). -# "at least one of" can be expressed by +a|b|c. -# all mandatory arguments are given. +# If given, the associative array `known_arguments` must contain a list of arguments +# prefixed with + (mandatory) or ? (optional). "at least one of" can be expressed by +a|b|c. parse_arguments() { local key local value @@ -155,11 +153,11 @@ parse_arguments() { for a in "$@"; do key="${a%%=*}" value="${a#*=}" - arguments["$key"]="$value" + arguments[$key]="$value" done declare -A allowed_keys - if [[ -v "known_arguments" ]]; then + if [[ -v known_arguments ]]; then local m for m in "${known_arguments[@]}"; do case "${m:0:1}" in @@ -168,28 +166,29 @@ parse_arguments() { local has_opt=false local m_opt # Splitting is intentional here - for m_opt in ${m//|/ }; do # shellcheck disable=SC2068 - allowed_keys["$m_opt"]=true - if [[ -v "arguments[$m_opt]" ]]; then + # shellcheck disable=SC2086 + for m_opt in ${m//|/ }; do + allowed_keys[$m_opt]=true + if [[ -v arguments[$m_opt] ]]; then has_opt=true fi done - [[ "$has_opt" == true ]] \ + [[ $has_opt == true ]] \ || die_trace 2 "Missing mandatory argument $m=..." ;; '?') - allowed_keys["${m:1}"]=true + allowed_keys[${m:1}]=true ;; *) die_trace 2 "Invalid start character in known_arguments, in argument '$m'" ;; esac done - fi - for a in "${!arguments[@]}"; do - [[ -v "allowed_keys[$a]" ]] \ - || die_trace 2 "Unkown argument '$a'" - done + for a in "${!arguments[@]}"; do + [[ -v allowed_keys[$a] ]] \ + || die_trace 2 "Unkown argument '$a'" + done + fi }