#!/bin/sh
-set -Ceuvx
-
-die() {
- echo "$*" >&2
- exit 1
-}
-
-error() {
- die "error: $*"
-}
-
-try_quiet() {
- "$@" >/dev/null 2>&1
-}
-
-check_illegal_chars() {
- case "$1" in *[!A-Za-z0-9_.-]*|"")
- error "illegal characters in $2 '$1'" ;;
- esac
-}
+set -Ceu
+SCRIPT_NAME=$0
# constants unlikely to change
PATH_DEV=/dev
IDX_BOOT_PARTITION=1
PATH_MNT=/mnt/debinst
-# sanity checks: required tools
-for CMD in debootstrap pvcreate vgcreate lvcreate vgs efibootmgr; do
- try_quiet command -v "${CMD}"\
- || error "required tool not found: ${CMD}"
-done
+# helpers
+msg_nonl() {
+ printf '[## %s ##] ' "${SCRIPT_NAME}"
+ # shellcheck disable=SC2059
+ # (assume we'll always pass a literal format string)
+ printf "$@"
+}
+msg() {
+ msg_nonl "$@"
+ printf '\n'
+}
+die() {
+ msg '%s' "$*" >&2
+ exit 1
+}
+error() {
+ die "error: $*"
+}
+try_quiet() {
+ "$@" >/dev/null 2>&1
+}
+check_chars_legality() {
+ case "$1" in *[!A-Za-z0-9_.-]*|"")
+ error "illegal characters in $2 '$1'" ;;
+ esac
+}
+chroot_sh() {
+ LANG=C.UTF-8 chroot "${PATH_MNT}" /bin/sh -c "$@"
+}
# inputs to confirm
[ $# -eq 3 ]\
NAME_VOLGROUP=$2
BOOT_LABEL=$3
+# constants derived from changeables
+LOGVOL_ROOT="${PATH_DEV}/${NAME_VOLGROUP}/${NAME_ROOT}"
+PATH_EFI_BOOT_LABEL="${PATH_EFI}/${BOOT_LABEL}"
+DEV_SLAVE="${PATH_MNT}${PATH_DEV}"
+
+# sanity checks: required tools
+for CMD in debootstrap efibootmgr lvcreate pvcreate vgcreate vgs; do
+ try_quiet command -v "${CMD}" ||\
+ error "required tool not found: ${CMD}"
+done
+
# inputs sanity check: PARTITION
-[ -b "${PARTITION}" ]\
- || error "${PARTITION} is not a block device"
-try_quiet findmnt --source "${PARTITION}"\
- && error "${PARTITION} is already mounted"
+[ -b "${PARTITION}" ] ||\
+ error "${PARTITION} is not a block device"
+try_quiet findmnt --source "${PARTITION}" &&\
+ error "${PARTITION} is already mounted"
# inputs sanity check: NAME_VOLGROUP
-check_illegal_chars "${NAME_VOLGROUP}" "volume group name"
-try_quiet vgs "${NAME_VOLGROUP}" \
- && error "volume group '${NAME_VOLGROUP}' already exists"
+check_chars_legality "${NAME_VOLGROUP}" "volume group name"
+try_quiet vgs "${NAME_VOLGROUP}" &&\
+ error "volume group '${NAME_VOLGROUP}' already exists"
# inputs sanity check: BOOT_LABEL
-check_illegal_chars "${BOOT_LABEL}" "boot label"
-[ -e "${PATH_EFI}/${BOOT_LABEL}" ] \
- && error "${PATH_EFI}/${BOOT_LABEL} already exists"
+check_chars_legality "${BOOT_LABEL}" "boot label"
+[ -e "${PATH_EFI}/${BOOT_LABEL}" ] &&\
+ error "${PATH_EFI}/${BOOT_LABEL} already exists"
efibootmgr \
- | sed -n 's/^Boot[0-9A-Fa-f]\{4\}\*\{0,1\} //p' \
- | grep -Fxq "${BOOT_LABEL}" \
- && error "an EFI boot entry named '${BOOT_LABEL}' already exists"
+ | sed -n 's/^Boot[0-9A-Fa-f]\{4\}[* ] //p' \
+ | awk '{print $1}' \
+ | grep -Fxq "${BOOT_LABEL}" &&\
+ error "an EFI boot entry named '${BOOT_LABEL}' already exists"
# run inputs by user and ask for confirmation
-echo "\
-target partition: [${PARTITION}] \
-name for volume group: [${NAME_VOLGROUP}] \
-boot label: [${BOOT_LABEL}]"
-printf "\
-this will erase %s – type YES! (all caps, \
-with exclamation mark) to continue: " "${PARTITION}"
-read CONFIRM
-[ "${CONFIRM}" = 'YES!' ]\
- || die "aborted: confirmation not given"
-
-# constants derived from changeables
-LOGVOL_ROOT="${PATH_DEV}/${NAME_VOLGROUP}/${NAME_ROOT}"
-PATH_EFI_BOOT_LABEL="${PATH_EFI}/${BOOT_LABEL}"
-DEV_SLAVE="${PATH_MNT}${PATH_DEV}"
+msg 'Your installation setup choices:'
+msg '- target partition (WILL BE ERASED!): [ %s ]' "${PARTITION}"
+msg '- how to name new volume group: [ %s ]' "${NAME_VOLGROUP}"
+msg '- boot label to register with EFI: [ %s ]' "${BOOT_LABEL}"
+msg_nonl 'To continue, type "YES!" (all caps, exclamation mark, no quotes): '
+read -r CONFIRM
+[ "${CONFIRM}" = 'YES!' ] ||\
+ die 'ABORTED: expected confirmation not given.'
# set up LVM and filesystem
+msg 'Initializing %s for LVM …' "${PARTITION}"
pvcreate "${PARTITION}"
+msg 'Creating volume group "%s" there …' "${NAME_VOLGROUP}"
vgcreate "${NAME_VOLGROUP}" "${PARTITION}"
+msg 'Creating logical volume "%s" there …' "${NAME_ROOT}"
lvcreate -l '100%FREE' -n "${NAME_ROOT}" "${NAME_VOLGROUP}"
mkfs.ext4 "${LOGVOL_ROOT}"
# mount and install base
+msg 'Mounting %s at %s …' "${LOGVOL_ROOT}" "${PATH_MNT}"
mkdir -p "${PATH_MNT}"
mount "${LOGVOL_ROOT}" "${PATH_MNT}"
+msg 'Installing Debian Suite "%s" there via debootstrap …' "${DEB_SUITE}"
debootstrap "${DEB_SUITE}" "${PATH_MNT}"
+msg 'For chroot environment also mounting %s into there …' "${PATH_DEV}"
mount --rbind "${PATH_DEV}" "${DEV_SLAVE}"
mount --make-rslave "${DEV_SLAVE}"
-# set up kernel, initrd, login
-LANG=C.UTF-8 chroot "${PATH_MNT}" /bin/sh -c "\
- apt update &&\
- apt install -y lvm2 linux-image-amd64 &&\
- passwd"
+# set up kernel, initrd
+msg 'Into chroot environment installing LVM tools, kernel, initrd …'
+chroot_sh "apt update"
+chroot_sh "apt install -y lvm2 linux-image-amd64"
# install kernel and initrd into EFI tree/vars
+msg 'EFI setup: copying kernel and initrd into %s …' "${PATH_EFI_BOOT_LABEL}"
mkdir "${PATH_EFI_BOOT_LABEL}"
for FILENAME in "${NAME_INITRD}" "${NAME_VMLINUZ}"; do
cp "${PATH_MNT}/${FILENAME}" "${PATH_EFI_BOOT_LABEL}/"
done
+msg 'EFI setup: adding boot entry %s …' "${BOOT_LABEL}"
efibootmgr \
--create \
--disk "${PATH_BOOT_DEVICE}" \
--loader "${BOOT_LABEL}/${NAME_VMLINUZ}" \
--unicode "root=${LOGVOL_ROOT} ro initrd=${BOOT_LABEL}\\${NAME_INITRD}"
+# ask root login at latest possible moment, so that on fails: less left undone
+chroot_sh "passwd"
+
# clean up mounts
+msg 'Mostly done! Now unmounting chroot environment …'
umount -R "${DEV_SLAVE}"
umount "${PATH_MNT}"
+msg 'Finished!'