Skip to content

Commit c7fb8a3

Browse files
authored
Merge branch 'master' into djdefi-expand-matrix
2 parents 53148cc + f6e418a commit c7fb8a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1826
-260
lines changed

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Lint Code Base
22

33
on:
4-
push:
4+
pull_request:
55
branches-ignore:
66
- 'master'
77

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Test and build
22

3-
on: [push]
3+
on: [pull_request]
44

55
jobs:
66
build:
@@ -14,7 +14,7 @@ jobs:
1414
run: |
1515
sudo apt-get update -y
1616
sudo apt-get install -y devscripts debhelper moreutils fakeroot jq pigz
17-
wget "https://storage.googleapis.com/shellcheck/shellcheck-v0.7.0.linux.x86_64.tar.xz"
17+
wget "https://github.com/koalaman/shellcheck/releases/download/v0.7.0/shellcheck-v0.7.0.linux.x86_64.tar.xz"
1818
tar --xz -xvf "shellcheck-v0.7.0.linux.x86_64.tar.xz"
1919
sudo cp shellcheck-v0.7.0/shellcheck /usr/bin/shellcheck
2020
if: matrix.os != 'macos-latest'

Dockerfile.alpine

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM alpine:latest
2+
3+
RUN apk --update --no-cache add \
4+
tar \
5+
rsync \
6+
ca-certificates \
7+
openssh \
8+
git \
9+
bash \
10+
gawk \
11+
procps
12+
13+
WORKDIR /backup-utils
14+
ADD https://github.com/github/backup-utils/archive/stable.tar.gz /
15+
RUN tar xzvf /stable.tar.gz --strip-components=1 -C /backup-utils && \
16+
mv /usr/bin/gawk /usr/bin/awk && \
17+
rm -r /stable.tar.gz
18+
19+
RUN chmod +x /backup-utils/share/github-backup-utils/ghe-docker-init
20+
21+
ENTRYPOINT ["/backup-utils/share/github-backup-utils/ghe-docker-init"]
22+
CMD ["ghe-host-check"]

RELEASING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ There is no need to align Backup Utilities patch releases with GitHub Enterprise
88

99
When making a `.0` release, you will need to specify the minimum supported version of GitHub Enterprise Server that that release supports.
1010

11+
Only repo administrator is allowed to run the release script, otherwise it will fail.
12+
1113
## Pre-release Actions
1214

1315
Prior to making a release,

backup.config-example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ GHE_NUM_SNAPSHOTS=10
5353
# WARNING: do not enable this, only useful for debugging/development
5454
#GHE_BACKUP_FSCK=no
5555

56+
# Cadence of MSSQL backups
57+
# <full>,<differential>,<transactionlog> all in minutes
58+
# e.g.
59+
# - Full backup every week (10080 minutes)
60+
# - Differential backup every day (1440 minutes)
61+
# - Transactionlog backup every 15 minutes
62+
#
63+
GHE_MSSQL_BACKUP_CADENCE=10080,1440,15
64+
5665
# If set to 'yes', ghe-backup jobs will run in parallel. Defaults to 'no'.
5766
#
5867
# WARNING: this feature is in beta.

bin/ghe-backup

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ bm_end "ghe-export-ssh-host-keys"
182182

183183
ghe-backup-mysql || failures="$failures mysql"
184184

185+
if ghe-ssh "$GHE_HOSTNAME" -- 'ghe-config --true app.actions.enabled'; then
186+
echo "Backing up MSSQL databases ..."
187+
ghe-backup-mssql 1>&3 || failures="$failures mssql"
188+
189+
echo "Backing up Actions data ..."
190+
ghe-backup-actions 1>&3 || failures="$failures actions"
191+
fi
192+
185193
commands=("
186194
echo \"Backing up Redis database ...\"
187195
ghe-backup-redis > redis.rdb || printf %s \"redis \" >> \"$failures_file\"")

bin/ghe-host-check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ fi
113113

114114
# backup-utils 2.13 onwards limits support to the current and previous two releases
115115
# of GitHub Enterprise Server.
116-
supported_minimum_version="2.18.0"
116+
supported_minimum_version="2.19.0"
117117

118118
if [ "$(version $version)" -ge "$(version $supported_minimum_version)" ]; then
119119
supported=1

bin/ghe-restore

Lines changed: 94 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
#/ Usage: ghe-restore [-fchv] [--version] [-s <snapshot-id>] [<host>]
2+
#/ Usage: ghe-restore [-cfhv] [--version] [--skip-mysql] [-s <snapshot-id>] [<host>]
33
#/
44
#/ Restores a GitHub instance from local backup snapshots.
55
#/
@@ -9,40 +9,54 @@
99
#/ <https://enterprise.github.com/help/articles/adding-an-ssh-key-for-shell-access>
1010
#/
1111
#/ OPTIONS:
12-
#/ -f | --force Don't prompt for confirmation before restoring.
13-
#/ -c | --config Restore appliance settings and license in addition to
14-
#/ datastores. Settings are not restored by default to
15-
#/ prevent overwriting different configuration on the
16-
#/ restore host.
17-
#/ -v | --verbose Enable verbose output.
18-
#/ -h | --help Show this message.
19-
#/ --version Display version information and exit.
20-
#/ -s <snapshot-id> Restore from the snapshot with the given id. Available
21-
#/ snapshots may be listed under the data directory.
22-
#/ <host> The <host> is the hostname or IP of the GitHub Enterprise
23-
#/ instance. The <host> may be omitted when the
24-
#/ GHE_RESTORE_HOST config variable is set in backup.config.
25-
#/ When a <host> argument is provided, it always overrides
26-
#/ the configured restore host.
12+
#/ -c | --config Restore appliance settings and license in addition to
13+
#/ datastores. Settings are not restored by default to
14+
#/ prevent overwriting different configuration on the
15+
#/ restore host.
16+
#/ -f | --force Don't prompt for confirmation before restoring.
17+
#/ -h | --help Show this message.
18+
#/ -v | --verbose Enable verbose output.
19+
#/ --skip-mysql Skip MySQL restore steps. Only applicable to external databases.
20+
#/ --version Display version information and exit.
21+
#/
22+
#/ -s <snapshot-id> Restore from the snapshot with the given id. Available
23+
#/ snapshots may be listed under the data directory.
24+
#/
25+
#/ <host> The <host> is the hostname or IP of the GitHub Enterprise
26+
#/ instance. The <host> may be omitted when the
27+
#/ GHE_RESTORE_HOST config variable is set in backup.config.
28+
#/ When a <host> argument is provided, it always overrides
29+
#/ the configured restore host.
2730
#/
2831

2932
set -e
3033

3134
# Parse arguments
32-
restore_settings=false
33-
force=false
35+
: ${RESTORE_SETTINGS:=false}
36+
export RESTORE_SETTINGS
37+
38+
: ${FORCE:=false}
39+
export FORCE
40+
41+
: ${SKIP_MYSQL:=false}
42+
export SKIP_MYSQL
43+
3444
while true; do
3545
case "$1" in
46+
--skip-mysql)
47+
SKIP_MYSQL=true
48+
shift
49+
;;
3650
-f|--force)
37-
force=true
51+
FORCE=true
3852
shift
3953
;;
4054
-s)
4155
snapshot_id="$(basename "$2")"
4256
shift 2
4357
;;
4458
-c|--config)
45-
restore_settings=true
59+
RESTORE_SETTINGS=true
4660
shift
4761
;;
4862
-h|--help)
@@ -116,10 +130,10 @@ ghe_remote_version_required "$GHE_HOSTNAME"
116130

117131
# Figure out if this instance has been configured or is entirely new.
118132
instance_configured=false
119-
if ghe-ssh "$GHE_HOSTNAME" -- "[ -f '$GHE_REMOTE_ROOT_DIR/etc/github/configured' ]"; then
133+
if is_instance_configured; then
120134
instance_configured=true
121135
else
122-
restore_settings=true
136+
RESTORE_SETTINGS=true
123137
fi
124138

125139
# Figure out if we're restoring into cluster
@@ -137,6 +151,11 @@ if ! $CLUSTER && [ "$GHE_BACKUP_STRATEGY" = "cluster" ]; then
137151
exit 1
138152
fi
139153

154+
# Ensure target appliance and restore snapshot are a compatible combination with respect to BYODB
155+
if ! ghe-restore-external-database-compatibility-check; then
156+
exit 1
157+
fi
158+
140159
# Figure out if this appliance is in a replication pair
141160
if ghe-ssh "$GHE_HOSTNAME" -- \
142161
"[ -f '$GHE_REMOTE_ROOT_DIR/etc/github/repl-state' ]"; then
@@ -149,31 +168,35 @@ fi
149168
# important data on the destination appliance that cannot be recovered. This is
150169
# mostly to prevent accidents where the backup host is given to restore instead
151170
# of a separate restore host since they're used in such close proximity.
152-
if $instance_configured && ! $force; then
171+
if $instance_configured && ! $FORCE; then
153172
echo
154173
echo "WARNING: All data on GitHub Enterprise appliance $hostname ($GHE_REMOTE_VERSION)"
155174
echo " will be overwritten with data from snapshot ${GHE_RESTORE_SNAPSHOT}."
156-
echo "Please verify that this is the correct restore host before continuing."
157-
printf "Type 'yes' to continue: "
175+
echo
158176

159-
while read -r response; do
160-
case $response in
161-
yes|Yes|YES)
162-
break
163-
;;
164-
'')
165-
printf "Type 'yes' to continue: "
166-
;;
167-
*)
168-
echo "Restore aborted." 1>&2
169-
exit 1
170-
;;
171-
esac
172-
done
177+
if is_external_database_snapshot && $RESTORE_SETTINGS; then
178+
echo "WARNING: This operation will also restore the external MySQL connection configuration,"
179+
echo " which may be dangerous if the GHES appliance the snapshot was taken from is still online."
180+
echo
181+
fi
182+
183+
prompt_for_confirmation "Please verify that this is the correct restore host before continuing."
184+
fi
185+
186+
# Prompt to verify that restoring BYODB snapshot to unconfigured instance
187+
# will result in BYODB connection information being restored as well.
188+
if is_external_database_snapshot && ! $instance_configured && ! $FORCE; then
189+
echo
190+
echo "WARNING: This operation will also restore the external MySQL connection configuration,"
191+
echo " which may be dangerous if the GHES appliance the snapshot was taken from is still online."
173192
echo
193+
194+
prompt_for_confirmation "Please confirm this before continuing."
174195
fi
175196

176197
# Log restore start message locally and in /var/log/syslog on remote instance
198+
START_TIME=$(date +%s)
199+
echo 'Start time:' $START_TIME
177200
echo "Starting restore of $GHE_HOSTNAME with backup-utils v$BACKUP_UTILS_VERSION from snapshot $GHE_RESTORE_SNAPSHOT"
178201
ghe_remote_logger "Starting restore from $(hostname) with backup-utils v$BACKUP_UTILS_VERSION / snapshot $GHE_RESTORE_SNAPSHOT ..."
179202

@@ -205,6 +228,14 @@ if $instance_configured; then
205228
fi
206229
fi
207230

231+
# Make sure the GitHub appliance has Actions enabled if the snapshot contains Actions data.
232+
if [ -d "$GHE_RESTORE_SNAPSHOT_PATH/mssql" ] || [ -d "$GHE_RESTORE_SNAPSHOT_PATH/actions" ]; then
233+
if ! ghe-ssh "$GHE_HOSTNAME" -- 'ghe-config --true app.actions.enabled'; then
234+
echo "Error: $GHE_HOSTNAME must have GitHub Actions enabled before restoring since the snapshot contains Actions data. Aborting." 1>&2
235+
exit 1
236+
fi
237+
fi
238+
208239
# Create benchmark file
209240
bm_init > /dev/null
210241

@@ -234,7 +265,7 @@ fi
234265

235266
# Restore settings and license if restoring to an unconfigured appliance or when
236267
# specified manually.
237-
if $restore_settings; then
268+
if $RESTORE_SETTINGS; then
238269
ghe-restore-settings "$GHE_HOSTNAME"
239270
fi
240271

@@ -255,10 +286,10 @@ if [ -s "$GHE_RESTORE_SNAPSHOT_PATH/uuid" ] && ! $CLUSTER; then
255286
ghe-ssh "$GHE_HOSTNAME" -- "sudo rm -rf /data/user/consul/raft"
256287
fi
257288

258-
if is_service_external 'mysql' "$GHE_RESTORE_SNAPSHOT_PATH/settings.json"; then
289+
if is_external_database_snapshot; then
259290
appliance_strategy="external"
260291
backup_snapshot_strategy="external"
261-
else
292+
else
262293
if is_binary_backup_feature_on; then
263294
appliance_strategy="binary"
264295
else
@@ -272,8 +303,22 @@ else
272303
fi
273304
fi
274305

275-
echo "Restoring MySQL database from ${backup_snapshot_strategy} backup snapshot on an appliance configured for ${appliance_strategy} backups ..."
276-
ghe-restore-mysql "$GHE_HOSTNAME" 1>&3
306+
if is_external_database_target_or_snapshot && $SKIP_MYSQL; then
307+
echo "Skipping MySQL restore."
308+
else
309+
echo "Restoring MySQL database from ${backup_snapshot_strategy} backup snapshot on an appliance configured for ${appliance_strategy} backups ..."
310+
ghe-restore-mysql "$GHE_HOSTNAME" 1>&3
311+
fi
312+
313+
if ghe-ssh "$GHE_HOSTNAME" -- 'ghe-config --true app.actions.enabled'; then
314+
echo "Restoring MSSQL databases ..."
315+
ghe-restore-mssql "$GHE_HOSTNAME" 1>&3
316+
317+
echo "Restoring Actions data ..."
318+
ghe-restore-actions "$GHE_HOSTNAME" 1>&3
319+
echo "* WARNING: Every self-hosted Actions runner that communicates with the restored GHES server must be restarted or reconfigured in order to continue functioning."
320+
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."
321+
fi
277322

278323
commands=("
279324
echo \"Restoring Redis database ...\"
@@ -405,8 +450,13 @@ else
405450
ghe-ssh "$GHE_HOSTNAME" -- /bin/sh 1>&3
406451
fi
407452

453+
END_TIME=$(date +%s)
454+
echo 'End time:' $END_TIME
455+
echo 'Runtime:' $(($END_TIME - $START_TIME)) 'seconds'
456+
408457
echo "Restore of $GHE_HOSTNAME from snapshot $GHE_RESTORE_SNAPSHOT finished."
409458

410459
if ! $instance_configured; then
411460
echo "To complete the restore process, please visit https://$hostname/setup/settings to review and save the appliance configuration."
412461
fi
462+

debian/changelog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
github-backup-utils (2.21.0) UNRELEASED; urgency=medium
2+
3+
* Introduce option to skip restoring of audit logs #596
4+
* Beta: Execute ghe-backup tasks in parallel #597
5+
* Beta: Execute ghe-restore tasks in parallel #601
6+
* Run repositories restore in parallel #603
7+
* Fix mismatched `bm_start` and `bm_end` commands #607
8+
* remove rsync restore method used by GHES versions prior to 2.13 #608
9+
* Output MySQL backup strategy for clarity during backup and restore #610
10+
11+
-- Hao Jiang <[email protected]> Tue, 09 Jun 2020 17:59:06 +0000
12+
113
github-backup-utils (2.19.5) UNRELEASED; urgency=medium
214

315
* In legacy mode we should use ghe-import-mysql #581

docs/backup-snapshot-file-structure.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ most recent successful snapshot:
3232
|- enterprise.ghl
3333
|- es-scan-complete
3434
|- manage-password
35+
|- mssql
3536
|- mysql.sql.gz
3637
|- redis.rdb
3738
|- settings.json
@@ -44,3 +45,20 @@ most recent successful snapshot:
4445

4546
Note: the `GHE_DATA_DIR` variable set in `backup.config` can be used to change
4647
the disk location where snapshots are written.
48+
49+
## MS SQL Server backup structure
50+
Actions service uses MS SQL Server as backend data store. Each snapshot includes a suite of backup files for MS SQL Server database(s).
51+
52+
To save time in backup, a three-level backup strategy is implemented. Based on the `GHE_MSSQL_BACKUP_CADENCE` setting, at each snapshot, either a (**F**)ull backup, a (**D**)ifferential or a (**T**)ransaction log backup is taken.
53+
54+
As a result, a suite always contains following for each database: a full backup, possibly a differential backup and at least one transaction log backup. Their relationship with timeline is demonstrated below:
55+
```
56+
M---8:00--16:00---T---8:00--16:00---W... (timeline)
57+
58+
F-----------------F-----------------F... (full backup)
59+
#-----D-----D-----#-----D-----D-----#... (differential backup)
60+
T--T--T--T--T--T--T--T--T--T--T--T--T... (transaction log backup)
61+
```
62+
To save disk space, at each snapshot, hard links are created to point to previous backup files. Only newly-created backup files are transferred from appliance to backup host. When a new full/differential backup is created, they become the new source for hard links and new base line for transaction log backups, for subsequent snapshots.
63+
64+
During restore, a suite of backup files are restored in the sequence of full -> differential -> chronological transaction log.

0 commit comments

Comments
 (0)