#!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail progname="$0" warn() { local line for line in "$@"; do echo "$progname: $line" 1>&2 done } error() { warn "$@" exit 1 } skip() { if (($# < 1)); then error 'name of value to be skipped is required' fi if (($# > 1)); then error 'too many arguments' fi local skip=$1 for s in "${skips[@]}"; do if [[ $s == "$skip" ]]; then return 1 fi done return 0 } args=$( getopt \ --options r:b:l:c:m:B:M:v \ --longoptions root:,boot-label:,main-label:,cryptmain-label:,mapping:,boot-options:,main-options:,verbose \ --name "$progname" \ -- "$@" ) eval set -- "$args" root=/mnt bootlbl=BOOT mainlbl=main cryptmainlbl=cryptmain mapping=main bootflags= mainflags= fatflags=() ext4flags=() skips=() while true; do case "$1" in -r | --root) root=$2 shift 2 ;; -b | --boot-label) skips+=(bootlbl) bootlbl=${2^^} shift 2 ;; -l | --main-label) skips+=(mainlbl) mainlbl=$2 shift 2 ;; -c | --cryptmain-label) skips+=(cryptmainlbl) cryptmainlbl=$2 shift 2 ;; -m | --mapping) skips+=(mapping) mapping=$2 shift 2 ;; -B | --boot-options) bootflags+=(--options "$2") shift 2 ;; -M | --main-options) mainflags+=(--options "$2") shift 2 ;; -v | --verbose) fatflags+=(-v) ext4flags+=(-v) shift ;; --) shift break ;; esac done if (($# < 1)); then error 'an argument specifying the block device is required' fi if (($# > 1)); then error 'too many arguments' fi blkdev=$1 sfdisk --label gpt --quiet -- "$blkdev" </dev/null while true; do read -rep 'Do you want your main partition to be encrypted? [y/N] ' input case "$input" in [Yy]*) while true; do read -rsp 'Enter password: ' password warn '' read -rsp 'Re-enter password: ' repassword warn '' if [[ $password == "$repassword" ]]; then break fi done if ! skip cryptmainlbl; then read -rep "Which label should the main LUKS partition have? [$cryptmainlbl] " input if [[ -n $input ]]; then cryptmainlbl=$input fi fi cryptsetup luksFormat --batch-mode --label "$cryptmainlbl" -- "$mainblkdev" <<<"$password" if ! skip mapping; then read -rep "Which name should the main LUKS mapping have? [$mapping] " input if [[ -n $input ]]; then mapping=$input fi fi cryptsetup open -- "$mainblkdev" "$mapping" <<<"$password" mainfs=/dev/mapper/$mapping break ;; '' | [Nn]*) mainfs=$mainblkdev break ;; *) warn 'Please answer with yes or no' ;; esac done if ! skip mainlbl; then read -rep "Which label should the main file system have? [$mainlbl] " input if [[ -n $input ]]; then mainlbl=$input fi fi mkfs.ext4 -qFL "$mainlbl" "${ext4flags[@]}" -- "$mainfs" mkdir --parents -- "$root" mount "${mainflags[@]}" -- "$mainfs" "$root" mkdir -- "$root/boot" mount "${bootflags[@]}" -- "$bootfs" "$root/boot"