Flush stdin before ask(); implement safe ctrl-c

This commit is contained in:
oddlama 2020-01-03 00:29:17 +01:00
parent 161afbc285
commit e47ffb0700
No known key found for this signature in database
GPG Key ID: 88EA325D51D53908
4 changed files with 62 additions and 40 deletions

View File

@ -13,12 +13,12 @@ check_has_program() {
sync_time() { sync_time() {
einfo "Syncing time" einfo "Syncing time"
ntpd -g -q >/dev/null \ ntpd -g -q \
|| die "Could not sync time with remote server" || die "Could not sync time with remote server"
einfo "Current date: $(LANG=C date)" einfo "Current date: $(LANG=C date)"
einfo "Writing time to hardware clock" einfo "Writing time to hardware clock"
hwclock --systohc --utc >/dev/null \ hwclock --systohc --utc \
|| die "Could not save time to hardware clock" || die "Could not save time to hardware clock"
} }
@ -40,22 +40,21 @@ prepare_installation_environment() {
} }
partition_device_print_config_summary() { partition_device_print_config_summary() {
echo "-------- Partition configuration --------" elog "-------- Partition configuration --------"
echo "Device: $PARTITION_DEVICE" elog "Device: $PARTITION_DEVICE"
elog "Existing partition table:" elog "Existing partition table:"
lsblk -n "$PARTITION_DEVICE" \ for_line_in <(lsblk -n "$PARTITION_DEVICE" \
|| die "Error in lsblk" || die "Error in lsblk") elog
elog "New partition table:" elog "New partition table:"
echo "$PARTITION_DEVICE" elog "$PARTITION_DEVICE"
echo "├─efi size=$PARTITION_EFI_SIZE" elog "├─efi size=$PARTITION_EFI_SIZE"
if [[ "$ENABLE_SWAP" == true ]]; then if [[ "$ENABLE_SWAP" == true ]]; then
echo "├─swap size=$PARTITION_SWAP_SIZE" elog "├─swap size=$PARTITION_SWAP_SIZE"
fi fi
echo "└─linux size=[remaining]" elog "└─linux size=[remaining]"
if [[ "$ENABLE_SWAP" != true ]]; then if [[ "$ENABLE_SWAP" != true ]]; then
echo "swap: disabled" elog "swap: disabled"
fi fi
echo
} }
partition_device() { partition_device() {
@ -93,7 +92,7 @@ partition_device() {
|| die "Could not create linux partition" || die "Could not create linux partition"
# Print partition table # Print partition table
einfo "Applied partition table:" einfo "Applied partition table"
sgdisk -p "$PARTITION_DEVICE" \ sgdisk -p "$PARTITION_DEVICE" \
|| die "Could not print partition table" || die "Could not print partition table"
@ -172,7 +171,7 @@ mount_root() {
bind_bootstrap_dir() { bind_bootstrap_dir() {
# Use new location by default # Use new location by default
GENTOO_BOOTSTRAP_DIR="$GENTOO_BOOTSTRAP_BIND" export GENTOO_BOOTSTRAP_DIR="$GENTOO_BOOTSTRAP_BIND"
# Bind the bootstrap dir to a location in /tmp, # Bind the bootstrap dir to a location in /tmp,
# so it can be accessed from within the chroot # so it can be accessed from within the chroot
@ -204,33 +203,38 @@ download_stage3() {
|| die "Could not parse list of tarballs" || die "Could not parse list of tarballs"
# Strip quotes # Strip quotes
CURRENT_STAGE3="${CURRENT_STAGE3:1:-1}" CURRENT_STAGE3="${CURRENT_STAGE3:1:-1}"
# File to indiciate successful verification
CURRENT_STAGE3_VERIFIED="${CURRENT_STAGE3}.verified"
# Download file if not already downloaded # Download file if not already downloaded
if [[ -e "$CURRENT_STAGE3" ]] ; then if [[ -e "$CURRENT_STAGE3_VERIFIED" ]]; then
einfo "$STAGE3_BASENAME tarball already exists" einfo "$STAGE3_BASENAME tarball already downloaded and verified"
else else
einfo "Downloading $STAGE3_BASENAME tarball" einfo "Downloading $STAGE3_BASENAME tarball"
download "$STAGE3_RELEASES/${CURRENT_STAGE3}" "${CURRENT_STAGE3}" download "$STAGE3_RELEASES/${CURRENT_STAGE3}" "${CURRENT_STAGE3}"
download "$STAGE3_RELEASES/${CURRENT_STAGE3}.DIGESTS.asc" "${CURRENT_STAGE3}.DIGESTS.asc" download "$STAGE3_RELEASES/${CURRENT_STAGE3}.DIGESTS.asc" "${CURRENT_STAGE3}.DIGESTS.asc"
# Import gentoo keys
einfo "Importing gentoo gpg key"
local GENTOO_GPG_KEY="$TMP_DIR/gentoo-keys.gpg"
download "https://gentoo.org/.well-known/openpgpkey/hu/wtktzo4gyuhzu8a4z5fdj3fgmr1u6tob?l=releng" "$GENTOO_GPG_KEY" \
|| die "Could not retrieve gentoo gpg key"
gpg --quiet --import < "$GENTOO_GPG_KEY" \
|| die "Could not import gentoo gpg key"
# Verify DIGESTS signature
einfo "Verifying DIGEST.asc signature"
gpg --quiet --verify "${CURRENT_STAGE3}.DIGESTS.asc" \
|| die "Signature of '${CURRENT_STAGE3}.DIGESTS.asc' invalid!"
# Check hashes
einfo "Verifying tarball integrity"
rhash -P --check <(grep -B 1 'tar.xz$' "${CURRENT_STAGE3}.DIGESTS.asc") \
|| die "Checksum mismatch!"
# Create verification file in case the script is restarted
touch "$CURRENT_STAGE3_VERIFIED"
fi fi
# Import gentoo keys
einfo "Importing gentoo gpg key"
local GENTOO_GPG_KEY="$TMP_DIR/gentoo-keys.gpg"
download "https://gentoo.org/.well-known/openpgpkey/hu/wtktzo4gyuhzu8a4z5fdj3fgmr1u6tob?l=releng" "$GENTOO_GPG_KEY" \
|| die "Could not retrieve gentoo gpg key"
gpg --import < "$GENTOO_GPG_KEY" \
|| die "Could not import gentoo gpg key"
# Verify DIGESTS signature
einfo "Verifying DIGEST.asc signature"
gpg --verify "${CURRENT_STAGE3}.DIGESTS.asc" \
|| die "Signature of '${CURRENT_STAGE3}.DIGESTS.asc' invalid!"
# Check hashes
einfo "Verifying tarball integrity"
rhash -P --check <(grep -B 1 'tar.xz$' "${CURRENT_STAGE3}.DIGESTS.asc") \
|| die "Checksum mismatch!"
} }
extract_stage3() { extract_stage3() {
@ -263,9 +267,9 @@ disable_logging() {
} }
gentoo_umount() { gentoo_umount() {
einfo "Unmounting root filesystem"
if mountpoint -q -- "$ROOT_MOUNTPOINT"; then if mountpoint -q -- "$ROOT_MOUNTPOINT"; then
umount -R "$ROOT_MOUNTPOINT" \ einfo "Unmounting root filesystem"
umount -R -l "$ROOT_MOUNTPOINT" \
|| die "Could not unmount filesystems" || die "Could not unmount filesystems"
fi fi
} }

View File

@ -88,6 +88,7 @@ main_install_gentoo_in_chroot() {
main_install() { main_install() {
[[ $# == 0 ]] || die "Too many arguments" [[ $# == 0 ]] || die "Too many arguments"
gentoo_umount
install_stage3 \ install_stage3 \
|| die "Failed to install stage3" || die "Failed to install stage3"
@ -108,11 +109,14 @@ main_umount() {
################################################ ################################################
# Main dispatch # Main dispatch
# Instantly kill when pressing ctrl-c
trap "kill $GENTOO_BOOTSTRAP_SCRIPT_PID" INT
einfo "Verbose script output will be logged to: '$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out'" einfo "Verbose script output will be logged to: '$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out'"
# Save old stdout # Save old stdout
exec 3>&1 exec 3>&1
# Restore old filedescriptor on certain signals # Restore old filedescriptor on certain signals
trap 'exec 1>&3' 0 1 2 3 RETURN trap 'exec 1>&3; exit 1' 0 1 2 3 RETURN
# Replace stdout with logfole # Replace stdout with logfole
exec 1>"$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out" exec 1>"$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out"
# Link to latest log file # Link to latest log file

View File

@ -6,6 +6,9 @@
# Source the systems profile # Source the systems profile
source /etc/profile source /etc/profile
# Set safe umask
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))"

View File

@ -36,7 +36,18 @@ die() {
exit 1 exit 1
} }
for_line_in() {
while IFS="" read -r line || [[ -n "$line" ]]; do
"$2" "$line"
done <"$1"
}
ask() { ask() {
# Empty stdin
local empty_stdin
while read -r -t 0.01 empty_stdin; do true; done
unset empty_stdin
while true; do while true; do
read -r -p "$* (Y/n) " response read -r -p "$* (Y/n) " response
case "${response,,}" in case "${response,,}" in
@ -49,15 +60,15 @@ ask() {
} }
countdown() { countdown() {
echo -n "$1" echo -n "$1" >&3
local i="$2" local i="$2"
while [[ $i -gt 0 ]]; do while [[ $i -gt 0 ]]; do
echo -n "$i " echo -n "$i " >&3
i=$((i - 1)) i=$((i - 1))
sleep 1 sleep 1
done done
echo echo >&3
} }
download_stdout() { download_stdout() {