summaryrefslogtreecommitdiff
path: root/alt-prune-rclone-rm.sh
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-10-07 15:48:37 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-10-07 15:48:37 -0700
commite518cc47b1aae229fd46998eb196b6033923555e (patch)
tree1df1a914ec21dedfee13ba1ffd453c8a70d807b7 /alt-prune-rclone-rm.sh
parente39fdea1257a3addca1c6c20860c82dfa98ad7cc (diff)
downloadbackomp-e518cc47b1aae229fd46998eb196b6033923555e.tar.gz
backomp-e518cc47b1aae229fd46998eb196b6033923555e.tar.xz
add alt-prune hook for rclone rm over sshHEADmaster
Diffstat (limited to 'alt-prune-rclone-rm.sh')
-rwxr-xr-xalt-prune-rclone-rm.sh73
1 files changed, 73 insertions, 0 deletions
diff --git a/alt-prune-rclone-rm.sh b/alt-prune-rclone-rm.sh
new file mode 100755
index 0000000..6e3eeb2
--- /dev/null
+++ b/alt-prune-rclone-rm.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+#
+# Copyright 2023 David Vazgenovich Shakaryan
+
+qargs() {
+ local arg str
+
+ for arg; do
+ [[ "${arg:-*}" =~ [^A-Za-z0-9%+./:=@_-] ]] && arg="${arg@Q}"
+ str+=" ${arg}"
+ done
+ printf '%s\n' "${str:1}"
+}
+
+target="${1}"
+
+[[ "${target}" =~ ^(rclone://([^:]+):)(.+) ]] || exit 1
+prefix="${BASH_REMATCH[1]}"
+remote="${BASH_REMATCH[2]}"
+path="${BASH_REMATCH[3]}"
+
+conf="$(rclone config dump)" || exit 1
+read -rd '' JQ <<'EOF'
+.[$k]
+| select(.type == "crypt" or .type == "sftp") // error("not crypt or sftp")
+| [.type, .remote]
+| @tsv
+EOF
+IFS=$'\t' read -r r_type r_remote < <(
+ jq -rc --arg k "${remote}" "${JQ}" <<<"${conf}") || exit 1
+
+if [[ "${r_type}" == 'crypt' ]]; then
+ crypt="${remote}"
+
+ [[ "${r_remote}" =~ ^([^:]+):(.*) ]] || exit 1
+ remote="${BASH_REMATCH[1]}"
+ base="${BASH_REMATCH[2]:+${BASH_REMATCH[2]}/}"
+
+ upath=0
+ while IFS=$'\t' read -r k v; do
+ [[ "${k% }" == "${path}" ]] && path="${base}${v# }" && upath=1
+ done < <(rclone cryptdecode --reverse "${crypt}:" "${path}")
+ wait "$!" || exit 1
+ ((upath)) || exit 1
+fi
+
+read -rd '' JQ <<'EOF'
+.[$k]
+| select(.type == "sftp") // error("not sftp")
+| select(.key_file_pass | not) // error("key uses passphrase")
+| [
+ (.key_file | select(.) // error("missing key")
+ | "-i", (sub("^~"; env.HOME) | @sh)),
+ (.known_hosts_file | select(.)
+ | "-o", ("UserKnownHostsFile=\(sub("^~"; env.HOME))" | @sh)),
+ (.port | select(.) | "-p", @sh),
+ ("\(.user // error("missing user"))@\(.host // error("missing host"))"
+ | @sh)
+]
+| join(" ")
+EOF
+mapfile -td '' args < <(
+ jq -rc --arg k "${remote}" "${JQ}" <<<"${conf}" | \
+ xargs -r printf '%s\0'
+ [[ "${PIPESTATUS[0]}" -eq 0 && "${PIPESTATUS[1]}" -eq 0 ]])
+wait "$!" || exit 1
+
+ssh_cmd=(ssh -o BatchMode=yes "${args[@]}")
+cmd=("${ssh_cmd[@]}"
+ "rm -rf $(printf '%q' "${path}")")
+echo "* $(qargs "${cmd[@]}")"
+"${cmd[@]}" || exit 1
+exit 0