Skip to content

Commit 3b43bd4

Browse files
LiyangWreevejd
authored andcommitted
Limit (#4)
Add sanity checks to backup process
1 parent e66c4a9 commit 3b43bd4

File tree

5 files changed

+97
-55
lines changed

5 files changed

+97
-55
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export PIP_REPO_PASSWORD=""
88
export PIP_REPO_HOST_WITH_CREDS="https://${PIP_REPO_USERNAME:?}:${PIP_REPO_PASSWORD:?}@na.artifactory.swg-devops.com/artifactory/api/pypi/apset-pypi-local/simple"
99

1010
export BACKUP_LOCAL_PATHS="/etc /var"
11+
export LOCAL_BACKUP_NUMBER=
12+
export MINIMUM_FREE_SPACE=
1113

1214
export MYSQL_ROOT_PASSWORD=
1315
export MYSQL_DATABASE=

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased][]
99

10+
## [1.3.0][] - 2019-07-24
11+
12+
### Added
13+
14+
- `LOCAL_BACKUP_NUMBER` to limit space used to store local backups
15+
- `MINIMUM_FREE_SPACE` to limit minimal space available on storage
16+
1017
## [1.2.0][] - 2019-06-14
1118

1219
### Added
@@ -105,7 +112,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
105112
- Upload to Softlayer
106113
- Travis CI for continuous integration
107114

108-
[unreleased]: https://github.ibm.com/bdu/gamora/compare/1.2.0...HEAD
115+
[unreleased]: https://github.ibm.com/bdu/gamora/compare/1.3.0...HEAD
116+
[1.3.0]: https://github.ibm.com/bdu/gamora/compare/1.2.0...1.3.0
109117
[1.2.0]: https://github.ibm.com/bdu/gamora/compare/1.1.0...1.2.0
110118
[1.1.0]: https://github.ibm.com/bdu/gamora/compare/1.0.1...1.1.0
111119
[1.0.1]: https://github.ibm.com/bdu/gamora/compare/1.0.0...1.0.1

docker-compose.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ services:
3737
- IBM_COS_BUCKET
3838
- IBM_COS_PATH
3939

40+
- LOCAL_BACKUP_NUMBER
4041
- BACKUP_LOCAL_PATHS
42+
- MINIMUM_FREE_SPACE
4143
links:
4244
- mysql
4345
- mongo

gamora/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ RUN echo 'http://dl-3.alpinelinux.org/alpine/edge/community' >> /etc/apk/reposit
2222
ARG PIP_REPO_HOST_WITH_CREDS
2323
ARG PIP_REPO_USERNAME
2424
ARG PIP_REPO_PASSWORD
25-
25+
# hadolint ignore=SC2039
2626
RUN [[ -n "${PIP_REPO_HOST_WITH_CREDS:?}" ]] \
2727
&& [[ -n "${PIP_REPO_USERNAME:?}" ]] \
2828
&& [[ -n "${PIP_REPO_PASSWORD:?}" ]]
@@ -51,6 +51,8 @@ WORKDIR /gamora
5151
COPY ./requirements.txt ./pip
5252
RUN pip download --no-input -r ./pip/requirements.txt --dest ./pip \
5353
&& rm /root/.pypirc /root/.pip/pip.conf
54+
# hadolint ignore=DL4006
55+
RUN curl -sL https://sentry.io/get-cli/ | bash
5456

5557
#######################
5658
#######################

gamora/docker-entrypoint.sh

Lines changed: 81 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#!/bin/bash
2-
set -e
2+
set -eo pipefail
33

44
# Docker volume for backups
55
export BACKUP_PATH=/backups
66

77
NOTIFICATION_SETTINGS=()
88
if [[ -n ${SENTRY_DSN:-} ]]; then
9-
NOTIFICATION_SETTINGS=(-n sentry "--sentry-dsn=${SENTRY_DSN:?}")
9+
NOTIFICATION_SETTINGS=(-n sentry "--sentry-dsn=${SENTRY_DSN:?}")
1010
fi
1111

1212
log() {
@@ -18,44 +18,53 @@ log() {
1818
upload_backup() {
1919
local filename=$1
2020
local remote_path
21-
21+
local backup_prefix=$2
2222
if [[ -z "${SOFTLAYER_PATH:-}" ]]; then
2323
log "Skipping upload because no Softlayer path"
24-
upload_backup_cos "${filename:?}"
24+
upload_backup_cos "${filename:?}" "${backup_prefix:?}"
2525
return
2626
fi
2727

2828
if [[ -z "${SOFTLAYER_USER:-}" ]]; then
2929
log "Skipping upload because no Softlayer user"
30-
upload_backup_cos "${filename:?}"
30+
upload_backup_cos "${filename:?}" "${backup_prefix:?}"
3131
return
3232
fi
3333

3434
if [[ -z "${SOFTLAYER_API_KEY:-}" ]]; then
3535
log "Skipping upload because no Softlayer api key"
36-
upload_backup_cos "${filename:?}"
36+
upload_backup_cos "${filename:?}" "${backup_prefix:?}"
3737
return
3838
fi
3939

4040
remote_path="${SOFTLAYER_PATH:?}/$(date +%Y/%m)"
4141

4242
log "Uploading backup"
4343
monsoon "${NOTIFICATION_SETTINGS[@]}" upload softlayer \
44-
--username "${SOFTLAYER_USER:?}" \
45-
--api-key "${SOFTLAYER_API_KEY:?}" \
46-
--datacenter "${SOFTLAYER_DATACENTER:?}" \
47-
--container "${SOFTLAYER_CONTAINER:?}" \
48-
--network "${SOFTLAYER_NETWORK:?}" \
49-
"${BACKUP_PATH:?}/${filename:?}" \
50-
"${remote_path:?}/${filename:?}" \
51-
&& rm -f "${BACKUP_PATH:?}/${filename:?}"
52-
log "Done: Uploading backup"
44+
--username "${SOFTLAYER_USER:?}" \
45+
--api-key "${SOFTLAYER_API_KEY:?}" \
46+
--datacenter "${SOFTLAYER_DATACENTER:?}" \
47+
--container "${SOFTLAYER_CONTAINER:?}" \
48+
--network "${SOFTLAYER_NETWORK:?}" \
49+
"${BACKUP_PATH:?}/${filename:?}" \
50+
"${remote_path:?}/${filename:?}"
51+
52+
if (($? == 0)); then
53+
54+
find ${BACKUP_PATH:?} -type f -regex ".*${backup_prefix:?}.*" -delete
55+
log "Done: Uploading backup"
56+
else
57+
58+
while [[ "$(find ${BACKUP_PATH:?} -type f -regex ".*${backup_prefix:?}.*" | wc -w)" -ge "${LOCAL_BACKUP_NUMBER:?}" ]]; do
59+
rm -f "${BACKUP_PATH:?}/$(ls -t "${BACKUP_PATH:?}" | grep "${backup_prefix:?}" | tail -1)"
60+
done
61+
fi
5362
}
5463

5564
upload_backup_cos() {
5665
local filename=$1
5766
local remote_path
58-
67+
local backup_prefix=$2
5968
if [[ -z "${IBM_COS_INSTANCE_ID:-}" ]]; then
6069
log "Skipping upload because no IBM COS service instance id"
6170
return
@@ -79,15 +88,23 @@ upload_backup_cos() {
7988

8089
log "Uploading backup to IBM COS"
8190
monsoon "${NOTIFICATION_SETTINGS[@]}" upload cos \
82-
--endpoint-url "${IBM_COS_ENDPOINT_URL}" \
83-
--instance-id "${IBM_COS_INSTANCE_ID}" \
84-
--access-key "${IBM_COS_ACCESS_KEY}" \
85-
--secret-key "${IBM_COS_SECRET_KEY}" \
86-
"${BACKUP_PATH:?}/${filename:?}" \
87-
"${IBM_COS_BUCKET:?}" \
88-
"${remote_path:?}" \
89-
&& rm -f "${BACKUP_PATH:?}/${filename:?}"
90-
log "Done: Uploading backup to IBM COS"
91+
--endpoint-url "${IBM_COS_ENDPOINT_URL}" \
92+
--instance-id "${IBM_COS_INSTANCE_ID}" \
93+
--access-key "${IBM_COS_ACCESS_KEY}" \
94+
--secret-key "${IBM_COS_SECRET_KEY}" \
95+
"${BACKUP_PATH:?}/${filename:?}" \
96+
"${IBM_COS_BUCKET:?}" \
97+
"${remote_path:?}"
98+
if (($? == 0)); then
99+
100+
find ${BACKUP_PATH:?} -type f -regex ".*${backup_prefix:?}.*" -delete
101+
log "Done: Uploading backup to IBM COS"
102+
else
103+
while [[ "$(find ${BACKUP_PATH:?} -type f -regex ".*${backup_prefix:?}.*" | wc -w)" -ge "${LOCAL_BACKUP_NUMBER:?}" ]]; do
104+
rm -f "${BACKUP_PATH:?}/$(ls -t "${BACKUP_PATH:?}" | grep "${backup_prefix:?}" | tail -1)"
105+
done
106+
fi
107+
91108
}
92109

93110
back_up_mongo() {
@@ -102,14 +119,14 @@ back_up_mongo() {
102119

103120
log "Taking mongo backup"
104121
monsoon "${NOTIFICATION_SETTINGS[@]}" backup mongo \
105-
-u "${MONGO_BACKUP_USER}" \
106-
-p "${MONGO_BACKUP_PASSWORD}" \
107-
--host="${MONGO_HOST}" \
108-
--archive="${BACKUP_PATH:?}/${filename}" \
109-
--gzip
122+
-u "${MONGO_BACKUP_USER}" \
123+
-p "${MONGO_BACKUP_PASSWORD}" \
124+
--host="${MONGO_HOST}" \
125+
--archive="${BACKUP_PATH:?}/${filename}" \
126+
--gzip
110127
log "Done: Taking mongo backup"
111128

112-
upload_backup "${filename:?}"
129+
upload_backup "${filename:?}" "mongo_backup"
113130
}
114131

115132
back_up_mysql() {
@@ -124,17 +141,17 @@ back_up_mysql() {
124141

125142
log "Taking mysql backup"
126143
monsoon "${NOTIFICATION_SETTINGS[@]}" backup mysql \
127-
--output="${BACKUP_PATH:?}/${filename}" \
128-
--gzip \
129-
--all-databases \
130-
--single-transaction \
131-
"--host=${MYSQL_HOST:?}" \
132-
"--port=${MYSQL_PORT:?}" \
133-
"--user=${MYSQL_USER:?}" \
134-
"--password=${MYSQL_PASSWORD:?}"
144+
--output="${BACKUP_PATH:?}/${filename}" \
145+
--gzip \
146+
--all-databases \
147+
--single-transaction \
148+
"--host=${MYSQL_HOST:?}" \
149+
"--port=${MYSQL_PORT:?}" \
150+
"--user=${MYSQL_USER:?}" \
151+
"--password=${MYSQL_PASSWORD:?}"
135152
log "Done: Taking mysql backup"
136153

137-
upload_backup "${filename:?}"
154+
upload_backup "${filename:?}" "mysql_backup"
138155
}
139156

140157
# PGDATABASE: gru,nsa,picard,pony,savant,sentry,usher
@@ -160,16 +177,16 @@ back_up_postgresql() {
160177
filename=postgresql_backup_${database:?}_$(date +"%Y%m%d_%H%M%S").archive.gz
161178

162179
monsoon "${NOTIFICATION_SETTINGS[@]}" backup postgresql \
163-
--output="${BACKUP_PATH:?}/${filename}" \
164-
--gzip \
165-
"--host=${PGHOST:?}" \
166-
"--port=${PGPORT:?}" \
167-
"--dbname=${database:?}" \
168-
"--username=${PGUSER:?}" \
169-
"--password" "${PGPASSWORD:?}"
180+
--output="${BACKUP_PATH:?}/${filename}" \
181+
--gzip \
182+
"--host=${PGHOST:?}" \
183+
"--port=${PGPORT:?}" \
184+
"--dbname=${database:?}" \
185+
"--username=${PGUSER:?}" \
186+
"--password" "${PGPASSWORD:?}"
170187
log "Done: Taking PostgreSQL backup of ${database:?}"
171188

172-
upload_backup "${filename:?}"
189+
upload_backup "${filename:?}" "postgresql_backup"
173190
done
174191
}
175192

@@ -194,14 +211,25 @@ back_up_files() {
194211
eval $cmd
195212
log "Done: Taking file backup"
196213

197-
upload_backup "${filename:?}"
214+
upload_backup "${filename:?}" "files_backup"
198215
}
199216

200217
main() {
201-
back_up_files
202-
back_up_mongo
203-
back_up_mysql
204-
back_up_postgresql
218+
local available_space_g
219+
df_out=($(df -m "${BACKUP_PATH:?}"))
220+
available_space_g="$((${df_out[10]:?} / 1024))"
221+
222+
if [[ ${available_space_g:?} -ge ${MINIMUM_FREE_SPACE:?} ]]; then
223+
224+
back_up_files
225+
back_up_mongo
226+
back_up_mysql
227+
back_up_postgresql
228+
else
229+
log "Error: Not Enough Local Storage Space For Backup"
230+
sentry-cli send-event -m "Not Enough Local Storage Space For Backup, available space ${available_space_g} GB, minimum free space: ${MINIMUM_FREE_SPACE} GB"
231+
exit 1
232+
fi
205233
}
206234

207235
main

0 commit comments

Comments
 (0)