alis/alis-recovery.sh

287 lines
9.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# shellcheck disable=SC1090,SC2153,SC2155,SC2034
#SC1090: Can't follow non-constant source. Use a directive to specify location.
#SC2153: Possible Misspelling: MYVARIABLE may not be assigned. Did you mean MY_VARIABLE?
#SC2155 Declare and assign separately to avoid masking return values
#SC2034: foo appears unused. Verify it or export it.
set -eu
# Arch Linux Install Script Recovery (alis-recovery) start a recovery for an
# failed installation or broken system.
# Copyright (C) 2022 picodotdev
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This script is hosted at https://github.com/picodotdev/alis. For new features,
# improvements and bugs fill an issue in GitHub or make a pull request.
# Pull Request are welcome!
#
# If you test it in real hardware please send me an email to pico.dev@gmail.com with
# the machine description and tell me if somethig goes wrong or all works fine.
#
# Please, don't ask for support for this script in Arch Linux forums, first read
# the Arch Linux wiki [1], the Installation Guide [2] and the General
# Recomendations [3], later compare the commands with those of this script.
#
# [1] https://wiki.archlinux.org
# [2] https://wiki.archlinux.org/index.php/Installation_guide
# [3] https://wiki.archlinux.org/index.php/General_recommendations
# Starts the reccovery of a Arch Linux system installed with alis.
#
# Usage:
# # loadkeys es
# # curl -sL https://raw.githubusercontent.com/picodotdev/alis/master/download.sh | bash
# # vim alis-recovery.conf
# # ./alis-recovery.sh
function init_config() {
local COMMONS_FILE="alis-commons.sh"
source "$COMMONS_FILE"
source "$COMMONS_CONF_FILE"
source "$RECOVERY_CONF_FILE"
}
function sanitize_variables() {
DEVICE=$(sanitize_variable "$DEVICE")
FILE_SYSTEM_TYPE=$(sanitize_variable "$FILE_SYSTEM_TYPE")
PARTITION_MODE=$(sanitize_variable "$PARTITION_MODE")
SWAP_SIZE=$(sanitize_variable "$SWAP_SIZE")
PARTITION_CUSTOMMANUAL_BOOT=$(sanitize_variable "$PARTITION_CUSTOMMANUAL_BOOT")
PARTITION_CUSTOMMANUAL_ROOT=$(sanitize_variable "$PARTITION_CUSTOMMANUAL_ROOT")
for I in "${BTRFS_SUBVOLUMES_MOUNTPOINTS[@]}"; do
IFS=',' read -ra SUBVOLUME <<< "$I"
if [ "${SUBVOLUME[0]}" == "root" ]; then
BTRFS_SUBVOLUME_ROOT=("${SUBVOLUME[@]}")
elif [ "${SUBVOLUME[0]}" == "swap" ]; then
BTRFS_SUBVOLUME_SWAP=("${SUBVOLUME[@]}")
fi
done
for I in "${PARTITION_MOUNT_POINTS[@]}"; do
IFS='=' read -ra PARTITION_MOUNT_POINT <<< "$I"
if [ "${PARTITION_MOUNT_POINT[1]}" == "/boot" ]; then
PARTITION_BOOT_NUMBER="${PARTITION_MOUNT_POINT[0]}"
elif [ "${PARTITION_MOUNT_POINT[1]}" == "/" ]; then
PARTITION_ROOT_NUMBER="${PARTITION_MOUNT_POINT[0]}"
fi
done
}
function check_variables() {
check_variables_value "KEYS" "$KEYS"
check_variables_boolean "LOG_TRACE" "$LOG_TRACE"
check_variables_boolean "LOG_FILE" "$LOG_FILE"
check_variables_value "DEVICE" "$DEVICE"
if [ "$DEVICE" == "auto" ]; then
local DEVICE_BOOT=$(lsblk -oMOUNTPOINT,PKNAME -P -M | grep 'MOUNTPOINT="/run/archiso/bootmnt"' | sed 's/.*PKNAME="\(.*\)".*/\1/')
if [ -n "$DEVICE_BOOT" ]; then
local DEVICE_BOOT="/dev/$DEVICE_BOOT"
fi
local DEVICE_DETECTED="false"
if [ -e "/dev/sda" ] && [ "$DEVICE_BOOT" != "/dev/sda" ]; then
if [ "$DEVICE_DETECTED" == "true" ]; then
echo "Auto device is ambigous, detected $DEVICE and /dev/sda."
exit 1
fi
DEVICE_DETECTED="true"
DEVICE_SDA="true"
DEVICE="/dev/sda"
fi
if [ -e "/dev/nvme0n1" ] && [ "$DEVICE_BOOT" != "/dev/nvme0n1" ]; then
if [ "$DEVICE_DETECTED" == "true" ]; then
echo "Auto device is ambigous, detected $DEVICE and /dev/nvme0n1."
exit 1
fi
DEVICE_DETECTED="true"
DEVICE_NVME="true"
DEVICE="/dev/nvme0n1"
fi
if [ -e "/dev/vda" ] && [ "$DEVICE_BOOT" != "/dev/vda" ]; then
if [ "$DEVICE_DETECTED" == "true" ]; then
echo "Auto device is ambigous, detected $DEVICE and /dev/vda."
exit 1
fi
DEVICE_DETECTED="true"
DEVICE_VDA="true"
DEVICE="/dev/vda"
fi
if [ -e "/dev/mmcblk0" ] && [ "$DEVICE_BOOT" != "/dev/mmcblk0" ]; then
if [ "$DEVICE_DETECTED" == "true" ]; then
echo "Auto device is ambigous, detected $DEVICE and /dev/mmcblk0."
exit 1
fi
DEVICE_DETECTED="true"
DEVICE_MMC="true"
DEVICE="/dev/mmcblk0"
fi
fi
check_variables_boolean "DEVICE_TRIM" "$DEVICE_TRIM"
check_variables_boolean "LVM" "$LVM"
check_variables_equals "LUKS_PASSWORD" "LUKS_PASSWORD_RETYPE" "$LUKS_PASSWORD" "$LUKS_PASSWORD_RETYPE"
check_variables_list "FILE_SYSTEM_TYPE" "$FILE_SYSTEM_TYPE" "ext4 btrfs xfs f2fs reiserfs" "true" "true"
check_variables_size "BTRFS_SUBVOLUME_ROOT" ${#BTRFS_SUBVOLUME_ROOT[@]} 3
check_variables_list "BTRFS_SUBVOLUME_ROOT" "${BTRFS_SUBVOLUME_ROOT[2]}" "/" "true" "true"
if [ -n "$SWAP_SIZE" ]; then
check_variables_size "BTRFS_SUBVOLUME_SWAP" ${#BTRFS_SUBVOLUME_SWAP[@]} 3
fi
for I in "${BTRFS_SUBVOLUMES_MOUNTPOINTS[@]}"; do
IFS=',' read -ra SUBVOLUME <<< "$I"
check_variables_size "SUBVOLUME" ${#SUBVOLUME[@]} 3
done
check_variables_list "PARTITION_MODE" "$PARTITION_MODE" "auto custom manual" "true" "true"
check_variables_value "PARTITION_BOOT_NUMBER" "$PARTITION_BOOT_NUMBER"
check_variables_value "PARTITION_ROOT_NUMBER" "$PARTITION_ROOT_NUMBER"
check_variables_boolean "CHROOT" "$CHROOT"
}
function warning() {
echo -e "${BLUE}Welcome to Arch Linux Install Script Recovery${NC}"
echo ""
read -r -p "Do you want to continue? [y/N] " yn
case $yn in
[Yy]* )
;;
[Nn]* )
exit
;;
* )
exit
;;
esac
}
function init() {
print_step "init()"
init_log_trace "$LOG_TRACE"
init_log_file "$LOG_FILE" "$RECOVERY_LOG_FILE"
loadkeys "$KEYS"
}
function facts() {
print_step "facts()"
facts_commons
if echo "$DEVICE" | grep -q "^/dev/sd[a-z]"; then
DEVICE_SDA="true"
elif echo "$DEVICE" | grep -q "^/dev/nvme"; then
DEVICE_NVME="true"
elif echo "$DEVICE" | grep -q "^/dev/vd[a-z]"; then
DEVICE_VDA="true"
elif echo "$DEVICE" | grep -q "^/dev/mmc"; then
DEVICE_MMC="true"
fi
}
function prepare() {
print_step "prepare()"
prepare_partition
configure_network
ask_passwords
}
function prepare_partition() {
if [ -d "${MNT_DIR}"/boot ]; then
umount "${MNT_DIR}"/boot
umount "${MNT_DIR}"
fi
if [ -e "/dev/mapper/$LVM_VOLUME_GROUP-$LVM_VOLUME_LOGICAL" ]; then
umount "/dev/mapper/$LVM_VOLUME_GROUP-$LVM_VOLUME_LOGICAL"
fi
if [ -e "/dev/mapper/$LUKS_DEVICE_NAME" ]; then
cryptsetup close "$LUKS_DEVICE_NAME"
fi
partprobe "$DEVICE"
}
function ask_passwords() {
if [ "$LUKS_PASSWORD" == "ask" ]; then
PASSWORD_TYPED="false"
while [ "$PASSWORD_TYPED" != "true" ]; do
read -r -sp 'Type LUKS password: ' LUKS_PASSWORD
echo ""
read -r -sp 'Retype LUKS password: ' LUKS_PASSWORD_RETYPE
echo ""
if [ "$LUKS_PASSWORD" == "$LUKS_PASSWORD_RETYPE" ]; then
PASSWORD_TYPED="true"
else
echo "LUKS password don't match. Please, type again."
fi
done
fi
}
function partition() {
print_step "partition()"
# setup
partition_setup
# luks and lvm
if [ -n "$LUKS_PASSWORD" ]; then
echo -n "$LUKS_PASSWORD" | cryptsetup --key-file=- open "$PARTITION_ROOT" "$LUKS_DEVICE_NAME"
sleep 5
fi
if [ -n "$LUKS_PASSWORD" ]; then
DEVICE_ROOT="/dev/mapper/$LUKS_DEVICE_NAME"
fi
if [ "$LVM" == "true" ]; then
DEVICE_ROOT="/dev/mapper/$LVM_VOLUME_GROUP-$LVM_VOLUME_LOGICAL"
fi
# options
partition_options
# mount
partition_mount
}
function recovery() {
arch-chroot "${MNT_DIR}"
}
function end() {
echo ""
if [ "$CHROOT" == "false" ]; then
echo -e "${GREEN}Recovery started.${NC}"
else
echo -e "${GREEN}Recovery ended.${NC}"
fi
echo "You must do an explicit reboot after finalize recovery (exit if in arch-chroot, ./alis-reboot.sh)."
echo ""
}
function main() {
init_config
sanitize_variables
check_variables
warning
init
facts
prepare
partition
if [ "$CHROOT" == "true" ]; then
recovery
fi
end
}
main