diff --git a/lib/nixos.nix b/lib/nixos.nix index b2acc3d..3eb9c06 100644 --- a/lib/nixos.nix +++ b/lib/nixos.nix @@ -260,7 +260,7 @@ in rec { generic-arg-help "${ownPath}" "$functionDoc" ${esc description} ${esc notesAndExamples} ${esc usageLine} || exit ) ; \exit 0 ; fi - # generic-arg-verify || \exit 3 + generic-arg-verify || \exit 3 # either call »argv[0]« with the remaining parameters as arguments, or if »$1« is »-c« eval »$2«. if [[ ''${args[trace]:-} ]] ; then set -x ; fi diff --git a/lib/setup-scripts/keys.sh b/lib/setup-scripts/keys.sh index 0ac98a5..41539f9 100644 --- a/lib/setup-scripts/keys.sh +++ b/lib/setup-scripts/keys.sh @@ -7,7 +7,10 @@ function prompt-for-user-passwords { # (void) userPasswords[$user]=@{config.users.users!catAttrSets.password[$user]} done local user ; for user in "@{!config.users.users!catAttrSets.passwordFile[@]}" ; do - if ! userPasswords[$user]=$(prompt-new-password "for the user account »$user«") ; then true ; \return 1 ; fi + for attempt in 2 3 x ; do + if userPasswords[$user]=$(prompt-new-password "for the user account »$user«") ; then break ; fi + if [[ $attempt == x ]] ; then \return 1 ; fi ; echo "Retrying ($attempt/3):" + done done } diff --git a/lib/setup-scripts/utils.sh b/lib/setup-scripts/utils.sh index dff0482..7a946f5 100644 --- a/lib/setup-scripts/utils.sh +++ b/lib/setup-scripts/utils.sh @@ -87,11 +87,29 @@ function write-secret {( set -u # 1: path, 2?: owner[:[group]], 3?: mode ## Interactively prompts for a password to be entered and confirmed. function prompt-new-password {( set -u # 1: usage read -s -p "Please enter the new password $1: " password1 || exit ; echo 1>&2 + if (( ${#password1} == 0 )) ; then printf 'Password empty.\n' 1>&2 ; \exit 1 ; fi read -s -p "Please enter the same password again: " password2 || exit ; echo 1>&2 - if (( ${#password1} == 0 )) || [[ "$password1" != "$password2" ]] ; then printf 'Passwords empty or mismatch, aborting.\n' 1>&2 ; \exit 1 ; fi + if [[ "$password1" != "$password2" ]] ; then printf 'Passwords mismatch.\n' 1>&2 ; \exit 1 ; fi printf %s "$password1" || exit )} +## If »secretFile« does not exist, interactively prompts up to three times for the secret to be stored in that file. +function prompt-secret-as {( set -u # 1: what, 2: secretFile, 3?: owner[:[group]], 4?: mode + if [[ -e $2 ]] ; then \return ; fi + what=$1 ; shift + function prompt { + read -s -p "Please enter $what: " value || exit ; echo 1>&2 + if (( ${#value} == 0 )) ; then printf 'Nothing entered. ' 1>&2 ; \return 1 ; fi + read -s -p "Please enter that again, or return empty to skip the check: " check || exit ; echo 1>&2 + if [[ $check && $value != "$check" ]] ; then printf 'Entered values mismatch. ' 1>&2 ; \return 1 ; fi + } + for attempt in 2 3 x ; do + if prompt && printf %s "$value" | write-secret "$@" ; then break ; fi + if [[ $attempt == x ]] ; then echo "Aborting." 1>&2 ; \return 1 ; fi + echo "Retrying ($attempt/3):" 1>&2 + done +)} + declare-flag install-system inspectScripts "" "When running installation hooks (»...*Commands« composed as Nix strings) print out and pause before each command. This works ... semi-well." ## Runs an installer hook script, optionally stepping through the script. diff --git a/lib/setup-scripts/zfs.sh b/lib/setup-scripts/zfs.sh index 1205d8a..597606a 100644 --- a/lib/setup-scripts/zfs.sh +++ b/lib/setup-scripts/zfs.sh @@ -56,7 +56,7 @@ function ensure-datasets { local zfs=@{native.zfs}/bin/zfs local name ; while IFS= read -u3 -r -d $'\0' name ; do - if [[ ! $name =~ $filterExp ]] ; then printf 'Skipping dataset »%s« since it does not match »%s«\n' "$name" "$filterExp" >&2 ; continue ; fi + if [[ ! $name =~ $filterExp ]] ; then : "Skipping dataset »$name« since it does not match »$filterExp«" ; continue ; fi eval 'local -A dataset='"@{config.setup.zfs.datasets[$name]}" eval 'local -A props='"${dataset[props]}" @@ -118,9 +118,9 @@ function ensure-datasets { ( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs create "${zfsCreate[@]}" "${dataset[name]}" ) || exit fi if [[ ${props[canmount]} != off ]] ; then ( - tmpMnt=$(mktemp -d) ; trap "" EXIT && @{native.util-linux}/bin/mount -t zfs -o zfsutil "${dataset[name]}" $tmpMnt && - trap "@{native.util-linux}/bin/umount '${dataset[name]}' ; rmdir $tmpMnt" EXIT && - chmod 000 -- "$tmpMnt" && chown "${dataset[uid]}:${dataset[gid]}" -- "$tmpMnt" && chmod "${dataset[mode]}" -- "$tmpMnt" + tmp=$( mktemp -d ) && mkdir $tmp/mnt && @{native.util-linux}/bin/mount -t zfs -o zfsutil "${dataset[name]}" $tmp/mnt || exit + trap "@{native.util-linux}/bin/umount '${dataset[name]}' ; rmdir $tmp{/mnt,}" EXIT || exit + chmod 000 -- $tmp/mnt && ( cd $tmp ; chown "${dataset[uid]}:${dataset[gid]}" -- mnt && chmod "${dataset[mode]}" -- mnt ) || exit ) || exit ; fi if [[ $explicitKeylocation && $explicitKeylocation != "${props[keylocation]:-}" ]] ; then ( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs set keylocation="$explicitKeylocation" "${dataset[name]}" ) || exit