-
Notifications
You must be signed in to change notification settings - Fork 14
/
restore.sh
executable file
·294 lines (256 loc) · 7.54 KB
/
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
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#!/bin/bash
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 2.0
#
# The contents of this file are subject to the Mozilla Public License Version
# 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Initial Developer of the Original Code is
# Etienne Rached
# https://github.com/etiennerached
# http://www.tech-and-dev.com/2013/10/backup-godaddy-files-and-databases.html
#
# Portions created by the Initial Developer are Copyright (C) 2013
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Andrew Parlane
# https://github.com/andrewparlane
# ***** END LICENSE BLOCK *****
################# Script Execution ###################
###!!! Edit at your own risk !!!###
#Store Current Date
Date=`date '+%Y-%m-%d_%H-%M-%S'`
#The first argument is the backup directory to use.
#This is not relative to ${backupDirectory}.
#It can be relative to the current directory or absolute
#For examlpe:
# ./restore.sh /abc/def/2017-12-13_16-42
# backup_script/restore.sh backups/2017-12-13_16-42
#It must contains:
# One config.sh
# One .sql or .sql.gz file per database entry in config.sh
# One .cnf for each dbName in config.sh
# One archive starting with files_ with the extension .tar, .tar.gz, .zip
#Specifically this directory should have been generated by the backup.sh script
if [ $# -eq 0 ]
then
echo "Required argument for backup file path" >&2
exit -1
fi
if [ ! -d $1 ]
then
echo "$1 does not exist" >&2
exit -1
fi
#check for config.sh
if [ ! -e "$1/config.sh" ]
then
echo "config.sh does not exist in this backup dir" >&2
exit -1
fi
# get our config
. $1/config.sh
#Check there is exactly 1 .sql or .sql.gz file for each $dbName
#When we find the file we populate dbBackup[] to use later
#And check for the .cnf
dbBackup=""
for i in ${!dbName[@]}
do
if [ -z ${dbName[$i]} ]
then
echo "dbName[$i] is empty, ignoring db" &>2
else
#How many .sql[.gz] files exist for this dbName
backupExists=0
for f in $1/${dbName[$i]}_*;
do
if [ -e $f ]
then
dbBackup[$i]=$f
backupExists+=1
fi
done
#Check that there's at least one
if [ ${backupExists} -eq 0 ]
then
echo "No backup exists for db ${dbName[$i]}" >&2
exit -1
fi
#Check there's not more than one
if [ ! ${backupExists} -eq 1 ]
then
echo "More than one backup exists for ${dbName[$i]}" >&2
exit -1
fi
#Check for the .cnf
if [ ! -e "$1/${dbCnf[$i]}" ]
then
echo "$1/${dbCnf[$i]} does not exist" >&2
exit -1
fi
fi
done
#Now check there is one and only one files_... .tar, .tar.gz, .zip file
backupExists=0
filesBackup=""
for f in $1/files_*;
do
if [ -e $f ]
then
filesBackup=$f
backupExists+=1
fi
done
#Check that there's at least one
if [ ${backupExists} -eq 0 ]
then
echo "No backup exists for files" >&2
exit -1
fi
#Check there's not more than one
if [ ! ${backupExists} -eq 1 ]
then
echo "More than one backup exists for files" >&2
exit -1
fi
##### Restore Databases #####
echo "Restoring databases"
for i in ${!dbName[@]}
do
if [ ! -z ${dbName[$i]} ]
then
while true; do
echo "Attempting to restore database ${dbName[$i]}"
read -p "Do you wish to use the backedup credentials file ${dbCnf[$i]}? [y/n] " yn
case $yn in
[Yy]* )
# use the credential file from the backup directory
mysqlCmd="mysql --defaults-extra-file=$1/$(basename ${dbCnf[$i]}) ${dbName[$i]}";
break;;
[Nn]* )
# enter the credentials manually
# first the host name (defaults to localhost)
read -p "Enter hostname [localhost]: " hostname
if [ -z ${hostname} ]
then
hostname="localhost"
fi
# then the user name
read -p "Enter username: " username
mysqlCmd="mysql -h ${hostname} -u ${username} -p ${dbName[$i]}";
break;;
* ) echo "Please answer yes or no.";;
esac
done
#gzipped?
if [[ "${dbBackup[$i]}" == *.gz ]]
then
gunzip -c ${dbBackup[$i]} | ${mysqlCmd}
else
cat ${dbBackup[$i]} | ${mysqlCmd}
fi
#Check the result
if [ ! $? -eq 0 ]
then
echo "Failed to restore databasa ${dbName[$i]}" >&2
exit -1
else
echo "Database ${dbName[$i]} restored OK"
fi
fi
done
echo "Restored all databases"
##### END OF Restore Databases #####
##### restore Files #####
echo "Restoring files"
#We first extract everything to a temporary directory
tmpRestoreDir="$HOME/tmp_restore_dir_$Date"
if [ -d ${tmpRestoreDir} ]
then
echo "${tmpRestoreDir} already exists. Please delete it and try again" >&2
exit -1
fi
#Create it
mkdir -p ${tmpRestoreDir}
#Check it's there now
if [ ! -d ${tmpRestoreDir} ]
then
echo "Failed to create ${tmpRestoreDir}" >&2
exit -1
fi
#Any existing files that would be overwritten get saved here
tmpReplacedOnDir="$HOME/tmp_replaced_on_$Date"
if [ -d ${tmpReplacedOnDir} ]
then
echo "${tmpReplacedOnDir} already exists. Please delete it and try again" >&2
exit -1
fi
#Create it
mkdir -p ${tmpReplacedOnDir}
#Check it's there now
if [ ! -d ${tmpReplacedOnDir} ]
then
echo "Failed to create ${tmpReplacedOnDir}" >&2
exit -1
fi
echo "Extracting ${filesBackup} to ${tmpRestoreDir} this may take a while"
#Zip
if [[ "${filesBackup}" == *.zip ]]
then
unzip -q ${filesBackup} -d ${tmpRestoreDir}
fi
#Tar
if [[ "${filesBackup}" == *.tar ]]
then
tar -xf ${filesBackup} -C ${tmpRestoreDir}
fi
#Tar GZip
if [[ "${filesBackup}" == *.tar.gz ]]
then
tar -zxf ${filesBackup} -C ${tmpRestoreDir}
fi
#Check the result
if [ ! $? -eq 0 ]
then
echo "Failed to extract ${filesBackup}" >&2
#Delete the empty tmp dir
exit -1
else
echo "Files extracted OK"
fi
#Check the expected files exist in this backup
for i in ${!filesPath[@]}
do
#Does this file path exist in ${tmpRestoreDir}
if [ ! -e "${tmpRestoreDir}/${filesPath[$i]}" ]
then
echo "Expected file / directory ${filesPath[$i]} doesn't exist in ${tmpRestoreDir}" >&2
#Continue anyway
else
#yep, exists
#Check if this file / dir exists in $HOME
if [ -e "$HOME/${filesPath[$i]}" ]
then
#yep, exists there too
#move this to the tmpReplacedOnDir
#so we can replace it with the restored version
mkdir -p "${tmpReplacedOnDir}/$(dirname ${filesPath[$i]})"
mv "$HOME/${filesPath[$i]}" "${tmpReplacedOnDir}/$(dirname ${filesPath[$i]})/"
fi
#Move the restroed file to $HOME
mv "${tmpRestoreDir}/${filesPath[$i]}" "$HOME/${filesPath[$i]}"
fi
done
echo "Files restored OK"
##### END OF Restore Files #####
echo "Backup $1 restored"
echo "Old files stored in ${tmpReplacedOnDir}, delete when ready"
################# END OF Script Execution ###################