-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackup.sh
More file actions
executable file
·198 lines (159 loc) · 6.6 KB
/
backup.sh
File metadata and controls
executable file
·198 lines (159 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env bash
set -euo pipefail
UPDATER_VERSION=0.2.0
printf "\n\u001b[35;1mdddMC - restic-scripts \u001b[36;1mv"
printf $UPDATER_VERSION
printf "\u001b[0m\n\n"
# pretty log function
log() {
echo $(printf '\e[1;30m')"=> $(printf '\033[m')$@"
}
# load embed generators
source ./success.sh
source ./error.sh
source ./prune-error.sh
source ./database_dump_error.sh
# load configuration
if [[ ! -f ./backup.conf ]]; then
log Could not find configuration file! Cannot proceed.
exit 1
fi;
source ./backup.conf
# remove latest logs so they don't grow too big
rm latest.log
# load the files we need to backup.
mapfile -t INCLUDE_FILES < $INCLUDE_FILE
mapfile -t EXCLUDE_FILES < $EXCLUDE_FILE
# remove illegal entries from INCLUDE_FILES
illegal_files=()
for i in "${!INCLUDE_FILES[@]}"; do
if [[ ${INCLUDE_FILES[$i]} =~ ^[[:space:]]*\#.*$ ]]; then
illegal_files+=("${INCLUDE_FILES[$i]}")
fi;
done
for el in "${illegal_files[@]}"; do
for i in "${!INCLUDE_FILES[@]}"; do
if [[ ${INCLUDE_FILES[i]} = $el ]]; then
unset 'INCLUDE_FILES[i]'
fi
done
done
# log the files we back up
log Files to backup:
for file in "${INCLUDE_FILES[@]}"; do
printf "\t- %s\n" "$file"
done
echo;
log Files to exclude:
for file in "${EXCLUDE_FILES[@]}"; do
printf "\t- %s\n" "$file"
done
# nice padding uwu
echo;
# take sql dumps
log Taking MariaDB SQL dumps...
mapfile -t MARIADB_DATABASES < $MARIADB_DATABASE_FILE
# ensure database location exists
mkdir -p $MARIADB_BACKUP_LOCATION
# iterate through database file and take dumps of each database
for database in "${MARIADB_DATABASES[@]}"; do
result=$(docker exec $MARIADB_CONTAINER_NAME mysqldump -u $MARIADB_USERNAME -p$MARIADB_PASSWORD $database > $MARIADB_BACKUP_LOCATION/$database.sql)
if [[ $result -ne 0 ]]; then
log Backup of database "$database" failed!
curl -X POST -H "Content-Type: application/json" -d "$(generate_dump_error_embed $database MariaDB)" https://canary.discord.com/api/v8/webhooks/$WEBHOOK_TOKEN
fi
done
echo;
# take pg dumps
log Taking PostgreSQL dumps...
mapfile -t POSTGRES_DATABASES < $POSTGRES_DATABASE_FILE
# ensure database location exists
mkdir -p $POSTGRES_BACKUP_LOCATION
# iterate through database file and take dumps of each database
for database in "${POSTGRES_DATABASES[@]}"; do
result=$(docker exec $POSTGRES_CONTAINER_NAME pg_dump -U $POSTGRES_USERNAME $database > $POSTGRES_BACKUP_LOCATION/$database.sql)
if [[ $result -ne 0 ]]; then
log Backup of database "$database" failed!
curl -X POST -H "Content-Type: application/json" -d "$(generate_dump_error_embed $database PostgreSQL)" https://canary.discord.com/api/v8/webhooks/$WEBHOOK_TOKEN
fi
done
# perform the backup
# only have a 400mbit connection to HE in CA, USA, therefore a 300mbit limit is enforced on uploads
echo
echo "+ restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE --limit-upload 300000 --limit-download 300000 --verbose backup $(echo ${INCLUDE_FILES[@]} | xargs) --exclude-file=$EXCLUDE_FILE | tee $LOG_FILE"
echo
restic_result=$(restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE --limit-upload 300000 --limit-download 300000 --verbose backup $(echo ${INCLUDE_FILES[@]} | xargs) --exclude-file=$EXCLUDE_FILE | tee $LOG_FILE)
cat $LOG_FILE
echo
RESTIC_LOGS=$(cat $LOG_FILE | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g')
if [[ ! $restic_result ]]; then
log Backup failed!
# assign error vars
RESTIC_ERROR=$(cat $LOG_FILE | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g')
SYSTEMD_LOGS=$(journalctl -xe -q --no-page | grep restic | tail -n 10)
SYSTEMD_LOGS=${SYSTEMD_LOGS:0:2047}
# check if empty - avoids bad request errors
if [[ -z $RESTIC_ERROR ]]; then
RESTIC_ERROR="No logs found."
fi
if [[ -z $SYSTEMD_LOGS ]]; then
SYSTEMD_LOGS="No logs found."
fi
curl -X POST -H "Content-Type: application/json" -d "$(generate_error_embed)" https://canary.discord.com/api/v8/webhooks/$WEBHOOK_TOKEN
log Sent information to Discord.
exit
fi
# # calculate statistics
# echo
# echo "+ restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE stats"
# RESTIC_STATS="$(restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE stats)"
# echo $RESTIC_STATS
# echo
# OUTPUT_DATE="$(date --iso-8601=seconds)"
# OUTPUT_SNAPSHOTS=$(echo $RESTIC_STATS | grep -Eo "Snapshots processed: [0-9]+" | sed -n -e 's/.*Snapshots processed://p' | xargs)
# OUTPUT_FILES=$(echo $RESTIC_STATS | grep -Eo "Total File Count: [0-9]+" | sed -n -e 's/.*Total File Count://p' | xargs)
# OUTPUT_SIZE=$(echo $RESTIC_STATS | grep -Eo "Total Size: [0-9]+\.[0-9]+ (T|G)iB" | sed -n -e 's/.*Total Size://p' | xargs)
# # debug logs
# log Backup performed at $OUTPUT_DATE
# printf "\t- %s\n" "Snapshots processed: $OUTPUT_SNAPSHOTS"
# printf "\t- %s\n" "Total file count: $OUTPUT_FILES"
# printf "\t- %s\n" "Total size: $OUTPUT_SIZE"
# echo
log Backup complete! Computing statistics...
echo
echo "+ restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE stats --mode blobs-per-file | tee $LOG_FILE"
echo
RESTIC_STATS=$(restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE stats --mode blobs-per-file | tee $LOG_FILE)
OUTPUT_DATE=$(date --iso-8601=seconds)
OUTPUT_SIZE=$(echo $RESTIC_STATS | sed -n -e 's/.*Total Size: //p' | tr ',' ' ')
cat $LOG_FILE
echo
# print debug info
log Backup performed at $OUTPUT_DATE
printf "\t- %s\n" "Total size: $OUTPUT_SIZE"
echo
# send embed to discord.
curl -X POST -H "Content-Type: application/json" -d "$(generate_success_embed)" https://canary.discord.com/api/v8/webhooks/$WEBHOOK_TOKEN
log Sent information to Discord.
# only retain the last month of hourly backups, and the last year of monthyl backups.
# helps to keep repository size reasonable.
log Cleaning up previous backups...
echo
echo "+ restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE forget --keep-within 1w --keep-weekly 52 --prune | tee $LOG_FILE"
echo
restic_result=$(restic -r $RESTIC_REPOSITORY --password-file $RESTIC_PASSWORD_FILE forget --keep-within 1w --keep-weekly 52 --prune | tee $LOG_FILE)
cat $LOG_FILE
echo
if [[ ! $restic_result ]]; then
log Cleanup failed!
# assign error vars
RESTIC_ERROR=$(cat $LOG_FILE | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g')
# check if empty - avoids bad request errors
if [[ -z $RESTIC_ERROR ]]; then
RESTIC_ERROR="No logs found."
fi
curl -X POST -H "Content-Type: application/json" -d "$(generate_prune_error_embed)" https://canary.discord.com/api/v8/webhooks/$WEBHOOK_TOKEN
log Sent information to Discord.
exit
fi
log "Cleanup successful! We're done here UwU~"