-
Notifications
You must be signed in to change notification settings - Fork 2
/
migrate.sh
executable file
·445 lines (360 loc) · 9.99 KB
/
migrate.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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
#!/bin/bash
# Repository: https://github.com/ProtocolNebula/server-web-migration
# Author: Rubén Arroyo Ceruelo
# This script copy ispconfig domain (single web and mysql)
# and move to another remote server (ispconfig or not).
# Remote MySQL and folder must exist
#-----------------
# STEP 0 - Configure
# You can set here the default parameters or pass by parameters
# For more information execute ./migrate.sh -h
#-----------------
## DEFAULT SETTINGS
# Main settings
compressFiles=false
# Client to do the copy, available: rsync | scp
sshClient=rsync
# LOCAL folder settings
localFolderTemp=~/temp_migration/
localFolderMigrate=
localBackupRemove=true
# LOCAL mysql settings
localDatabaseHost=localhost
localDatabaseUser=root
localDatabasePassword=
localDatabaseName=
# REMOTE SSH settings
remoteSSHPrivateKeyFile=
remoteSSHPort=22
# REMOTE Folder settings
remoteFolderWWW=
remoteFolderClean=false
remoteBackupRemove=true
# REMOTE MySQL settings (once connected via ssh)
remoteDatabaseHost=localhost
remoteDatabaseUser=root
remoteDatabasePassword=
remoteDatabaseName=
## USAGE HELP
usage () {
cat <<HELP_USAGE
Script that helps migrate folders and databases (mysql) between servers.
Oficial repository: https://github.com/ProtocolNebula/server-web-migration
Usage: $0 [OPTIONS]
You can do:
Only WWW migration (set only folder parameters)
Only MySQL migration (set only MySQL parameters)
Full migration (set both parameters)
Only create local files (set only local parameters)
Full migration (set local and remote parameters)
OPTIONS
GENERAL
--local-folder-temp DEFAULT: ${localFolderTemp}
--compress-files DEFAULT: false - Compress files in zip format instead copying directly
--ssh-client DEFAULT: rsync - rsync or SCP
SSH SETTINGS
--remote-ssh-user-server
--remote-ssh-port DEFAULT: ${remoteSSHPort}
-i | --remote-ssh-private-key-file If not setted, password will prompted
FOLDERS
-s | --local-folder-migrate
-d | --remote-folder-migrate
--local-backup-remove DEFAULT: ${localBackupRemove} - Remove local backup files after success
--remote-folder-clean DEFAULT: ${remoteFolderClean} - Clean remote folder before copy files
--remote-backup-remove DEFAULT: ${remoteBackupRemove} - Remove remote backup files after success
DATABASE (MYSQL)
--local-db-user
--local-db-password
--local-db-name
--remote-db-user
--remote-db-password
--remote-db-name
EXAMPLE:
$0 \\
--compress-files false \\
--local-folder-temp ~/temp_migration/ \\ # DEFAULT PARAMETER
--local-folder-migrate /var/www/domain/web \\
--local-backup-remove true \\
--remote-folder-clean false \\
--remote-folder-migrate /var/www/domain/web \\
--remote-backup-remove true \\
--remote-ssh-user-server user@remoteserver \\
--remote-ssh-port 22 \\
-i ~/.ssh/id_rsa \\
--local-db-user DBUSER \\
--local-db-password PWD \\
--local-db-name DBNAME \\
--remote-db-user DBUSER \\
--remote-db-password PWD \\
--remote-db-name DBNAME
HELP_USAGE
}
## READ INPUT SETTINGS
if [[ "$1" == "" ]]; then
echo "No options specified."
echo -e "Showing help menu...\n"
usage
exit 1
fi
while [[ "$1" != "" ]]; do
case $1 in
# Local Folder Settings
-t | --local-folder-temp )
shift
localFolderTemp=$1
;;
--compress-files )
shift
compressFiles=$1
;;
--ssh-client )
shift
sshClient=$1
;;
-s | --local-folder-migrate )
shift
localFolderMigrate=$1
;;
--remote-folder-clean )
shift
remoteFolderClean=$1
;;
--local-backup-remove )
shift
localBackupRemove=$1
;;
--remote-backup-remove )
shift
remoteBackupRemove=$1
;;
# Local MySQL Settings
--local-db-host )
shift
localDatabaseHost=$1
;;
--local-db-user )
shift
localDatabaseUser=$1
;;
--local-db-password )
shift
localDatabasePassword=$1
;;
--local-db-name )
shift
localDatabaseName=$1
;;
# REMOTE - SSH
--remote-ssh-user-server )
shift
remoteSSHUserAndServer=$1
;;
-i | --remote-ssh-private-key-file )
shift
remoteSSHPrivateKeyFile=$1
;;
--remote-ssh-port )
shift
remoteSSHPort=$1
;;
# Remote Folder Settings
-d | --remote-folder-migrate )
shift
remoteFolderWWW=$1
;;
# Local MySQL Settings
--remote-db-host )
shift
remoteDatabaseHost=$1
;;
--remote-db-user )
shift
remoteDatabaseUser=$1
;;
--remote-db-password )
shift
remoteDatabasePassword=$1
;;
--remote-db-name )
shift
remoteDatabaseName=$1
;;
# Other menu
-h | --help)
usage
exit
;;
*)
usage
exit 1
esac
# Remove $1 and move $2 to $1...
shift
done
echo -e "Starting migration...\n"
## Check all minimal settings
if [ -z "$localFolderTemp" ]; then
echo 'Local folder temp not defined'; exit 2;
elif [[ -n "$localFolderMigrate" && "$localFolderMigrate" = "$localFolderTemp" ]]; then
echo 'CAUTION: Local folder TEMP must be different than MIGRATE folder';
echo 'Temp folder will be empty before backup start';
exit 2;
elif [[ -z "$localFolderMigrate" && -z "$localDatabaseName" ]]; then
echo 'No --local-folder-migrate or --local-db-name defined'; exit 2;
elif [ -n "$remoteSSHUserAndServer" ]; then
if [[ -n "$localFolderMigrate" && -z "$remoteFolderWWW" ]]; then
echo '--remote-folder-migrate null but --local-migrate-folder defined'; exit 2;
elif [[ -z "$localDatabaseName" && -n "$remoteDatabaseName" ]]; then
echo '--local-database-name null but --remote-database-name defined'; exit 2;
elif [[ -n "$localDatabaseName" && -z "$remoteDatabaseName" ]]; then
echo '--remote-database-name but --local-database-name defined'; exit 2;
fi
fi;
# Functions
# $1 = SRC: source file/folder
# $2 = DST: remote file/folder (relative to home directory)
# $3 = ISFOLDER: Is folder? (copy recursive)
sshCopy () {
SRC=$1
DST=$2
ISFOLDER=$3
if [ $sshClient == "scp" ]; then
# Prepare base SCP command to copy files
SCP_COMMAND="scp -P ${remoteSSHPort}"
# Set private key if specified
if [ -n "$remoteSSHPrivateKeyFile" ]; then
SCP_COMMAND="${SCP_COMMAND} \
-i ${remoteSSHPrivateKeyFile}"
fi
if [ $ISFOLDER == "true" ]; then
SCP_COMMAND="${SCP_COMMAND} \
${SRC}"
else
SCP_COMMAND="${SCP_COMMAND} \
-rp ${SRC}/*"
fi
# Set files and folders to SCP
SCP_COMMAND="${SCP_COMMAND} \
${remoteSSHUserAndServer}:${DST}"
# Execute final SCP command
echo Executing $SCP_COMMAND
${SCP_COMMAND}
elif [ $sshClient == "rsync" ]; then
# -e parameter not works correctly passed as function, so RSYNC_RSH is exported (will be read by rsync as -e)
export RSYNC_RSH="ssh -p ${remoteSSHPort}"
# Prepare to copy as files, copying onlyu if files not exist or are different
RSYNC_COMMAND="rsync -Pau"
# Set private key if specified
if [ -n "$remoteSSHPrivateKeyFile" ]; then
export RSYNC_RSHRSYNC_RSH="${RSYNC_RSH} -i ${remoteSSHPrivateKeyFile}"
fi
RSYNC_COMMAND="${RSYNC_COMMAND} \
${SRC} \
${remoteSSHUserAndServer}:${DST}"
# Execute final SCP command
echo Executing $RSYNC_COMMAND
${RSYNC_COMMAND}
else
echo "SSH Client not found"
exit 1
fi
}
echo "Create / Wipe temporal folder (${localFolderTemp})"
mkdir -p ${localFolderTemp}
rm -rf ${localFolderTemp}/{.[!.],}*
#-----------------
# STEP 1 - Prepare backup
#-----------------
ZIP_FILE_NAME=web.zip
ZIP_FILE_PATH=${localFolderTemp}${ZIP_FILE_NAME}
# Dump and ZIP SQL
DB_FILE_NAME=DB_TO_MIGRATE.sql
DB_FILE_PATH=${localFolderTemp}/${DB_FILE_NAME}
if [ -n "$localDatabaseName" ]; then
echo "Dumping MySQL database (${localDatabaseName})"
mysqldump \
-h ${localDatabaseHost} \
-u ${localDatabaseUser} \
--password=${localDatabasePassword} \
${localDatabaseName} > ${DB_FILE_PATH}
echo "Compressing db file"
zip -q -j ${ZIP_FILE_PATH} ${DB_FILE_PATH}
fi
# ZIP SQL + files
if [[ -n "$localFolderMigrate" && $compressFiles == "true" ]]; then
echo "Compressing folder to migrate"
# Zip file from content folder to remove parent path in zip file
(cd ${localFolderMigrate} && \
zip -q -r ${ZIP_FILE_PATH} . && \
cd -)
fi
#-----------------
# STEP 2 - Copy to remote server
#-----------------
# No migration required?
if [ -z "$remoteSSHUserAndServer" ]; then
echo "No destination server setted."
echo "Backup done successfully"
exit 0
fi
echo "Sending files to remote server"
# Set * to match also hidden files
shopt -s dotglob
if [ $compressFiles == "true" ]; then
sshCopy $ZIP_FILE_PATH $remoteFolderWWW false
else
if [ -n "$localFolderMigrate" ]; then
sshCopy "$localFolderMigrate/*" "$remoteFolderWWW" true
fi
if [ -n "$localDatabaseName" ]; then
sshCopy "${DB_FILE_PATH}" "$remoteFolderWWW" false
fi
fi
echo "Files sended successfully"
#-----------------
# STEP 3 - Restore on remote server
#-----------------
echo "Restoring data on remote server..."
# Main SSH command
SSH_COMMAND="ssh -p ${remoteSSHPort}"
# Add private key file if specified
if [ -n "$remoteSSHPrivateKeyFile" ]; then
SSH_COMMAND="${SSH_COMMAND} -i ${remoteSSHPrivateKeyFile}"
fi
# Add remote connection data
SSH_COMMAND="${SSH_COMMAND} ${remoteSSHUserAndServer}"
# Connect to remote SSH server and execute batch scripts to unzip and import SQL
${SSH_COMMAND} << EOF
# Move to remote folder
cd ${remoteFolderWWW};
# Remote folder clean before restore
if [[ $compressFiles == "true" && $remoteFolderClean == true ]]; then
echo "Cleaning remote folder"
rm -rf !\("${ZIP_FILE_NAME}"\)9$0 150
fi
if [ $compressFiles == "true" ]; then
# Unzip file (contain web/mysql)
unzip -u -o -q ${ZIP_FILE_NAME};
fi
# Import mysql if db file
if [ -n "$remoteDatabaseName" ]; then
mysql \
-h ${remoteDatabaseHost} \
-u ${remoteDatabaseUser} \
--password=${remoteDatabasePassword} \
${remoteDatabaseName} \
< ${DB_FILE_NAME}
fi
# Remote backup files remove
if [ "$remoteBackupRemove" = true ]; then
echo "Removing remote backup files"
rm -rf ${ZIP_FILE_NAME} ${DB_FILE_NAME}
fi
EOF
# Local backup files remove
if [ "$remoteBackupRemove" = true ]; then
echo "Removing local backup files"
rm -rf ${ZIP_FILE_PATH} ${DB_FILE_PATH}
fi
echo "Migration success"