@@ -47,7 +47,7 @@ log_level() {
47
47
else
48
48
display=" -"
49
49
fi
50
- else
50
+ else
51
51
if [ " $level " = " info" ]; then
52
52
display=" ${GREEN} INFO${NC} "
53
53
elif [ " $level " = " warn" ]; then
@@ -89,7 +89,7 @@ log_rsync(){
89
89
90
90
log_ssh (){
91
91
log_level " ssh" " $1 "
92
- }
92
+ }
93
93
94
94
# Assume this script lives in share/github-backup-utils/ when setting the root
95
95
GHE_BACKUP_ROOT=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) /../.." && pwd) "
@@ -150,15 +150,15 @@ export GHE_RESTORE_IN_PROGRESS
150
150
export GHE_BACKUP_IN_PROGRESS
151
151
152
152
ghe_restore_check () {
153
- if [ -h $GHE_RESTORE_IN_PROGRESS ]; then
153
+ if [ -h " $GHE_RESTORE_IN_PROGRESS " ]; then
154
154
echo " Error: detected a restore already in progress from a previous version of ghe-restore." 1>&2
155
155
echo " If there is no restore in progress anymore, please remove" 1>&2
156
156
echo " the $GHE_RESTORE_IN_PROGRESS file and try again." 1>&2
157
157
exit 1
158
158
fi
159
159
160
- if [ -f $GHE_RESTORE_IN_PROGRESS ]; then
161
- progress=$( cat $GHE_RESTORE_IN_PROGRESS )
160
+ if [ -f " $GHE_RESTORE_IN_PROGRESS " ]; then
161
+ progress=$( cat " $GHE_RESTORE_IN_PROGRESS " )
162
162
pid=$( echo " $progress " | cut -d ' ' -f 2)
163
163
echo " Error: A restore of $GHE_HOSTNAME may still be running on PID $pid ." 1>&2
164
164
echo " If PID $pid is not a process related to the restore utilities, please remove" 1>&2
@@ -168,15 +168,15 @@ ghe_restore_check() {
168
168
}
169
169
170
170
ghe_backup_check () {
171
- if [ -h $GHE_BACKUP_IN_PROGRESS ]; then
171
+ if [ -h " $GHE_BACKUP_IN_PROGRESS " ]; then
172
172
echo " Error: detected a backup already in progress from a previous version of ghe-backup." 1>&2
173
173
echo " If there is no backup in progress anymore, please remove" 1>&2
174
174
echo " the $GHE_DATA_DIR /$GHE_BACKUP_IN_PROGRESS file and try again." 1>&2
175
175
exit 1
176
176
fi
177
177
178
- if [ -f $GHE_BACKUP_IN_PROGRESS ]; then
179
- progress=$( cat $GHE_BACKUP_IN_PROGRESS )
178
+ if [ -f " $GHE_BACKUP_IN_PROGRESS " ]; then
179
+ progress=$( cat " $GHE_BACKUP_IN_PROGRESS " )
180
180
pid=$( echo " $progress " | cut -d ' ' -f 2)
181
181
echo " Error: A backup of $GHE_HOSTNAME may still be running on PID $pid ." 1>&2
182
182
echo " If PID $pid is not a process related to the backup utilities, please remove" 1>&2
@@ -186,14 +186,14 @@ ghe_backup_check() {
186
186
}
187
187
188
188
ghe_restore_finished () {
189
- if [ -f $GHE_RESTORE_IN_PROGRESS ]; then
190
- rm -f $GHE_RESTORE_IN_PROGRESS
189
+ if [ -f " $GHE_RESTORE_IN_PROGRESS " ]; then
190
+ rm -f " $GHE_RESTORE_IN_PROGRESS "
191
191
fi
192
192
}
193
193
194
194
ghe_backup_finished () {
195
- if [ -f $GHE_BACKUP_IN_PROGRESS ]; then
196
- rm -f $GHE_BACKUP_IN_PROGRESS
195
+ if [ -f " $GHE_BACKUP_IN_PROGRESS " ]; then
196
+ rm -f " $GHE_BACKUP_IN_PROGRESS "
197
197
fi
198
198
}
199
199
@@ -265,7 +265,7 @@ if [ -n "$GHE_VERBOSE" ]; then
265
265
exec 3>> " $GHE_VERBOSE_LOG "
266
266
log_info " $calling_script_name $* " 1>&3
267
267
else
268
- # colorize the input if supported.
268
+ # colorize the input if supported.
269
269
display_caller=" ${BLUE} $calling_script_name ${NC} "
270
270
exec 3>> " $GHE_VERBOSE_LOG "
271
271
log_info " $display_caller $* " 1>&3
@@ -327,11 +327,11 @@ if [ ! -d "$GHE_DATA_DIR" ]; then
327
327
fi
328
328
329
329
# Set some defaults if needed.
330
- : ${GHE_NUM_SNAPSHOTS:= 10}
330
+ : " ${GHE_NUM_SNAPSHOTS:= 10} "
331
331
332
332
# Generate a backup timestamp if one has not already been generated.
333
333
# We export the variable so the process group shares the same value.
334
- : ${GHE_SNAPSHOT_TIMESTAMP:= $(date +" %Y%m%dT%H%M%S" )}
334
+ : " ${GHE_SNAPSHOT_TIMESTAMP:= $(date +" %Y%m%dT%H%M%S" )} "
335
335
export GHE_SNAPSHOT_TIMESTAMP
336
336
337
337
# Set the current snapshot directory to <data-dir>/<timestamp>. This is where
@@ -341,50 +341,50 @@ export GHE_SNAPSHOT_DIR
341
341
342
342
# The root filesystem location. This must be used so that tests can override
343
343
# the root as a local directory location.
344
- : ${GHE_REMOTE_ROOT_DIR:= " " }
344
+ : " ${GHE_REMOTE_ROOT_DIR:= " " } "
345
345
346
346
# The root location of persistent data and applications on the remote side. This
347
347
# is always "/data" for GitHub instances. Use of this variable allows
348
348
# the location to be overridden in tests.
349
- : ${GHE_REMOTE_DATA_DIR:= " /data" }
349
+ : " ${GHE_REMOTE_DATA_DIR:= " /data" } "
350
350
351
351
# The root location of user data stores such as git repositories, pages sites,
352
352
# elasticsearch indices, etc. This is "/data" under 1.x filesystem layouts and
353
353
# "/data/user" under the 2.x filesystem layout. The location is adjusted
354
354
# dynamically in ghe_remote_version_config() immediately after obtaining the
355
355
# remote version. Utilities that transfer data in and out of the appliance
356
356
# should use this variable to ensure proper behavior under different versions.
357
- : ${GHE_REMOTE_DATA_USER_DIR:= " $GHE_REMOTE_DATA_DIR " }
357
+ : " ${GHE_REMOTE_DATA_USER_DIR:= " $GHE_REMOTE_DATA_DIR " } "
358
358
359
359
# The location of the license file on the remote side. This is always
360
360
# "/data/enterprise/enterprise.ghl" for GitHub instances. Use of this variable
361
361
# allows the location to be overridden in tests.
362
- : ${GHE_REMOTE_LICENSE_FILE:= " $GHE_REMOTE_DATA_DIR /enterprise/enterprise.ghl" }
362
+ : " ${GHE_REMOTE_LICENSE_FILE:= " $GHE_REMOTE_DATA_DIR /enterprise/enterprise.ghl" } "
363
363
364
364
# The number of seconds to wait for in progress git-gc processes to complete
365
365
# before starting the sync of git data. See share/github-backup-utils/ghe-backup-repositories-rsync
366
366
# for more information. Default: 10 minutes.
367
- : ${GHE_GIT_COOLDOWN_PERIOD:= 600}
367
+ : " ${GHE_GIT_COOLDOWN_PERIOD:= 600} "
368
368
369
369
# Set "true" to get verbose logging of all ssh commands on stderr
370
- : ${GHE_VERBOSE_SSH:= false}
370
+ : " ${GHE_VERBOSE_SSH:= false} "
371
371
372
372
# The location of the cluster configuration file on the remote side.
373
373
# This is always "/data/user/common/cluster.conf" for GitHub Cluster instances.
374
374
# Use of this variable allows the location to be overridden in tests.
375
- : ${GHE_REMOTE_CLUSTER_CONF_FILE:= " $GHE_REMOTE_DATA_DIR /user/common/cluster.conf" }
375
+ : " ${GHE_REMOTE_CLUSTER_CONF_FILE:= " $GHE_REMOTE_DATA_DIR /user/common/cluster.conf" } "
376
376
377
377
# The location of the file used to disable GC operations on the remote side.
378
- : ${SYNC_IN_PROGRESS_FILE:= " $GHE_REMOTE_DATA_USER_DIR /repositories/.sync_in_progress" }
378
+ : " ${SYNC_IN_PROGRESS_FILE:= " $GHE_REMOTE_DATA_USER_DIR /repositories/.sync_in_progress" } "
379
379
380
380
# Base path for temporary directories and files.
381
- : ${TMPDIR:= " /tmp" }
381
+ : " ${TMPDIR:= " /tmp" } "
382
382
383
383
# Backup cadence for MS SQL. Determines the kind of backup taken, either full, differential,
384
384
# or transaction log, based on when the last backup of that kind was taken. This defaults to
385
385
# taking a full backup once a week, a differential backup once a day, and transaction logs every
386
386
# 15 minutes.
387
- : ${GHE_MSSQL_BACKUP_CADENCE:= 10080,1440,15}
387
+ : " ${GHE_MSSQL_BACKUP_CADENCE:= 10080,1440,15} "
388
388
389
389
# ##############################################################################
390
390
# ## Dynamic remote version config
@@ -404,11 +404,22 @@ ghe_remote_version_config() {
404
404
# If we don't have a readlink command, parse ls -l output.
405
405
if ! type readlink 1> /dev/null 2>&1 ; then
406
406
readlink () {
407
- if [ -x " $1 " ]; then
408
- ls -ld " $1 " | sed ' s/.*-> //'
409
- else
410
- return 1
411
- fi
407
+ local ret=0 f=' '
408
+ while [ $# -gt 0 ]; do
409
+ f=" $1 "
410
+ shift 1
411
+
412
+ [ ! -e " $f " ] && [ ! -h " $f " ] && {
413
+ ret=1
414
+ continue
415
+ }
416
+
417
+ # shellcheck disable=SC2012 # In this specific scenario, this method is OK
418
+ f=" $( ls -ld " $f " ) "
419
+ echo " ${f//* -> / } "
420
+ done
421
+
422
+ return $ret
412
423
}
413
424
fi
414
425
@@ -426,10 +437,12 @@ ghe_remote_version_required() {
426
437
427
438
# override hostname w/ ghe-host-check output because the port could have
428
439
# been autodetected to 122.
429
- GHE_HOSTNAME=$( echo " $_out " | sed ' s/Connect \(.*:[0-9]*\) OK.*/\1/' )
440
+ GHE_HOSTNAME=" ${_out/ Connect / } "
441
+ GHE_HOSTNAME=" ${GHE_HOSTNAME/ OK*/ } "
430
442
export GHE_HOSTNAME
431
443
432
- GHE_REMOTE_VERSION=$( echo " $_out " | sed ' s/.*(\(.*\))/\1/' )
444
+ GHE_REMOTE_VERSION=" ${GHE_HOSTNAME#* \( } "
445
+ GHE_REMOTE_VERSION=" ${GHE_HOSTNAME%% \) * } "
433
446
export GHE_REMOTE_VERSION
434
447
435
448
ghe_parse_remote_version " $GHE_REMOTE_VERSION "
@@ -441,9 +454,11 @@ ghe_remote_version_required() {
441
454
# Parse a version string into major, minor and patch parts and echo.
442
455
ghe_parse_version () {
443
456
local version_major version_minor version_patch
444
- version_major=$( echo " ${1# v} " | cut -f 1 -d .)
445
- version_minor=$( echo " $1 " | cut -f 2 -d .)
446
- version_patch=$( echo " $1 " | cut -f 3 -d .)
457
+ version_patch=" ${1# v} "
458
+ version_major=" ${version_patch%% .* } "
459
+ version_patch=" ${version_patch#* .} "
460
+ version_minor=" ${version_patch%% .* } "
461
+ version_patch=" ${version_patch#* .} "
447
462
version_patch=${version_patch%% [a-zA-Z]* }
448
463
449
464
echo " $version_major $version_minor $version_patch "
@@ -457,7 +472,7 @@ ghe_parse_version() {
457
472
# appliance version.
458
473
ghe_parse_remote_version () {
459
474
# shellcheck disable=SC2046 # Word splitting is required to populate the variables
460
- read -r GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH <<< $ ( ghe_parse_version $1 )
475
+ read -r GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH < < ( ghe_parse_version " $1 " )
461
476
export GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH
462
477
}
463
478
@@ -504,15 +519,18 @@ ghe_debug() {
504
519
if [ $# -ne 0 ]; then
505
520
echo -e " Debug: $* " 1>&3
506
521
elif [ -p /dev/stdin ]; then
507
- echo " \n" 1>&3
508
- while read line; do
522
+ echo -e " \n" 1>&3
523
+ while read -r line; do
509
524
echo -e " Debug: $line " 1>&3
510
525
done < /dev/stdin
511
526
fi
512
527
}
513
528
514
529
version () {
515
- echo " ${@# v} " | awk -F. ' { printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'
530
+ local v=" ${*# v} "
531
+
532
+ # shellcheck disable=SC2183,SC2086 # We want to glob (SC2086) and expect 4 (fuzzy) params (SC2183)
533
+ printf " %d%03d%03d%03d\n" ${v// ./ }
516
534
}
517
535
518
536
# The list of gists returned by the source changed in 2.16.23, 2.17.14,
@@ -521,11 +539,11 @@ version() {
521
539
# In newer versions, gist paths are unmodified, and only other repo types
522
540
# are truncated with `dirname`.
523
541
fix_paths_for_ghe_version () {
524
- if [[ " $GHE_REMOTE_VERSION " =~ 2.16. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.16.23) " ]] ||
525
- [[ " $GHE_REMOTE_VERSION " =~ 2.17. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.17.14) " ]] ||
526
- [[ " $GHE_REMOTE_VERSION " =~ 2.18. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.18.8) " ]] ||
527
- [[ " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.19.3) " ]]; then
528
- GIST_FILTER=" -e /gist/b"
542
+ if [[ " $GHE_REMOTE_VERSION " =~ 2.16. && " $( version " $GHE_REMOTE_VERSION " ) " -ge " $( version 2.16.23) " ]] ||
543
+ [[ " $GHE_REMOTE_VERSION " =~ 2.17. && " $( version " $GHE_REMOTE_VERSION " ) " -ge " $( version 2.17.14) " ]] ||
544
+ [[ " $GHE_REMOTE_VERSION " =~ 2.18. && " $( version " $GHE_REMOTE_VERSION " ) " -ge " $( version 2.18.8) " ]] ||
545
+ [[ " $( version " $GHE_REMOTE_VERSION " ) " -ge " $( version 2.19.3) " ]]; then
546
+ GIST_FILTER=( -e /gist/b)
529
547
else
530
548
unset GIST_FILTER
531
549
fi
@@ -538,7 +556,7 @@ fix_paths_for_ghe_version() {
538
556
# 3. truncate from the final slash (if any) to the end
539
557
# If the GIST_FILTER was set above (because we're on a modern version of
540
558
# GHES), then don't modify lines with "gist" in them.
541
- sed $ GIST_FILTER -e ' s/\/$//; s/^[^\/]*$/./; s/\/[^\/]*$//'
559
+ sed " ${ GIST_FILTER[@]} " -e ' s/\/$//; s/^[^\/]*$/./; s/\/[^\/]*$//'
542
560
}
543
561
544
562
is_binary_backup_feature_on () {
0 commit comments