#!/usr/bin/env bash set -o errexit set -o pipefail CONFIG="$(mktemp)" declare -rgA default_values=( ["wifi_if"]="wlan0" ["install_dev"]="/dev/mmcblk2" ["repo"]="https://alpha.de.repo.voidlinux.org/current/aarch64" ["arch"]="aarch64" ["timezone"]="Europe/Zurich" ["keymap"]="uk" ["locale"]="en_US.UTF-8 UTF-8" ) get_value() { local white=$'\e[97m' local nocolour=$'\e[0m' local var_name="$1" local prompt="$2" local secure="" if [ -n "$3" ]; then secure="s" fi # shellcheck source=/dev/null . "$CONFIG" if [ -z "${!var_name}" ]; then local def_val="${default_values[$var_name]}" read -${secure}rp "$white$prompt [$def_val]:$nocolour " value echo "export $var_name=\"${value:-$def_val}\"" >> "$CONFIG" # shellcheck source=/dev/null . "$CONFIG" fi echo "${!var_name}" } network() { local wifi_if wifi_if="$(get_value "wifi_if" "wifi interface name")" ip link set "$wifi_if" up nmcli device wifi list local wifi_ssid wifi_ssid="$(get_value "wifi_ssid" "wifi ssid")" local wifi_pw wifi_pw="$(get_value "wifi_pw" "wifi password" 1)" nmcli con delete "$wifi_ssid" || true nmcli device wifi connect "$wifi_ssid" password "$wifi_pw" } datetime() { local datetime datetime="$(get_value "datetime" "date and time now (like 2020-01-01 12:00)")" date "+%Y--%m-%d %T" --set="$datetime" hwclock --systohc } partition() { local install_dev install_dev="$(get_value "install_dev" "installation device")" if [ ! -e "$install_dev" ]; then echo "device node $install_dev does not exist" exit 1 fi sfdisk --force "$install_dev" << EOF label: gpt start=16MiB size=512MiB, type=bc13c2ff-59e6-4262-a352-b275fd6f7172 type=b921b045-1df0-41c3-af44-4c6f280d3fae EOF mkfs.vfat -F32 "$install_dev"p1 } create_luks() { local install_dev install_dev="$(get_value "install_dev" "installation device")" cryptsetup luksFormat "$install_dev"p2 } open_luks() { local install_dev install_dev="$(get_value "install_dev" "installation device")" cryptsetup open "$install_dev"p2 void } create_lvm() { pvcreate /dev/mapper/void vgcreate void /dev/mapper/void lvcreate -L 4G void -n swap lvcreate -l 100%FREE void -n root } open_lvm() { vgchange --activate y } make_filesystems() { mkswap -L SWAP /dev/void/swap mkfs.xfs -f -L ROOT /dev/void/root } ensure_mount() { local src="$1" local dest="$2" local with_rbind="$3" local rbind="" if [ ! -z "$with_rbind" ]; then rbind="--rbind" fi mount $rbind "$src" "$dest" if [ ! -z "$with_rbind" ]; then mount --make-rslave "$dest" fi } mount_filesystems() { local install_dev install_dev="$(get_value "install_dev" "installation device")" ensure_mount "/dev/void/root" "/mnt" mkdir -p /mnt/boot ensure_mount "$install_dev"p1 "/mnt/boot" swapon /dev/void/swap } install_basesystem() { local repo repo="$(get_value "repo" "package repository")" local arch arch="$(get_value "arch" "installation architecture")" XBPS_ARCH=$arch xbps-install -S -y -r /mnt -R "$repo" base-system pinebookpro-base dracut lvm2 cryptsetup sudo stow << 'EOF' y EOF cp /etc/resolv.conf /mnt/etc/ } mount_special_filesystems() { ensure_mount "/sys" "/mnt/sys" 1 ensure_mount "/dev" "/mnt/dev" 1 ensure_mount "/proc" "/mnt/proc" 1 ensure_mount "/tmp" "/mnt/tmp" 1 } set_fstab() { local install_dev install_dev="$(get_value "install_dev" "installation device")" local boot_uuid boot_uuid="$(blkid | grep "${install_dev}p1" | awk '{print $2}')" cat >/mnt/etc/fstab </dev/null | hexdump -v -e '/1 " %02X"' | tr '[:upper:]' '[:lower:]')" local root_uuid root_uuid="$(blkid | grep "${install_dev}p2" | awk '{print $2}' | sed 's/"//g')" sed -i "s/setenv macaddr.*/setenv macadr $mac/g" "$boot_txt" sed -i "s|root=PARTUUID=|root=/dev/void/root rd.auto=1 cryptdevice=${root_uuid}:lvm|g" "$boot_txt" cp "$boot_txt" "$boot_txt_mine" mkimage -A arm -O linux -T script -C none -n "boot script" -d "$boot_txt" "$boot_scr" } set_sudoers() { sed -i 's/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g' /mnt/etc/sudoers } set_user() { local user_name user_name="$(get_value "user_name" "username")" local user_pw user_pw="$(get_value "user_pw" "user password" 1)" chroot /mnt /bin/env -i \ user_name="$user_name" \ user_pw="$user_pw" \ /bin/bash <<"EOT" useradd --groups wheel --create-home --shell /bin/bash --user-group $user_name echo -e "$user_pw\n$user_pw" | passwd "$user_name" EOT } set_base_conf() { local timezone timezone="$(get_value "timezone" "timezone")" local keymap keymap="$(get_value "keymap" "keymap")" local hostname hostname="$(get_value "hostname" "hostname")" local locale locale="$(get_value "locale" "locale")" echo "$locale" >> /mnt/etc/default/libc-locales chroot /mnt /bin/env -i \ timezone="$timezone" \ /bin/bash <<"EOT" xbps-reconfigure -f glibc-locales ln -sf /usr/share/zoneinfo/$timezone /etc/localtime EOT echo "$hostname" > /mnt/etc/hostname cat >/mnt/etc/hosts < 127.0.0.1 localhost.localdomain localhost $hostname ::1 localhost.localdomain localhost ip6-localhost $hostname # End of file EOF cat >/mnt/etc/rc.conf < /etc/hostname # #HOSTNAME="void-live" # Set RTC to UTC or localtime. #HARDWARECLOCK="UTC" # Set timezone, availables timezones at /usr/share/zoneinfo. TIMEZONE="$timezone" # Keymap to load, see loadkeys(8). KEYMAP="$keymap" # Console font to load, see setfont(8). #FONT="lat9w-16" # Console map to load, see setfont(8). #FONT_MAP= # Font unimap to load, see setfont(8). #FONT_UNIMAP= # Amount of ttys which should be setup. #TTYS= EOF } tidy_up() { sync if grep -qe "/mnt " /proc/mounts; then umount -R /mnt fi swapoff /dev/void/swap > /dev/null 2>&1 || true vgchange --activate n cryptsetup close void > /dev/null 2>&1 || true } full_install() { datetime network partition create_luks open_luks create_lvm open_lvm make_filesystems mount_filesystems install_basesystem mount_special_filesystems set_fstab set_boot_scr set_sudoers set_user set_base_conf tidy_up } repair() { open_luks open_lvm mount_filesystems mount_special_filesystems chroot /mnt bash tidy_up } help() { cat << EOF the following commands are available: datetime network partition create_luks open_luks create_lvm open_lvm make_filesystems mount_filesystems install_basesystem mount_special_filesystems set_fstab set_boot_scr set_sudoers set_user set_base_conf full_install repair tidy_up help ensure to understand what they are doing before using them EOF } commands=( "datetime" "network" "partition" "create_luks" "open_luks" "open_lvm" "make_filesystems" "mount_filesystems" "set_fstab" "set_boot_scr" "set_sudoers" "set_user" "set_base_conf" "full_install" "repair" "tidy_up" "help" ) cmd_loop() { local cmd while [[ "$cmd" != "exit" ]]; do read -rp "${white}>$nocolour " cmd if [[ "${commands[*]}" == *"${cmd}"* ]]; then $cmd else if [ "$cmd" != "exit" ]; then echo "no such command" fi fi done } trap tidy_up 0 SIGHUP SIGINT SIGQUIT SIGABRT SIGTERM if [ "$1" == "full" ]; then full_install else cmd_loop fi