32
32
set -e
33
33
34
34
# Parse arguments
35
- : ${RESTORE_SETTINGS:= false}
35
+ : " ${RESTORE_SETTINGS:= false} "
36
36
export RESTORE_SETTINGS
37
37
38
- : ${FORCE:= false}
38
+ : " ${FORCE:= false} "
39
39
export FORCE
40
40
41
- : ${SKIP_MYSQL:= false}
41
+ : " ${SKIP_MYSQL:= false} "
42
42
export SKIP_MYSQL
43
43
44
44
while true ; do
@@ -87,30 +87,30 @@ while true; do
87
87
done
88
88
89
89
start_cron () {
90
- log_info " Starting cron ..."
90
+ log_info " Starting cron ..."
91
91
if $CLUSTER ; then
92
- if ! ghe-ssh " $GHE_HOSTNAME " -- " ghe-cluster-each -- sudo timeout 120s service cron start" ; then
93
- log_warn " Failed to start cron on one or more nodes"
92
+ if ! ghe-ssh " $GHE_HOSTNAME " -- " ghe-cluster-each -- sudo timeout 120s service cron start" ; then
93
+ log_warn " Failed to start cron on one or more nodes"
94
94
fi
95
95
else
96
- if ! ghe-ssh " $GHE_HOSTNAME " -- " sudo timeout 120s service cron start" ; then
97
- log_warn " Failed to start cron"
96
+ if ! ghe-ssh " $GHE_HOSTNAME " -- " sudo timeout 120s service cron start" ; then
97
+ log_warn " Failed to start cron"
98
98
fi
99
99
fi
100
100
}
101
101
102
102
cleanup () {
103
- log_info " Exiting, cleaning up ..."
103
+ log_info " Exiting, cleaning up ..."
104
104
if [ -n " $1 " ]; then
105
105
update_restore_status " $1 "
106
106
fi
107
107
108
108
if $ACTIONS_STOPPED && ghe-ssh " $GHE_HOSTNAME " -- ' ghe-config --true app.actions.enabled' ; then
109
- log_info " Restarting Actions after restore ..."
109
+ log_info " Restarting Actions after restore ..."
110
110
# In GHES 3.3+, ghe-actions-start no longer has a -f (force) flag. In GHES 3.2 and below, we must provide the
111
111
# force flag to make sure it can start in maintenance mode. Use it conditionally based on whether it exists
112
112
# in the --help output
113
- if ghe-ssh " $GHE_HOSTNAME " -- ' ghe-actions-start --help' | grep -q force ; then
113
+ if ghe-ssh " $GHE_HOSTNAME " -- ' ghe-actions-start --help' | grep -q force; then
114
114
ghe-ssh " $GHE_HOSTNAME " -- ' ghe-actions-start -f' 1>&3
115
115
else
116
116
ghe-ssh " $GHE_HOSTNAME " -- ' ghe-actions-start' 1>&3
@@ -122,15 +122,15 @@ cleanup () {
122
122
fi
123
123
124
124
# Cleanup SSH multiplexing
125
- log_info " Cleaning up SSH multiplexing ..."
126
- if ! ghe-ssh --clean ; then
127
- log_info " Failed to clean up SSH multiplexing"
125
+ log_info " Cleaning up SSH multiplexing ..."
126
+ if ! ghe-ssh --clean; then
127
+ log_info " Failed to clean up SSH multiplexing"
128
128
fi
129
- # Remove in-progress file
130
- log_info " Removing in-progress file ..." 1>&3
131
129
132
- if ! rm -f ${GHE_DATA_DIR} /in-progress-restore ; then
133
- log_error " Failed to remove in-progress file" 1>&3
130
+ # Remove in-progress file
131
+ log_info " Removing in-progress file ..." 1>&3
132
+ if ! rm -f " ${GHE_DATA_DIR} /in-progress-restore" ; then
133
+ log_error " Failed to remove in-progress file" 1>&3
134
134
fi
135
135
}
136
136
@@ -139,23 +139,24 @@ cleanup () {
139
139
cleanup_cluster_nodes () {
140
140
uuid=" $1 "
141
141
if [ -z " $uuid " ]; then
142
- log_error " Node UUID required."
142
+ log_error " Node UUID required."
143
143
exit 2
144
144
fi
145
- log_info " Cleaning up spokes" 1>&3
146
- ghe-spokes server evacuate git-server-$uuid ' Removing replica'
147
- ghe-spokes server destroy git-server-$uuid
148
145
149
- log_info " Cleaning up storage" 1>&3
150
- ghe-storage destroy-host storage-server-$uuid --force
146
+ log_info " Cleaning up spokes" 1>&3
147
+ ghe-spokes server evacuate " git-server-$uuid " ' Removing replica'
148
+ ghe-spokes server destroy " git-server-$uuid "
149
+
150
+ log_info " Cleaning up storage" 1>&3
151
+ ghe-storage destroy-host " storage-server-$uuid " --force
151
152
152
- log_info " Cleaning up dpages" 1>&3
153
- ghe-dpages offline pages-server-$uuid
154
- ghe-dpages remove pages-server-$uuid
153
+ log_info " Cleaning up dpages" 1>&3
154
+ ghe-dpages offline " pages-server-$uuid "
155
+ ghe-dpages remove " pages-server-$uuid "
155
156
156
- log_info " Cleaning up redis" 1>&3
157
- ghe-redis-cli del resque:queue:maint_git-server-$uuid
158
- ghe-redis-cli srem resque:queues maint_git-server-$uuid
157
+ log_info " Cleaning up redis" 1>&3
158
+ ghe-redis-cli del " resque:queue:maint_git-server-$uuid "
159
+ ghe-redis-cli srem resque:queues " maint_git-server-$uuid "
159
160
}
160
161
161
162
# Bring in the backup configuration
@@ -190,7 +191,7 @@ export GHE_RESTORE_SNAPSHOT
190
191
ghe_backup_check
191
192
192
193
# Detect if the backup we are restoring has a leaked ssh key
193
- echo " Checking for leaked keys in the backup snapshot that is being restored ..."
194
+ echo " Checking for leaked keys in the backup snapshot that is being restored ..."
194
195
ghe-detect-leaked-ssh-keys -s " $GHE_RESTORE_SNAPSHOT_PATH " || true
195
196
196
197
# Figure out whether to use the tarball or rsync restore strategy based on the
@@ -218,7 +219,7 @@ export CLUSTER
218
219
219
220
# Restoring a cluster backup to a standalone appliance is not supported
220
221
if ! $CLUSTER && [ " $GHE_BACKUP_STRATEGY " = " cluster" ]; then
221
- log_error " Error: Snapshot from a GitHub Enterprise cluster cannot be restored to a standalone appliance. Aborting." >&2
222
+ log_error " Error: Snapshot from a GitHub Enterprise cluster cannot be restored to a standalone appliance. Aborting." >&2
222
223
exit 1
223
224
fi
224
225
230
231
# Figure out if this appliance is in a replication pair
231
232
if ghe-ssh " $GHE_HOSTNAME " -- \
232
233
" [ -f '$GHE_REMOTE_ROOT_DIR /etc/github/repl-state' ]" ; then
233
- log_error " Error: Restoring to an appliance with replication enabled is not supported. Please teardown replication before restoring." >&2
234
+ log_error " Error: Restoring to an appliance with replication enabled is not supported. Please teardown replication before restoring." >&2
234
235
exit 1
235
236
fi
236
237
267
268
# Log restore start message locally and in /var/log/syslog on remote instance
268
269
START_TIME=$( date +%s)
269
270
log_info " Starting restore of $GHE_HOSTNAME with backup-utils v$BACKUP_UTILS_VERSION from snapshot $GHE_RESTORE_SNAPSHOT "
271
+
270
272
ghe_remote_logger " Starting restore from $( hostname) with backup-utils v$BACKUP_UTILS_VERSION / snapshot $GHE_RESTORE_SNAPSHOT ..."
271
273
# Create an in-progress-restore file to prevent simultaneous backup or restore runs
272
- echo " ${START_TIME} $$ " > ${GHE_DATA_DIR} /in-progress-restore
274
+ echo " ${START_TIME} $$ " > " ${GHE_DATA_DIR} /in-progress-restore"
273
275
274
276
# Keep other processes on the VM or cluster in the loop about the restore status.
275
277
#
@@ -295,7 +297,7 @@ update_restore_status "restoring"
295
297
# Make sure the GitHub appliance is in maintenance mode.
296
298
if $instance_configured ; then
297
299
if ! ghe-maintenance-mode-status " $GHE_HOSTNAME " ; then
298
- log_error " Error: $GHE_HOSTNAME must be put in maintenance mode before restoring. Aborting." 1>&2
300
+ log_error " Error: $GHE_HOSTNAME must be put in maintenance mode before restoring. Aborting." 1>&2
299
301
exit 1
300
302
fi
301
303
fi
@@ -305,9 +307,9 @@ RELEASE_VERSION=$(ghe-ssh "$GHE_HOSTNAME" -- 'ghe-config --get core.package-vers
305
307
306
308
# If the backup being restored is from an appliance with Actions disabled, restoring it onto an appliance with Actions enabled will cause
307
309
# mismatches in the secrets needed for Actions which ultimately results in Actions not working properly. Note: xargs is to remove whitespace
308
- ACTIONS_ENABLED_IN_BACKUP=$( git config -f $GHE_RESTORE_SNAPSHOT_PATH /settings.json --bool app.actions.enabled | xargs)
310
+ ACTIONS_ENABLED_IN_BACKUP=$( git config -f " $GHE_RESTORE_SNAPSHOT_PATH /settings.json" --bool app.actions.enabled | xargs)
309
311
if [[ $ACTIONS_ENABLED_IN_BACKUP != true ]] && ghe-ssh " $GHE_HOSTNAME " -- ' ghe-config --true app.actions.enabled' ; then
310
- log_error " Restoring a backup with Actions disabled onto an appliance with Actions enabled is not supported." >&2
312
+ log_error " Restoring a backup with Actions disabled onto an appliance with Actions enabled is not supported." >&2
311
313
exit 1
312
314
fi
313
315
391
393
# Restore UUID if present and not restoring to cluster.
392
394
if [ -s " $GHE_RESTORE_SNAPSHOT_PATH /uuid" ] && ! $CLUSTER ; then
393
395
log_info " Restoring UUID ..."
394
- cat " $GHE_RESTORE_SNAPSHOT_PATH /uuid" |
395
- ghe-ssh " $GHE_HOSTNAME " -- " sudo sponge '$GHE_REMOTE_DATA_USER_DIR /common/uuid' 2>/dev/null"
396
+ ghe-ssh " $GHE_HOSTNAME " -- " sudo sponge '$GHE_REMOTE_DATA_USER_DIR /common/uuid' 2>/dev/null" < " $GHE_RESTORE_SNAPSHOT_PATH /uuid"
396
397
ghe-ssh " $GHE_HOSTNAME " -- " sudo systemctl stop consul" || true
397
398
ghe-ssh " $GHE_HOSTNAME " -- " sudo rm -rf /data/user/consul/raft"
398
- fi
399
+ fi
399
400
400
401
if is_external_database_snapshot; then
401
402
appliance_strategy=" external"
@@ -428,12 +429,13 @@ if ghe-ssh "$GHE_HOSTNAME" -- 'ghe-config --true app.actions.enabled'; then
428
429
ACTIONS_STOPPED=true
429
430
ghe-ssh " $GHE_HOSTNAME " -- ' ghe-actions-stop' 1>&3
430
431
431
- log_info " Restoring MSSQL databases ..."
432
+ log_info " Restoring MSSQL databases ..."
432
433
ghe-restore-mssql " $GHE_HOSTNAME " 1>&3
433
434
434
435
log_info " Restoring Actions data ..."
435
436
ghe-restore-actions " $GHE_HOSTNAME " 1>&3
436
- echo " * WARNING: Every self-hosted Actions runner that communicates with the restored GHES server must be restarted or reconfigured in order to continue functioning. \n See https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners for more details on how to reconfigure self-hosted Actions runners."
437
+ echo " * WARNING: Every self-hosted Actions runner that communicates with the restored GHES server must be restarted or reconfigured in order to continue functioning."
438
+ echo " See https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners for more details on how to reconfigure self-hosted Actions runners."
437
439
fi
438
440
439
441
if ghe-ssh " $GHE_HOSTNAME " -- ' ghe-config --true app.minio.enabled' ; then
@@ -485,16 +487,16 @@ if ! $CLUSTER && [ -d "$GHE_RESTORE_SNAPSHOT_PATH/elasticsearch" ]; then
485
487
fi
486
488
487
489
# Restore the audit log migration sentinel file, if it exists in the snapshot
488
- if test -f " $GHE_RESTORE_SNAPSHOT_PATH " /es-scan-complete; then
490
+ if test -f " $GHE_RESTORE_SNAPSHOT_PATH /es-scan-complete" ; then
489
491
log_info " Restoring Elasticsearch audit log migration sentinel file ..." 1>&3
490
- if ! ghe-ssh " $GHE_HOSTNAME " -- " sudo touch $GHE_REMOTE_DATA_USER_DIR /common/es-scan-complete" ; then
492
+ if ! ghe-ssh " $GHE_HOSTNAME " -- " sudo touch $GHE_REMOTE_DATA_USER_DIR /common/es-scan-complete" ; then
491
493
log_info " Failed to restore Elasticsearch audit log migration sentinel file." 1>&3
492
494
fi
493
495
fi
494
496
495
497
# Restore exported audit logs to 2.12.9 and newer single nodes and
496
498
# all releases of cluster
497
- if $CLUSTER || [ " $( version $GHE_REMOTE_VERSION ) " -ge " $( version 2.12.9) " ]; then
499
+ if $CLUSTER || [ " $( version " $GHE_REMOTE_VERSION " ) " -ge " $( version 2.12.9) " ]; then
498
500
if [[ " $GHE_RESTORE_SKIP_AUDIT_LOGS " = " yes" ]]; then
499
501
log_info " Skipping restore of audit logs."
500
502
else
508
510
509
511
if [ " $GHE_PARALLEL_ENABLED " = " yes" ]; then
510
512
log_info " Restoring data in parallel ..."
511
- $GHE_PARALLEL_COMMAND $ GHE_PARALLEL_COMMAND_OPTIONS -- " ${commands[@]} "
513
+ " $GHE_PARALLEL_COMMAND " " ${ GHE_PARALLEL_COMMAND_OPTIONS[@]} " -- " ${commands[@]} "
512
514
else
513
515
log_info " Restoring data serially ..." 1>&3
514
516
for c in " ${commands[@]} " ; do
515
- eval " $c "
517
+ eval " $c "
516
518
done
517
519
fi
518
520
519
521
# Restart an already running memcached to reset the cache after restore
520
- log_info " Restarting memcached ..." 1>&3
522
+ log_info " Restarting memcached ..." 1>&3
521
523
echo " sudo restart -q memcached 2>/dev/null || true" |
522
524
ghe-ssh " $GHE_HOSTNAME " -- /bin/sh
523
525
@@ -564,7 +566,7 @@ CRON_RUNNING=true
564
566
# Clean up all stale replicas on configured instances.
565
567
if ! $CLUSTER && $instance_configured ; then
566
568
log_info " Cleaning up replicas..." 1>&3
567
- restored_uuid=$( cat $GHE_RESTORE_SNAPSHOT_PATH /uuid)
569
+ restored_uuid=$( cat " $GHE_RESTORE_SNAPSHOT_PATH /uuid" )
568
570
other_nodes=$( echo "
569
571
set -o pipefail; \
570
572
ghe-spokes server show --json \
@@ -604,11 +606,12 @@ else
604
606
fi
605
607
606
608
END_TIME=$( date +%s)
607
- log_info " Runtime: $(( ${ END_TIME} - ${ START_TIME} )) seconds"
608
- log_info " Restore of $GHE_HOSTNAME from snapshot $GHE_RESTORE_SNAPSHOT finished. "
609
+ log_info " Runtime: $(( END_TIME - START_TIME)) seconds"
610
+ log_info " Completed restore of $GHE_HOSTNAME from snapshot $GHE_RESTORE_SNAPSHOT at $( date + " %H:%M:%S " ) "
609
611
612
+ log_info " Restore of $GHE_HOSTNAME finished."
610
613
611
614
if ! $instance_configured ; then
612
- echo " To complete the restore process, please visit https://$hostname /setup/settings to review and save the appliance configuration."
615
+ echo " To complete the restore process, please visit https://$hostname /setup/settings to review and save the appliance configuration."
613
616
fi
614
617
0 commit comments