Commit d2fa21b5 authored by Martin Potthast's avatar Martin Potthast

Delete snapshot.sh

parent f1d4cc62
#!/usr/bin/env bash
### \b
### Cephfs snapshot utilities
### \b
### Author: Alban Bruder
### Year: 2020-today
. "${WEBIS_LIB_PATH}/bashhelper.sh"
check_tools "realpath"
### Create a snapshot in PATH.
###
### 'cephfs-snap -t hourly -n 24 /mnt/server'
### would make a snapshot in /mnt/server/.snap/ called hourly_<date>_<time>
### where <date> is on the form YYYY-MM-DD and <time> is on the form
### HH:MM:SS. This format makes shure snapshot names sort correctly in
### cronological order even when sorted alphabetically. The 24 newest
### snapshots matching the prefix are kept around. The rest are deleted.
###
### : path : dpath! : .
### : -t : --tag : str : manual : Snapshot tag
### : -n : --num : int :: Number of snapshots with the given tag
cmd_create() {
ARG_PATH="$(realpath "$ARG_PATH")"
if [[ "$ARG_TAG" =~ [^a-zA-Z0-9] ]]; then
logError "Only alphanumeric characters are allowed as tag."
exit 1
fi
if [[ -z "$ARG_NUM" ]]; then
ARG_NUM="-1"
fi
newsnap="${ARG_PATH}/.snap/${ARG_TAG}_$(date +'%Y%m%d_%H%M%S')"
# Create snapshot
if [ ! "$ARG_NUM" -eq 0 ] ; then
mkdir -p "${newsnap}"
if [ $? -eq 0 ] ; then
logInfo "Created cephfs snapshot: ${newsnap}"
else
logError "Error creating cephfs snapshot: ${newsnap}"
fi
fi
# Remove snapshots
if [ "$ARG_NUM" -gt -1 ] ; then
ls -dr ${ARG_PATH}/.snap/${ARG_TAG}_* | tail -n +$(( $ARG_NUM+1 )) | while read oldsnap ; do
rmdir "${oldsnap}" 2>&1
if [ $? -eq 0 ] ; then
logInfo "Removed cephfs snapshot: ${oldsnap}"
else
logError "Error removing cephfs snapshot: ${oldsnap}"
fi
done
fi
}
### List snapshots that include PATH.
###
### : path : path : .
### : -t : --tag : str :: Snapshot tag
cmd_list() {
snappattern=^.
if [[ ! -z "$ARG_TAG" ]]; then
snappattern="${ARG_TAG}_*_*"
fi
prefix="$(realpath -m "$ARG_PATH")"
suffix=""
# list snapshots
while [[ "$prefix" != "/" ]]; do
ls -d -1a "${prefix}"/.snap/* 2>/dev/null | while read snap ; do
if [[ -e "$snap/$suffix" ]] && { [[ -z "$ARG_TAG" ]] || [[ "$(basename $snap)" =~ ^"$ARG_TAG"_[0-9]{8}_[0-9]{6}$ ]]; }; then
if [[ "$(basename $snap)" =~ ^[a-zA-Z0-9]*_[0-9]{8}_[0-9]{6}$ ]]; then
snap_date="$(basename $snap | awk -F'_' '{print substr($2,1,4) "-" substr($2,5,2) "-" substr($2,7,2) " " substr($3,1,2) ":" substr($3,3,2) ":" substr($3,5,2)}')"
snap_tag="$(basename $snap | awk -F'_' '{print $1}')"
else
snap_date="$(date -r "$snap" "+%Y-%m-%d %H:%M:%S")"
snap_tag="$(basename $snap)"
fi
echo "$snap_date $snap_tag $(echo "$snap/$suffix" | sed 's/\/$//g')"
fi
done
suffix="$(echo "$(basename "$prefix")/$suffix" | sed 's/\/$//g')"
prefix="$(dirname "$prefix")"
done | sort -r
}
### Restore PATH from snapshot.
###
### Can recover individual files or folders or entire snapshots.
### Unless otherwise specified, the TARGET matches the PATH.
###
### : path : path : .
### : target : path : .
### : -t : --tag : str :: Snapshot tag
### : -n : --num : int : 10 : Number of snapshots to list
### : -d : --diff ::: Show diff before restoring the snapshot
### : -r : --rsync ::: Use rsync for the restoration (will delete files that are in TARGET but not in the selected snapshot)
cmd_restore() {
if [[ ! -z "$ARG_DIFF" ]]; then
check_tools "git"
fi
if [[ ! -z "$ARG_RSYNC" ]]; then
check_tools "rsync"
fi
path="$(realpath -m $ARG_PATH)"
if [[ "$ARG_TARGET" == "." && "$ARG_PATH" != "." ]]; then
target="$path"
else
target="$(realpath -m $ARG_TARGET)"
fi
IFS=$'\n'
snapshots=($(exec_sub_cmd list -t "$ARG_TAG" "$path" | head -n $ARG_NUM))
if [[ "${#snapshots[@]}" -eq 0 ]]; then
logWarning "No snapshots found for: $path"
exit 1
fi
logInfo "Select a snapshot:"
select snap in "${snapshots[@]}"; do
if [ "$REPLY" -lt 1 ] || [ "$REPLY" -gt "${#snapshots[@]}" ]; then
logError "Invalid selection."
else
snap="$(echo "$snap" | awk '{print $4}')"
logInfo "You selected: $snap"
break
fi
done
if ! [ -z "$ARG_DIFF" ]; then
git diff -D --no-index --no-renames --no-prefix --summary "$(realpath --relative-to=$(pwd) $snap)" "$(realpath --relative-to=$(pwd) $target)"
fi
yes_no_prompt "Are your sure you want to restore '$(realpath --relative-to=$(pwd) $snap)' to '$(realpath --relative-to=$(pwd) $target)'?" || exit 1
restore_cmd=(cp -a)
if [[ ! -z "$ARG_RSYNC" ]]; then
restore_cmd=(rsync --delete -a --exclude=".snap/")
fi
if [[ -d "$snap" ]]; then
"${restore_cmd[@]}" "$snap/." "$target/"
else
"${restore_cmd[@]}" "$snap" "$target"
fi
logInfo "Snapshot restored."
}
exec_sub_cmd "$@"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment