Enhance cloud storage handling and configuration documentation
- Updated `ssr.conf.example` to clarify the usage of `SSR_CLOUD_PATH` for custom cloud providers, including examples for handling multiple folders. - Introduced `ssr::cloud::resolve_storage_pattern` function in `lib/cloud.sh` to improve directory resolution for cloud storage providers, ensuring proper handling of multiple matches. - Refactored `ssr::cloud::resolve_dir` to utilize the new storage resolution function, enhancing error handling and user feedback for cloud directory detection.
This commit is contained in:
@@ -9,7 +9,12 @@
|
|||||||
# Provider: icloud | dropbox | googledrive | onedrive | custom
|
# Provider: icloud | dropbox | googledrive | onedrive | custom
|
||||||
SSR_CLOUD_PROVIDER=icloud
|
SSR_CLOUD_PROVIDER=icloud
|
||||||
|
|
||||||
# Only used when SSR_CLOUD_PROVIDER=custom. Absolute path.
|
# Absolute path. Required for SSR_CLOUD_PROVIDER=custom.
|
||||||
|
# For onedrive / googledrive / dropbox: if macOS has more than one matching
|
||||||
|
# folder under ~/Library/CloudStorage (e.g. "OneDrive" and "OneDrive - Adobe"),
|
||||||
|
# you must set SSR_CLOUD_PATH to the root you want so SSR does not pick at random.
|
||||||
|
# Example (quote if the folder name contains spaces):
|
||||||
|
# SSR_CLOUD_PATH="/Users/you/Library/CloudStorage/OneDrive - Adobe"
|
||||||
# SSR_CLOUD_PATH=/Volumes/MyNAS/macos-sync
|
# SSR_CLOUD_PATH=/Volumes/MyNAS/macos-sync
|
||||||
|
|
||||||
# Subfolder inside the cloud root for SSR data: per-host backups live under
|
# Subfolder inside the cloud root for SSR data: per-host backups live under
|
||||||
|
|||||||
+70
-8
@@ -2,6 +2,66 @@
|
|||||||
# lib/cloud.sh — cloud storage provider abstraction.
|
# lib/cloud.sh — cloud storage provider abstraction.
|
||||||
# Resolves SSR_CLOUD_DIR based on SSR_CLOUD_PROVIDER from config.
|
# Resolves SSR_CLOUD_DIR based on SSR_CLOUD_PROVIDER from config.
|
||||||
|
|
||||||
|
# Echo one directory under ~/Library/CloudStorage matching find -name "$1".
|
||||||
|
# $2 = label for errors (e.g. OneDrive). $3 = optional fallback dir if zero matches.
|
||||||
|
# If several folders match (e.g. personal + work OneDrive), SSR_CLOUD_PATH must
|
||||||
|
# be set to the absolute path of the chosen root (same as one of the matches);
|
||||||
|
# otherwise we abort with a list of candidates. Tilde in SSR_CLOUD_PATH is expanded.
|
||||||
|
ssr::cloud::resolve_storage_pattern() {
|
||||||
|
local pattern="$1" label="$2" zero_fallback="${3:-}"
|
||||||
|
local cs="$HOME/Library/CloudStorage"
|
||||||
|
local custom="${SSR_CLOUD_PATH:-}"
|
||||||
|
case "$custom" in
|
||||||
|
'~' | '~'/*) custom="${custom/#\~/$HOME}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local matches=()
|
||||||
|
local d
|
||||||
|
if [[ -d "$cs" ]]; then
|
||||||
|
while IFS= read -r d; do
|
||||||
|
[[ -n "$d" && -d "$d" ]] && matches+=("$d")
|
||||||
|
done < <(find "$cs" -maxdepth 1 -type d -name "$pattern" 2>/dev/null | LC_ALL=C sort -u)
|
||||||
|
fi
|
||||||
|
|
||||||
|
local n="${#matches[@]}"
|
||||||
|
if [[ "$n" -eq 0 ]]; then
|
||||||
|
if [[ -n "$zero_fallback" && -d "$zero_fallback" ]]; then
|
||||||
|
printf '%s\n' "$zero_fallback"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
ssr::die "$label folder not found under ~/Library/CloudStorage"
|
||||||
|
fi
|
||||||
|
if [[ "$n" -eq 1 ]]; then
|
||||||
|
printf '%s\n' "${matches[0]}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$custom" ]]; then
|
||||||
|
ssr::err "Multiple $label folders found; set SSR_CLOUD_PATH in ssr.conf to the root you want (absolute path), or use SSR_CLOUD_PROVIDER=custom."
|
||||||
|
for d in "${matches[@]}"; do ssr::err " $d"; done
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ssr::validate_path "$custom"
|
||||||
|
[[ -d "$custom" ]] || ssr::die "SSR_CLOUD_PATH is not a directory: $custom"
|
||||||
|
|
||||||
|
local abs_c abs_m picked=""
|
||||||
|
abs_c="$(cd "$custom" && pwd -P)" || ssr::die "SSR_CLOUD_PATH not accessible: $custom"
|
||||||
|
for d in "${matches[@]}"; do
|
||||||
|
abs_m="$(cd "$d" && pwd -P)" || continue
|
||||||
|
if [[ "$abs_m" == "$abs_c" ]]; then
|
||||||
|
picked="$d"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [[ -z "$picked" ]]; then
|
||||||
|
ssr::err "SSR_CLOUD_PATH=$custom is not one of the detected $label roots:"
|
||||||
|
for d in "${matches[@]}"; do ssr::err " $d"; done
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$picked"
|
||||||
|
}
|
||||||
|
|
||||||
ssr::cloud::resolve_dir() {
|
ssr::cloud::resolve_dir() {
|
||||||
local provider="${SSR_CLOUD_PROVIDER:-icloud}" custom="${SSR_CLOUD_PATH:-}"
|
local provider="${SSR_CLOUD_PROVIDER:-icloud}" custom="${SSR_CLOUD_PATH:-}"
|
||||||
|
|
||||||
@@ -10,23 +70,25 @@ ssr::cloud::resolve_dir() {
|
|||||||
printf '%s\n' "$HOME/Library/Mobile Documents/com~apple~CloudDocs"
|
printf '%s\n' "$HOME/Library/Mobile Documents/com~apple~CloudDocs"
|
||||||
;;
|
;;
|
||||||
dropbox)
|
dropbox)
|
||||||
if [[ -d "$HOME/Library/CloudStorage" ]]; then
|
if [[ ! -d "$HOME/Library/CloudStorage" ]]; then
|
||||||
find "$HOME/Library/CloudStorage" -maxdepth 1 -type d -name 'Dropbox*' -print -quit 2>/dev/null \
|
[[ -d "$HOME/Dropbox" ]] || ssr::die "Dropbox not found (no ~/Library/CloudStorage and no ~/Dropbox)."
|
||||||
|| printf '%s\n' "$HOME/Dropbox"
|
|
||||||
else
|
|
||||||
printf '%s\n' "$HOME/Dropbox"
|
printf '%s\n' "$HOME/Dropbox"
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
|
ssr::cloud::resolve_storage_pattern 'Dropbox*' 'Dropbox' "$HOME/Dropbox"
|
||||||
;;
|
;;
|
||||||
googledrive)
|
googledrive)
|
||||||
find "$HOME/Library/CloudStorage" -maxdepth 1 -type d -name 'GoogleDrive-*' -print -quit 2>/dev/null \
|
ssr::cloud::resolve_storage_pattern 'GoogleDrive-*' 'Google Drive' ''
|
||||||
|| ssr::die "Google Drive folder not found under ~/Library/CloudStorage"
|
|
||||||
;;
|
;;
|
||||||
onedrive)
|
onedrive)
|
||||||
find "$HOME/Library/CloudStorage" -maxdepth 1 -type d -name 'OneDrive-*' -print -quit 2>/dev/null \
|
ssr::cloud::resolve_storage_pattern 'OneDrive-*' 'OneDrive' ''
|
||||||
|| ssr::die "OneDrive folder not found under ~/Library/CloudStorage"
|
|
||||||
;;
|
;;
|
||||||
custom)
|
custom)
|
||||||
[[ -n "$custom" ]] || ssr::die "SSR_CLOUD_PROVIDER=custom requires SSR_CLOUD_PATH"
|
[[ -n "$custom" ]] || ssr::die "SSR_CLOUD_PROVIDER=custom requires SSR_CLOUD_PATH"
|
||||||
|
case "$custom" in
|
||||||
|
'~' | '~'/*) custom="${custom/#\~/$HOME}" ;;
|
||||||
|
esac
|
||||||
|
ssr::validate_path "$custom"
|
||||||
printf '%s\n' "$custom"
|
printf '%s\n' "$custom"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
Reference in New Issue
Block a user