|
33 | 33 | # init |
34 | 34 | opt_backupcfg_list='' # -b |
35 | 35 | opt_checksums='0' # -c |
36 | | -opt_luks_target_uuid='' # -d |
| 36 | +opt_luks_targets_list='' # -d |
37 | 37 | opt_email_to='' # -e |
38 | 38 | opt_email_from='' # -f |
39 | 39 | opt_email_cc='' # -g |
|
66 | 66 | opt_checksums='1' |
67 | 67 | ;; |
68 | 68 |
|
69 | | - # disk UUID |
| 69 | + # list of disk labels or UUIDs |
70 | 70 | 'd') |
71 | | - opt_luks_target_uuid="${OPTARG}" |
72 | | - if ! printf '%s' "${opt_luks_target_uuid}" | grep -E -q -e "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" |
| 71 | + opt_luks_targets_list="${OPTARG}" |
| 72 | + if [ -z "${opt_luks_targets_list}" ] |
73 | 73 | then |
74 | | - opt_email_to='' |
| 74 | + opt_luks_targets_list='' |
75 | 75 | printf '%s: Invalid value for "%s", ignoring it.\n' "$(basename "${0}")" "${opt}" 1>&2 |
76 | 76 | exit 2 |
77 | 77 | fi |
@@ -179,7 +179,7 @@ USB drives, including proper logging and optional email notifications. |
179 | 179 | .PP |
180 | 180 | .BI "-b " "PveID[:maxCount[,PveID:maxCount[,...]]]" "" |
181 | 181 | .B [-c] |
182 | | -.BI "[-d " "UUID of a disk to decrypt" "]" |
| 182 | +.BI "[-d " "pve_backup_disk_label[,UUID[,...]]" |
183 | 183 | .BI "[-e " "[email protected]" "]" |
184 | 184 | .BI "[-f " "[email protected]" "]" |
185 | 185 | |
@@ -210,15 +210,17 @@ Enable checksum creation and verification of the copies (recommended for |
210 | 210 | safety but probably doubles the time needed for completing the backup task). |
211 | 211 | .TP |
212 | 212 | .B -d |
213 | | -A UUID of the target partition to decrypt. Will be used to search it in |
214 | | -/dev/disk/by-uuid/ (you might use 'blkid /dev/sdX1' to determine the UUID). |
215 | | -By default, the script is simply using the first partition on the first USB |
216 | | -disk it is able to find via /dev/disk/by-path/. No worries: existing drives |
217 | | -not used for backups won't be destroyed as the decryption will fail. But this |
218 | | -automatism presumes that only one USB disk is connected during the |
219 | | -script run. Defining a UUID will work if there are multiple disks (e.g. when |
220 | | -it is not feasible in your environment to just have one disk connected |
221 | | -simultaneously). |
| 213 | +By default, the script searches the following locations for a partition to use |
| 214 | +as the backup target for decryption and mounting: |
| 215 | +1. The first partition labeled "pve_backup_usb" listed under /dev/disk/by-label/. |
| 216 | +2. The first partition on the first USB disk found via /dev/disk/by-path/. |
| 217 | +No need to worry: existing partitions or drives not intended for backups will |
| 218 | +not be destroyed, as decryption will simply fail, and the script will stop. |
| 219 | +If this automated behavior does not match your environment, you can provide a |
| 220 | +custom list of disk labels or UUIDs to search before the default locations are |
| 221 | +checked. Separate multiple targets with commas (CSV format). Any given UUID |
| 222 | +will be searched under /dev/disk/by-uuid/, while any other string matching the |
| 223 | +pattern "^[0-9a-zA-Z_ \-]{1,16}$" will be searched under /dev/disk/by-label/. |
222 | 224 | .TP |
223 | 225 | .B -e |
224 | 226 | Email address to send notifications to. Format: '[email protected]'. |
|
322 | 324 | IFS=',' read -r -a backupcfg_array <<< "${opt_backupcfg_list}" |
323 | 325 | readonly backupcfg_array |
324 | 326 |
|
325 | | -if [ -z "${opt_luks_target_uuid}" ] |
| 327 | +if [ -z "${opt_luks_targets_list}" ] |
326 | 328 | then |
327 | | - readonly luks_target_uuid="" |
| 329 | + readonly luks_targets_list="" |
328 | 330 | else |
329 | | - readonly luks_target_uuid="${opt_luks_target_uuid}" |
| 331 | + readonly luks_targets_list="${opt_luks_targets_list}" |
330 | 332 | fi |
| 333 | +IFS=',' read -r -a luks_targets_array <<< "${luks_targets_list}" |
| 334 | +readonly luks_targets_array |
331 | 335 |
|
332 | 336 | if [ -z "${opt_backup_user}" ] |
333 | 337 | then |
@@ -796,14 +800,72 @@ then |
796 | 800 | fi |
797 | 801 |
|
798 | 802 |
|
799 | | -# determine target device |
| 803 | +# determine target device partition |
800 | 804 | luks_target="" |
801 | | -if [ -n "${luks_target_uuid}" ] |
| 805 | +message="Searching for target partition at" |
| 806 | +for luks_target in "${luks_targets_array[@]}" |
| 807 | +do |
| 808 | + # UUID of a partition |
| 809 | + if [ -n "${luks_target}" ] && |
| 810 | + printf '%s' "${luks_target}" | grep -E -q -e "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" |
| 811 | + then |
| 812 | + luks_target="/dev/disk/by-uuid/${luks_target}" |
| 813 | + if [ -L "${luks_target}" ] |
| 814 | + then |
| 815 | + message "${message} '${luks_target}'... found." |
| 816 | + break 1 |
| 817 | + else |
| 818 | + message "${message} '${luks_target}'... not found, continuing." |
| 819 | + fi |
| 820 | + |
| 821 | + # label of a partition |
| 822 | + elif [ -n "${luks_target}" ] && |
| 823 | + printf '%s' "${luks_target}" | grep -E -q -e "^[0-9a-zA-Z_ \-]{1,16}$" |
| 824 | + then |
| 825 | + luks_target="/dev/disk/by-label/${luks_target}" |
| 826 | + if [ -L "${luks_target}" ] |
| 827 | + then |
| 828 | + message "${message} '${luks_target}'... found." |
| 829 | + break 1 |
| 830 | + else |
| 831 | + message "${message} '${luks_target}'... not found, continuing." |
| 832 | + fi |
| 833 | + |
| 834 | + # invalid value |
| 835 | + elif [ -n "${luks_target}" ] |
| 836 | + then |
| 837 | + message "Invalid value '${luks_target}' (has to be a valid partition label or UUID, check '-d' parameter), continuing." "warning" |
| 838 | + fi |
| 839 | + |
| 840 | + # nothing was found (yet) |
| 841 | + luks_target="" |
| 842 | +done |
| 843 | +# use the first partition with a "pve_backup_usb" label if no (useable) target was specified or found |
| 844 | +if [ -z "${luks_target}" ] |
802 | 845 | then |
803 | | - luks_target="/dev/disk/by-uuid/${luks_target_uuid}" |
804 | | -else |
| 846 | + luks_target="/dev/disk/by-label/pve_backup_usb" |
| 847 | + if [ -L "${luks_target}" ] |
| 848 | + then |
| 849 | + message "${message} '${luks_target}'... found." |
| 850 | + else |
| 851 | + message "${message} '${luks_target}'... not found, continuing." |
| 852 | + fi |
| 853 | +fi |
| 854 | +# use the first partition of the first usb storage device if no (useable) target was specified or found |
| 855 | +if [ -z "${luks_target}" ] |
| 856 | +then |
| 857 | + |
805 | 858 | luks_target="/dev/$(ls -l /dev/disk/by-path/*usb*part1 | cut -f 7 -d "/" | head -n 1)" |
| 859 | + if [ -b "${luks_target}" ] |
| 860 | + then |
| 861 | + message "${message} '${luks_target}'... found." |
| 862 | + else |
| 863 | + message "${message} '${luks_target}'... not found." |
| 864 | + endScript "Could not determine any target partition for decryption (backup storage device available?)." "error" |
| 865 | + exit 1 # endScript should exit, this is just a fallback |
| 866 | + fi |
806 | 867 | fi |
| 868 | +unset message |
807 | 869 |
|
808 | 870 |
|
809 | 871 | # unlock target device |
|
1097 | 1159 | if [ $exitcode_sha1sum -ne 0 ] |
1098 | 1160 | then |
1099 | 1161 | errors_during_backup="1" |
1100 | | - message="Creating checksums file failed with exit code $exitcode_sha1sum." |
| 1162 | + message="Creating checksums file failed with exit code ${exitcode_sha1sum}." |
1101 | 1163 | # continue on error |
1102 | 1164 | if [ "${opt_continue_on_backuperror}" = "1" ] |
1103 | 1165 | then |
|
0 commit comments