-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackup-restore.sh
executable file
·153 lines (135 loc) · 4.38 KB
/
backup-restore.sh
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
#!/bin/sh
set -euo pipefail
BACKUP=0
RESTORE=0
TAR=""
DB=""
RESTART=0
# Usage info
show_help() {
cat << EOF
Usage: ${0##*/} [-h] [-r|-b backup or restore. Mutually exclusive.] [-d db-backup.sql file] [-t data-backup.tgz]...
-h Display this help and exit 0.
-b A backup operation.
-r A restore operation.
-d <NAME> The database .sql file to restore.
-t <NAME> The file system .tgz file to restore.
EOF
}
backup() {
DATE=$(date +"%d%m%y%y_%H%M%S")
local RUNNING=$(docker ps | awk '{print $NF}' | grep -E "^bitbucket$" | cat)
if [ "${RUNNING}" ]; then
RESTART=1
echo "Stopping Bitbucket during backup..."
docker-compose down --timeout 90 > /dev/null 2>&1
fi
docker-compose -f backup-restore-compose.yml up -d > /dev/null 2>&1
echo "Backing up Bitbucket data directory..."
docker exec backup-bitbucket sh -c "cd /bitbucket_data && mkdir -p /host/backup/ && tar czf /host/backup/${DATE}-bitbucket-data.tgz ."
echo "Backing up database with pg_dump..."
docker exec backup-bitbucket sh -c "pg_dump --username bitbucket --format=p --dbname=bitbucket --file=/host/backup/${DATE}-bitbucket-db.sql"
docker-compose -f backup-restore-compose.yml down --timeout 30 > /dev/null 2>&1
# If it was running AND this is a BACKUP operation bring it back to previous state.
# Otherwise bring it back to previous state after RESTORE operation.
if [[ "${RESTART}" == 1 && "${BACKUP}" == 1 ]]; then
docker-compose up -d > /dev/null 2>&1
fi
}
restore() {
backup # Make a fresh backup in case things go wrong.
docker-compose -f backup-restore-compose.yml up -d > /dev/null 2>&1
if [ "${DB}" ]; then
echo "Restoring database with ${DB}"
docker exec -it backup-bitbucket sh -c "psql -U bitbucket -d bitbucket < /host/backup/${DB}"
fi
if [ "${TAR}" ]; then
echo "Restoring data directory with ${TAR}"
docker exec -it backup-bitbucket sh -c "tar -xzf /host/backup/${TAR} --directory /bitbucket_data"
fi
docker-compose -f backup-restore-compose.yml down > /dev/null 2>&1
if [[ $RESTART == 1 ]]; then
docker-compose up -d /dev/null 2>&1
fi
}
OPTIND=1
while getopts 'd:t:rbh' opt; do
case $opt in
h)
show_help
exit 0
;;
b)
BACKUP=1
;;
r)
RESTORE=1
;;
d)
if [ ! -f "${OPTARG}" ]; then
echo "The file ${OPTARG} does not seem to exist! Exiting..."
exit 1
elif [ ! "${OPTARG##*.}" == "sql" ]; then
echo "This doesn't look like a .sql file! Exiting..."
exit 1
fi
DB="${OPTARG##*/}"
;;
t)
if [ ! -f "${OPTARG}" ]; then
echo "The file ${OPTARG} does not seem to exist! Exiting..."
exit 1
elif [ ! "${OPTARG##*.}" == "tgz" ]; then
echo "This doesn't look like a zipped .tgz! Exiting..."
exit 1
fi
TAR="${OPTARG##*/}"
;;
\?)
show_help
exit 1
;;
esac
done
shift "$((OPTIND-1))" # Discard the options and sentinel --
if [[ $RESTORE == 1 && $BACKUP == 1 ]]; then
echo "You can only specify -b OR -r"
show_help
exit 1
elif [[ $RESTORE == 1 && ( ! $TAR && ! $DB ) ]]; then
echo "You must provide something to restore! Exiting..."
show_help
exit 1
fi
if [ $RESTORE == 1 ]; then
# User confirmation
echo "-----------------------------------------------------"
if [[ ! "${DB}" || ! "${TAR}" ]]; then
read -p "This looks like a partial restore! Are you SURE?
Database SQL file: ${DB}
Data directory .tgz file: ${TAR}
A fresh BACKUP will be done prior to a restore.
[Y|y]:[N|n] : " ANSWER
else
read -p "Restore the following.
Database SQL file: ${DB}
Data directory .tgz file: ${TAR}
A fresh BACKUP will be done prior to a restore.
[Y|y]:[N|n] : " ANSWER
fi
echo "-----------------------------------------------------"
case $ANSWER in
Y|y)
restore
;;
N|n)
exit 0
;;
*)
echo "You must answer [Y|y] or [N|n]."
exit 1
;;
esac
else
backup
fi