From: Cheng-Ling Lai Date: Tue, 21 Apr 2026 09:18:37 +0000 (+0800) Subject: Add scripts/snapper-sync to sync highest snapshot number X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=e7f3f8455bf4ccac1fc882a690e119e60b0dcc58;p=thirdparty%2Fsnapper.git Add scripts/snapper-sync to sync highest snapshot number --- diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 48a37965..ecdd04b8 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -16,7 +16,8 @@ pam_snapper_SCRIPTS = \ endif -EXTRA_DIST = snapper-hourly $(pam_snapper_SCRIPTS) +EXTRA_DIST = snapper-hourly snapper-sync $(pam_snapper_SCRIPTS) install-data-local: install -D snapper-hourly $(DESTDIR)/etc/cron.hourly/suse.de-snapper + install -D snapper-sync $(DESTDIR)/usr/sbin diff --git a/scripts/snapper-sync b/scripts/snapper-sync new file mode 100755 index 00000000..b49d07be --- /dev/null +++ b/scripts/snapper-sync @@ -0,0 +1,64 @@ +#!/bin/sh + +set -eu + +# Check for the required binaries +check_binary() { + command -v "$1" >/dev/null 2>&1 || { + echo >&2 "Error: '$1' is required but not found in PATH." + exit 1 + } +} + +check_binary jq +check_binary mkdir +check_binary snapper +check_binary snbk + +# Construct a list of dictionaries containing the necessary snapshot information, +# including the name of the backup-config, the name of the source-config, and the snapshot +# number +config_mapping=$( + snbk --machine-readable json list-configs | + jq -r '."backup-configs" | map({key: .name, value: .config}) | from_entries' +) + +if outputs=$(snbk --machine-readable json list); then + snapshots=$( + echo $outputs | + jq --argjson config_mapping "$config_mapping" ' + .snapshots | . |= map(. + {config: $config_mapping[.name]}) + ' + ) +else + echo >&2 "Error: 'snbk list' failed with exit status $?" + exit 1 +fi + +# Create the snapshot placeholder with the highest number if missing +echo "$config_mapping" | jq -r 'keys[]' | while read -r backup_config; do + + # Query the name of source-config for the currently processed backup-config + source_config=$(echo "$config_mapping" | jq -r ".[\"$backup_config\"]") + + # Query the highest snapshot number across backup-configs with the same source-config + max_num=$( + echo "$snapshots" | + jq -r "[.[] | select(.config == \"$source_config\")] | max_by(.number) | .number" + ) + + # Query the source subvolume path + subvol_path=$( + snapper --machine-readable json -c "$source_config" get-config | jq -r '.SUBVOLUME' + ) + + # Check and make the snapshot placeholder with the highest number + target_path="$subvol_path/.snapshots/$max_num" + if [ -d "$target_path" ]; then + echo "$target_path exists." + else + mkdir "$target_path" + echo "$target_path created." + fi + +done