From 7f4e62ee4b9dcd43126aa477eb519c08452a969b Mon Sep 17 00:00:00 2001 From: Alex Tavarez Date: Wed, 17 Sep 2025 15:33:16 -0400 Subject: [PATCH] Changed default ZFS pool name, created prompt-based conditional with a case allowing for custom datasets, added cases for custom encrypted dataset or symbolic link creation --- zfs/zfs-media-drive.sh | 133 ++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 21 deletions(-) diff --git a/zfs/zfs-media-drive.sh b/zfs/zfs-media-drive.sh index 8fcd62c..10ace09 100644 --- a/zfs/zfs-media-drive.sh +++ b/zfs/zfs-media-drive.sh @@ -3,7 +3,7 @@ set -euo pipefail SCRIPT_ROOT=$(dirname "$0") # @TODO: Implement more soft-coding and interactivity to this script -ZFS_POOL_NAME="media" +ZFS_POOL_NAME="medialib" ZFS_COMPAT="openzfs-2.1-linux" ZFS_KEY_LOC="file:///etc/zfs/keys/zroot.key" ZFS_KEY_FORMAT="passphrase" @@ -31,40 +31,72 @@ create_zpool () { mkdataset () { mkdir -p "$1" - sudo zfs create -o mountpoint="$1" "$2" + sudo zfs create -v -o mountpoint="$1" "$2" } create_datasets () { - DATASET=("${HOME}/Documents/.calibre" "${1}/LITERATURE") - mkdataset "${DATASET[0]}" "${DATASET[1]}" + read -r -p "Provide custom datasets? (y/n): " CUSTOMIZE_DATASETS + + if [[ "$CUSTOMIZE_DATASETS" =~ [Nn]* ]]; then + DATASET=("${HOME}/Documents/.calibre" "${1}/LITERATURE") + mkdataset "${DATASET[0]}" "${DATASET[1]}" - DATASET=("${HOME}/Videos" "${1}/FILM") - mkdataset "${DATASET[0]}" "${DATASET[1]}" + DATASET=("${HOME}/Videos" "${1}/FILM") + mkdataset "${DATASET[0]}" "${DATASET[1]}" - DATASET=("${HOME}/.var/app/com.valvesoftware.Steam" "${1}/STEAMGAMES") - mkdataset "${DATASET[0]}" "${DATASET[1]}" + DATASET=("${HOME}/.var/app/com.valvesoftware.Steam" "${1}/STEAMGAMES") + mkdataset "${DATASET[0]}" "${DATASET[1]}" - DATASET=("${HOME}/.var/app/org.libretro.RetroArch" "${1}/RARCHGAMES") - mkdataset "${DATASET[0]}" "${DATASET[1]}" + DATASET=("${HOME}/.var/app/org.libretro.RetroArch" "${1}/RARCHGAMES") + mkdataset "${DATASET[0]}" "${DATASET[1]}" - DATASET=("${HOME}/Games" "${1}/GAMES") - mkdataset "${DATASET[0]}" "${DATASET[1]}" - ln -s "${HOME}/.var/app/com.valvesoftware.Steam" "${DATASET[0]}/Steam" - ln -s "${HOME}/.var/app/org.libretro.RetroArch" "${DATASET[0]}/libRetro" + DATASET=("${HOME}/Games" "${1}/GAMES") + mkdataset "${DATASET[0]}" "${DATASET[1]}" + ln -s "${HOME}/.var/app/com.valvesoftware.Steam" "${DATASET[0]}/Steam" + ln -s "${HOME}/.var/app/org.libretro.RetroArch" "${DATASET[0]}/libRetro" - DATASET=("${HOME}/.var/app/org.libretro.RetroArch" "${1}/RARCHGAMES") - mkdataset "${DATASET[0]}" "${DATASET[1]}" + DATASET=("${HOME}/.var/app/org.libretro.RetroArch" "${1}/RARCHGAMES") + mkdataset "${DATASET[0]}" "${DATASET[1]}" - DATASET=("${HOME}/.XXX" "${1}/XXX") - mkdir -p "${DATASET[0]}" - sudo zfs create -o keylocation=prompt -o keyformat=passphrase -o mountpoint="${DATASET[0]}" "${DATASET[1]}" + DATASET=("${HOME}/.XXX" "${1}/XXX") + mkdir -p "${DATASET[0]}" + sudo zfs create -o keylocation=prompt -o keyformat=passphrase -o mountpoint="${DATASET[0]}" "${DATASET[1]}" + elif [[ "$CUSTOMIZE_DATASETS" =~ [Yy]* ]]; then + while true; do + read -r -a DATASET -p "Define a mount path and its corresponding dataset name or route, in that order: " + + if [ ${#DATASET[@]} -eq 2 ]; then + mkdataset "${DATASET[0]}" "${1}"/"${DATASET[1]}" + + read -r -p "Create another ZFS dataset? (y/n): " ANOTHER_DATASET + + if [[ "$ANOTHER_DATASET" =~ [Yy]* ]]; then + continue + elif [[ "$ANOTHER_DATASET" =~ [Nn]* ]]; then + break + fi + else + printf "Error: must provide 2 arguments (i.e., mount path and dataset name or route)." + read -r -p "Try again? (y/n): " RETRY_PROMPT + + if [[ "$RETRY_PROMPT" =~ [Yy]* ]]; then + continue + elif [[ "$RETRY_PROMPT" =~ [Nn]* ]]; then + break + fi + fi + done + else + exit 1 + fi } print_menu () { - echo "$(<"${SCRIPT_ROOT}"/zfs-media-drive.help)" + printf "%s" "$(<"${SCRIPT_ROOT}"/zfs-media-drive.help)" } if [ -z "$1" ]; then + printf "Subcommand must be provided" exit 1 fi @@ -84,12 +116,71 @@ if [ -n "$1" ] && [ "$1" == "init" ]; then done if [ -z "$ZFS_TARGET_DRIVE" ]; then - echo "Error: It is necessary to argue a -d option." + printf "Error: It is necessary to argue a -d option." exit 1 fi + export ZFS_POOL_NAME create_zpool "$ZFS_TARGET_DRIVE" "$ZFS_POOL_NAME" "$ZFS_COMPAT" "$ZFS_KEY_LOC" "$ZFS_KEY_FORMAT" "$ZFS_COMPRESSION" + printf "Following pool has been created: \n" + zpool list -v | grep "$ZFS_POOL_NAME" create_datasets "$ZFS_POOL_NAME" + printf "Following datasets have been created: \n" + zfs list | grep "$ZFS_POOL_NAME" +elif [ -n "$1" ] && [ "$1" == "enc" ]; then + while true; do + read -r -a DATASET -p "Define a mount path and its corresponding dataset name or route, in that order: " + + if [ ${#DATASET[@]} -eq 2 ]; then + mkdir -p "${DATASET[0]}" + sudo zfs create -v -o keylocation=prompt -o keyformat=passphrase -o mountpoint="${DATASET[0]}" "${ZFS_POOL_NAME}"/"${DATASET[1]}" + + read -r -p "Create another ZFS dataset? (y/n): " ANOTHER_DATASET + + if [[ "$ANOTHER_DATASET" =~ [Yy]* ]]; then + continue + elif [[ "$ANOTHER_DATASET" =~ [Nn]* ]]; then + break + fi + else + printf "Error: must provide 2 arguments (i.e., mount path and dataset name or route)." + read -r -p "Try again? (y/n): " RETRY_PROMPT + + if [[ "$RETRY_PROMPT" =~ [Yy]* ]]; then + continue + elif [[ "$RETRY_PROMPT" =~ [Nn]* ]]; then + break + fi + fi + done +elif [ -n "$1" ] && [ "$1" == "link" ]; then + while true; do + read -r -a LINKAGE -p "Define a symbolic link source path and destination dataset: " + + if [ ${#LINKAGE[@]} -eq 2 ]; then + if ! [ -d "${LINKAGE[0]}" ]; then + mkdir -p "${LINKAGE[0]}" + fi + ln -s "${LINKAGE[0]}" "${ZFS_POOL_NAME}"/"${LINKAGE[1]}" + + read -r -p "Create another symbolic link? (y/n): " ANOTHER_LINKAGE + + if [[ "$ANOTHER_LINKAGE" =~ [Yy]* ]]; then + continue + elif [[ "$ANOTHER_LINKAGE" =~ [Nn]* ]]; then + break + fi + else + printf "Error: must provide 2 arguments (i.e., source path and destination path)." + read -r -p "Try again? (y/n): " RETRY_PROMPT + + if [[ "$RETRY_PROMPT" =~ [Yy]* ]]; then + continue + elif [[ "$RETRY_PROMPT" =~ [Nn]* ]]; then + break + fi + fi + done else while getopts "h" flag; do case "$flag" in