@@ -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) "
@@ -156,15 +156,15 @@ export GHE_RESTORE_IN_PROGRESS
156
156
export GHE_BACKUP_IN_PROGRESS
157
157
158
158
ghe_restore_check () {
159
- if [ -h $GHE_RESTORE_IN_PROGRESS ]; then
159
+ if [ -h " $GHE_RESTORE_IN_PROGRESS " ]; then
160
160
echo " Error: detected a restore already in progress from a previous version of ghe-restore." 1>&2
161
161
echo " If there is no restore in progress anymore, please remove" 1>&2
162
162
echo " the $GHE_RESTORE_IN_PROGRESS file and try again." 1>&2
163
163
exit 1
164
164
fi
165
165
166
- if [ -f $GHE_RESTORE_IN_PROGRESS ]; then
167
- progress=$( cat $GHE_RESTORE_IN_PROGRESS )
166
+ if [ -f " $GHE_RESTORE_IN_PROGRESS " ]; then
167
+ progress=$( cat " $GHE_RESTORE_IN_PROGRESS " )
168
168
pid=$( echo " $progress " | cut -d ' ' -f 2)
169
169
echo " Error: A restore of $GHE_HOSTNAME may still be running on PID $pid ." 1>&2
170
170
echo " If PID $pid is not a process related to the restore utilities, please remove" 1>&2
@@ -174,15 +174,15 @@ ghe_restore_check() {
174
174
}
175
175
176
176
ghe_backup_check () {
177
- if [ -h $GHE_BACKUP_IN_PROGRESS ]; then
177
+ if [ -h " $GHE_BACKUP_IN_PROGRESS " ]; then
178
178
echo " Error: detected a backup already in progress from a previous version of ghe-backup." 1>&2
179
179
echo " If there is no backup in progress anymore, please remove" 1>&2
180
180
echo " the $GHE_DATA_DIR /$GHE_BACKUP_IN_PROGRESS file and try again." 1>&2
181
181
exit 1
182
182
fi
183
183
184
- if [ -f $GHE_BACKUP_IN_PROGRESS ]; then
185
- progress=$( cat $GHE_BACKUP_IN_PROGRESS )
184
+ if [ -f " $GHE_BACKUP_IN_PROGRESS " ]; then
185
+ progress=$( cat " $GHE_BACKUP_IN_PROGRESS " )
186
186
pid=$( echo " $progress " | cut -d ' ' -f 2)
187
187
echo " Error: A backup of $GHE_HOSTNAME may still be running on PID $pid ." 1>&2
188
188
echo " If PID $pid is not a process related to the backup utilities, please remove" 1>&2
@@ -192,19 +192,20 @@ ghe_backup_check() {
192
192
}
193
193
194
194
ghe_restore_finished () {
195
- if [ -f $GHE_RESTORE_IN_PROGRESS ]; then
196
- rm -f $GHE_RESTORE_IN_PROGRESS
195
+ if [ -f " $GHE_RESTORE_IN_PROGRESS " ]; then
196
+ rm -f " $GHE_RESTORE_IN_PROGRESS "
197
197
fi
198
198
}
199
199
200
200
ghe_backup_finished () {
201
- if [ -f $GHE_BACKUP_IN_PROGRESS ]; then
202
- rm -f $GHE_BACKUP_IN_PROGRESS
201
+ if [ -f " $GHE_BACKUP_IN_PROGRESS " ]; then
202
+ rm -f " $GHE_BACKUP_IN_PROGRESS "
203
203
fi
204
204
}
205
205
206
206
ghe_parallel_check () {
207
207
GHE_PARALLEL_COMMAND_OPTIONS=()
208
+ GHE_PARALLEL_RSYNC_COMMAND_OPTIONS=()
208
209
209
210
if [ " $GHE_PARALLEL_ENABLED " != " yes" ]; then
210
211
return 0
@@ -240,12 +241,12 @@ ghe_parallel_check() {
240
241
fi
241
242
242
243
if [ -n " $GHE_PARALLEL_RSYNC_MAX_JOBS " ]; then
243
- GHE_PARALLEL_RSYNC_COMMAND_OPTIONS= " -j $GHE_PARALLEL_RSYNC_MAX_JOBS "
244
+ GHE_PARALLEL_RSYNC_COMMAND_OPTIONS+=( -j " $GHE_PARALLEL_RSYNC_MAX_JOBS " )
244
245
fi
245
246
246
247
if [ -n " $GHE_PARALLEL_MAX_LOAD " ]; then
247
248
GHE_PARALLEL_COMMAND_OPTIONS+=(-l " $GHE_PARALLEL_MAX_LOAD " )
248
- GHE_PARALLEL_RSYNC_COMMAND_OPTIONS+=" -l $GHE_PARALLEL_MAX_LOAD "
249
+ GHE_PARALLEL_RSYNC_COMMAND_OPTIONS+=( -l " $GHE_PARALLEL_MAX_LOAD " )
249
250
fi
250
251
}
251
252
@@ -271,7 +272,7 @@ if [ -n "$GHE_VERBOSE" ]; then
271
272
exec 3>> " $GHE_VERBOSE_LOG "
272
273
log_info " $calling_script_name $* " 1>&3
273
274
else
274
- # colorize the input if supported.
275
+ # colorize the input if supported.
275
276
display_caller=" ${BLUE} $calling_script_name ${NC} "
276
277
exec 3>> " $GHE_VERBOSE_LOG "
277
278
log_info " $display_caller $* " 1>&3
@@ -332,11 +333,11 @@ if [ ! -d "$GHE_DATA_DIR" ]; then
332
333
fi
333
334
334
335
# Set some defaults if needed.
335
- : ${GHE_NUM_SNAPSHOTS:= 10}
336
+ : " ${GHE_NUM_SNAPSHOTS:= 10} "
336
337
337
338
# Generate a backup timestamp if one has not already been generated.
338
339
# We export the variable so the process group shares the same value.
339
- : ${GHE_SNAPSHOT_TIMESTAMP:= $(date +" %Y%m%dT%H%M%S" )}
340
+ : " ${GHE_SNAPSHOT_TIMESTAMP:= $(date +" %Y%m%dT%H%M%S" )} "
340
341
export GHE_SNAPSHOT_TIMESTAMP
341
342
342
343
# Set the current snapshot directory to <data-dir>/<timestamp>. This is where
@@ -346,50 +347,50 @@ export GHE_SNAPSHOT_DIR
346
347
347
348
# The root filesystem location. This must be used so that tests can override
348
349
# the root as a local directory location.
349
- : ${GHE_REMOTE_ROOT_DIR:= " " }
350
+ : " ${GHE_REMOTE_ROOT_DIR:= " " } "
350
351
351
352
# The root location of persistent data and applications on the remote side. This
352
353
# is always "/data" for GitHub instances. Use of this variable allows
353
354
# the location to be overridden in tests.
354
- : ${GHE_REMOTE_DATA_DIR:= " /data" }
355
+ : " ${GHE_REMOTE_DATA_DIR:= " /data" } "
355
356
356
357
# The root location of user data stores such as git repositories, pages sites,
357
358
# elasticsearch indices, etc. This is "/data" under 1.x filesystem layouts and
358
359
# "/data/user" under the 2.x filesystem layout. The location is adjusted
359
360
# dynamically in ghe_remote_version_config() immediately after obtaining the
360
361
# remote version. Utilities that transfer data in and out of the appliance
361
362
# should use this variable to ensure proper behavior under different versions.
362
- : ${GHE_REMOTE_DATA_USER_DIR:= " $GHE_REMOTE_DATA_DIR " }
363
+ : " ${GHE_REMOTE_DATA_USER_DIR:= " $GHE_REMOTE_DATA_DIR " } "
363
364
364
365
# The location of the license file on the remote side. This is always
365
366
# "/data/enterprise/enterprise.ghl" for GitHub instances. Use of this variable
366
367
# allows the location to be overridden in tests.
367
- : ${GHE_REMOTE_LICENSE_FILE:= " $GHE_REMOTE_DATA_DIR /enterprise/enterprise.ghl" }
368
+ : " ${GHE_REMOTE_LICENSE_FILE:= " $GHE_REMOTE_DATA_DIR /enterprise/enterprise.ghl" } "
368
369
369
370
# The number of seconds to wait for in progress git-gc processes to complete
370
371
# before starting the sync of git data. See share/github-backup-utils/ghe-backup-repositories-rsync
371
372
# for more information. Default: 10 minutes.
372
- : ${GHE_GIT_COOLDOWN_PERIOD:= 600}
373
+ : " ${GHE_GIT_COOLDOWN_PERIOD:= 600} "
373
374
374
375
# Set "true" to get verbose logging of all ssh commands on stderr
375
- : ${GHE_VERBOSE_SSH:= false}
376
+ : " ${GHE_VERBOSE_SSH:= false} "
376
377
377
378
# The location of the cluster configuration file on the remote side.
378
379
# This is always "/data/user/common/cluster.conf" for GitHub Cluster instances.
379
380
# Use of this variable allows the location to be overridden in tests.
380
- : ${GHE_REMOTE_CLUSTER_CONF_FILE:= " $GHE_REMOTE_DATA_DIR /user/common/cluster.conf" }
381
+ : " ${GHE_REMOTE_CLUSTER_CONF_FILE:= " $GHE_REMOTE_DATA_DIR /user/common/cluster.conf" } "
381
382
382
383
# The location of the file used to disable GC operations on the remote side.
383
- : ${SYNC_IN_PROGRESS_FILE:= " $GHE_REMOTE_DATA_USER_DIR /repositories/.sync_in_progress" }
384
+ : " ${SYNC_IN_PROGRESS_FILE:= " $GHE_REMOTE_DATA_USER_DIR /repositories/.sync_in_progress" } "
384
385
385
386
# Base path for temporary directories and files.
386
- : ${TMPDIR:= " /tmp" }
387
+ : " ${TMPDIR:= " /tmp" } "
387
388
388
389
# Backup cadence for MS SQL. Determines the kind of backup taken, either full, differential,
389
390
# or transaction log, based on when the last backup of that kind was taken. This defaults to
390
391
# taking a full backup once a week, a differential backup once a day, and transaction logs every
391
392
# 15 minutes.
392
- : ${GHE_MSSQL_BACKUP_CADENCE:= 10080,1440,15}
393
+ : " ${GHE_MSSQL_BACKUP_CADENCE:= 10080,1440,15} "
393
394
394
395
# ##############################################################################
395
396
# ## Dynamic remote version config
@@ -420,10 +421,12 @@ ghe_remote_version_required() {
420
421
421
422
# override hostname w/ ghe-host-check output because the port could have
422
423
# been autodetected to 122.
423
- GHE_HOSTNAME=$( echo " $_out " | sed ' s/Connect \(.*:[0-9]*\) OK.*/\1/' )
424
+ GHE_HOSTNAME=" ${_out/ Connect / } "
425
+ GHE_HOSTNAME=" ${GHE_HOSTNAME/ OK*/ } "
424
426
export GHE_HOSTNAME
425
427
426
- GHE_REMOTE_VERSION=$( echo " $_out " | sed ' s/.*(\(.*\))/\1/' )
428
+ GHE_REMOTE_VERSION=" ${_out#* \( } "
429
+ GHE_REMOTE_VERSION=" ${GHE_REMOTE_VERSION%% \) * } "
427
430
export GHE_REMOTE_VERSION
428
431
429
432
ghe_parse_remote_version " $GHE_REMOTE_VERSION "
@@ -435,9 +438,8 @@ ghe_remote_version_required() {
435
438
# Parse a version string into major, minor and patch parts and echo.
436
439
ghe_parse_version () {
437
440
local version_major version_minor version_patch
438
- version_major=$( echo " ${1# v} " | cut -f 1 -d .)
439
- version_minor=$( echo " $1 " | cut -f 2 -d .)
440
- version_patch=$( echo " $1 " | cut -f 3 -d .)
441
+
442
+ IFS=. read -r version_major version_minor version_patch _ <<< " ${1#v}"
441
443
version_patch=${version_patch%% [a-zA-Z]* }
442
444
443
445
echo " $version_major $version_minor $version_patch "
@@ -451,7 +453,7 @@ ghe_parse_version() {
451
453
# appliance version.
452
454
ghe_parse_remote_version () {
453
455
# shellcheck disable=SC2046 # Word splitting is required to populate the variables
454
- read -r GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH <<< $ ( ghe_parse_version $1 )
456
+ read -r GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH < < ( ghe_parse_version " $1 " )
455
457
export GHE_VERSION_MAJOR GHE_VERSION_MINOR GHE_VERSION_PATCH
456
458
}
457
459
@@ -498,15 +500,19 @@ ghe_debug() {
498
500
if [ $# -ne 0 ]; then
499
501
echo -e " Debug: $* " 1>&3
500
502
elif [ -p /dev/stdin ]; then
501
- echo " \n" 1>&3
502
- while read line; do
503
+ echo -e " \n" 1>&3
504
+ while read -r line; do
503
505
echo -e " Debug: $line " 1>&3
504
506
done < /dev/stdin
505
507
fi
506
508
}
507
509
508
510
version () {
509
- echo " ${@# v} " | awk -F. ' { printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'
511
+ local v=" ${*# v} "
512
+
513
+ # Discard stderr and always return true as trailing alpha (eg. "v1.2.3pre") will upset printf
514
+ # shellcheck disable=SC2183,SC2086 # We want to glob (SC2086) and expect 4 (fuzzy) params (SC2183)
515
+ printf " %d%03d%03d%03d\n" ${v// ./ } 2> /dev/null || true
510
516
}
511
517
512
518
# The list of gists returned by the source changed in 2.16.23, 2.17.14,
@@ -515,11 +521,11 @@ version() {
515
521
# In newer versions, gist paths are unmodified, and only other repo types
516
522
# are truncated with `dirname`.
517
523
fix_paths_for_ghe_version () {
518
- if [[ " $GHE_REMOTE_VERSION " =~ 2.16. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.16.23) " ]] ||
519
- [[ " $GHE_REMOTE_VERSION " =~ 2.17. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.17.14) " ]] ||
520
- [[ " $GHE_REMOTE_VERSION " =~ 2.18. && " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.18.8) " ]] ||
521
- [[ " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.19.3) " ]]; then
522
- GIST_FILTER=" -e /gist/b"
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" )
523
529
else
524
530
unset GIST_FILTER
525
531
fi
@@ -532,7 +538,7 @@ fix_paths_for_ghe_version() {
532
538
# 3. truncate from the final slash (if any) to the end
533
539
# If the GIST_FILTER was set above (because we're on a modern version of
534
540
# GHES), then don't modify lines with "gist" in them.
535
- sed $ GIST_FILTER -e ' s/\/$//; s/^[^\/]*$/./; s/\/[^\/]*$//'
541
+ sed " ${ GIST_FILTER[@]} " -e ' s/\/$//; s/^[^\/]*$/./; s/\/[^\/]*$//'
536
542
}
537
543
538
544
is_binary_backup_feature_on () {
0 commit comments