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