Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zsnapshots: allow filesystem selection when no argument is specified #586

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions zfsbootmenu/bin/zsnapshots
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
# vim: softtabstop=2 shiftwidth=2 expandtab

sources=(
/lib/profiling-lib.sh
Expand All @@ -24,13 +25,40 @@ global_header() {
echo -n -e "\\033[1;33m[ Recover from snapshot ]"
}

if [ $# -ne 1 ] ; then
echo "Usage: $0 filesystem"
exit
fi
fs_header() {
echo -n -e "\\033[1;33m[ Select a filesystem ]"
}

fs="${1}"

if [ -z "${fs}" ]; then
if ! candidates="$( find_be_candidates 2>/dev/null )"; then
zerror "no root candidates found; specify a filesystem manually"
exit 1
fi

header="$( column_wrap "^[RETURN] select:[ESCAPE] cancel" )"
sort_key="$( get_sort_key )"
preview_label="Sorted by: ${sort_key^}"

if ! fs="$(
fzf --header="${header}" --prompt "Filesystem > " \
${HAS_BORDER:+--border-label="$( fs_header )"} \
${HAS_BORDER:+--preview-label-pos=2:bottom} \
${HAS_BORDER:+--preview-label="$( colorize orange " ${preview_label} " )"} \
--preview-window="up:${PREVIEW_HEIGHT}${HAS_BORDER:+,border-sharp}" \
--preview="/libexec/zfsbootmenu-preview {} '${BOOTFS}'" <<< "${candidates}"
)"; then
tput clear
exit 0;
fi
fi

if [ -z "${fs}" ]; then
zerror "a filesystem must be selected to browse snapshots"
exit 1
fi

if ! is_zfs_filesystem "${fs}" ; then
zerror "'${fs}' is not a ZFS filesystem"
exit 1
Expand Down
63 changes: 40 additions & 23 deletions zfsbootmenu/lib/zfsbootmenu-ui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -582,26 +582,17 @@ get_sort_key() {
echo -n "${sort_key:-name}"
}

# arg1: path to BE list
# prints: nothing
# returns: 0 iff at least one valid BE was found

populate_be_list() {
local be_list fs canmount mnt active candidates ret sort_key
# prints: potential boot environments, one per line
# returns: 0 if any candidate was found, 1 otherwise

be_list="${1}"
if [ -z "${be_list}" ]; then
zerror "be_list is undefined"
return 1
fi
zdebug "be_list set to ${be_list}"
find_be_candidates() {
local fs mnt active ret sort_key list_fields have_bootfs

list_fields="name,canmount,mountpoint,org.zfsbootmenu:active"
sort_key="$( get_sort_key )"

# Truncate the list to avoid stale entries
: > "${be_list}"

# Find valid BEs
ret=1
have_bootfs=
while IFS=$'\t' read -r fs canmount mnt active; do
if [ "${mnt}" = "/" ]; then
# When mountpoint=/, BE is a candidate unless org.zfsbootmenu:active=off
Expand All @@ -613,8 +604,10 @@ populate_be_list() {
# All other datasets are ignored
continue
fi

# If BOOTFS is defined, we'll manually append it to the array
if [ "${BOOTFS}" = "${fs}" ] ; then
# If BOOTFS is defined, we'll manually append it to the array
have_bootfs="yes"
continue
fi

Expand All @@ -623,14 +616,38 @@ populate_be_list() {
zwarn "canmount=on set for '${fs}', should be canmount=noauto"
fi

candidates+=( "${fs}" )
done <<< "$(zfs list -H -o name,canmount,mountpoint,org.zfsbootmenu:active -S "${sort_key}")"
echo "${fs}"
ret=0
done <<< "$( zfs list -H -o "${list_fields}" -S "${sort_key}" )"

# put bootfs at the end
if [ -n "${BOOTFS}" ] && [ -n "${have_bootfs}" ]; then
echo "${BOOTFS}"
ret=0
fi

return "${ret}"
}

# arg1: path to BE list
# prints: nothing
# returns: 0 iff at least one valid BE was found

populate_be_list() {
local be_list fs ret

be_list="${1}"
if [ -z "${be_list}" ]; then
zerror "be_list is undefined"
return 1
fi
zdebug "be_list set to ${be_list}"

# put bootfs on the end, so it is shown first with --tac
[ -n "${BOOTFS}" ] && candidates+=( "${BOOTFS}" )
# Truncate the list to avoid stale entries
: > "${be_list}"

ret=1
for fs in "${candidates[@]}"; do
while read -r fs; do
# Remove any existing cmdline cache
rm -f "$( be_location "${fs}" )/cmdline"

Expand All @@ -642,6 +659,6 @@ populate_be_list() {
echo "${fs}" >> "${be_list}"
ret=0
fi
done
done <<< "$( find_be_candidates 2>/dev/null )"
return $ret
}
Loading