-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstransfer.sh
339 lines (322 loc) · 11.4 KB
/
stransfer.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
#!/usr/bin/env bash
# Default values
CONFIG=".stransfer.conf"
SSH_PORT=22
CLEAR_LOCAL_DIR=false
TRANSFER_METHOD=rsync
OLD_SSH_VERSION=false
# / Default values
function printUsage(){
echo -e "\nUsage: ./site_transfer.sh -s <step> -f -h\n"
echo -e "Keys:\n"
echo "-s: select steps to run, allowed values: addStransferPubKey, copyDatabase or copyFiles"
echo "-f: set a custom configuration file path, ./.stransfer.conf is used by default"
echo "-h | --help: print help"
echo -e "\nVariables for the configuration file:"
echo "
TRANSFER_METHOD - the method of files transfering, rsync (by default) or scp
REMOTE_SSH_CONNECTION - the ssh connection string in a format <user>@<host>
AUTH_TYPE - a type of ssh authentification. Allowed values: stransferPubkey or sshpass. If the public key authentification is necessary, check the option PubkeyAuthentication isn't set to no in the sshd configuration
REMOTE_SSH_PASSWORD - the password for ssh conection. It's used when AUTH_TYPE is set to sshpass
SSH_PORT - the port of the ssh connection, it's set to 22 by default
LOCAL_PATH - the files' transfering aim directory on the local server
REMOTE_PATH - the files' transfering source directory on the remote server
CLEAR_LOCAL_DIR - if it set to true (by default), a local directory is cleared before files transfer
LOCAL_DB_NAME - a database name on the current server
LOCAL_DB_USER - a user with permissions to the local database
LOCAL_DB_PASSWORD - the local database user password
REMOTE_DB_NAME - a database name on the remote server
REMOTE_DB_USER - a user with permissions to the remote database
REMOTE_DB_PASSWORD - the remote database user password
LOCAL_DUMP_PATH - a temporary local directory for database dump
REMOTE_DUMP_PATH - a temporary remote directory for database dump
";
}
function printMessage() {
if [ -z "$1" ]; then
return 1
fi
echo -e "$1"
}
# Don't use numbers as arguments
function validate() {
local STATUS=0
for i in "$@"; do
local TMP="${!i}"
if [ -z "$TMP" ] || [ "$TMP" = "$i" ]; then
printMessage "\t- $i";
STATUS=1
fi
done
return $STATUS
}
function checkSSHConnection(){
local STATUS
local CHECKED_AUTH_TYPE
if [ -z "$1" ]; then
CHECKED_AUTH_TYPE="$AUTH_TYPE";
else
CHECKED_AUTH_TYPE="$1";
fi
case "${CHECKED_AUTH_TYPE}" in
stransferPubkey)
STATUS=$(ssh -p "${SSH_PORT}" -i "$HOME/.ssh/stransfer" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" echo ok 2>&1)
;;
sshpass)
STATUS=$(sshpass -p "${REMOTE_SSH_PASSWORD}" ssh -p "${SSH_PORT}" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" echo ok 2>&1)
;;
*)
STATUS=$(ssh -p "${SSH_PORT}" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" echo ok 2>&1)
;;
esac
if [[ $STATUS == ok ]]; then
true
else
false
fi
}
function runSSHCommand {
if [ -z "$1" ]; then
return 1;
fi
if [ -z "$2" ]; then
COMMAND="$AUTH_TYPE";
else
COMMAND="$2";
fi
case "$COMMAND" in
stransferPubkey)
ssh -p "${SSH_PORT}" -i "$HOME/.ssh/stransfer" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" "$1"
;;
sshpass)
sshpass -p "${REMOTE_SSH_PASSWORD}" ssh -p "${SSH_PORT}" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" "$1"
;;
*)
ssh -p "${SSH_PORT}" -o BatchMode=yes -o ConnectTimeout=5 "${REMOTE_SSH_CONNECTION}" "$1"
;;
esac
}
function addStransferPubKey(){
if [ -z ${REMOTE_SSH_PASSWORD+x} ]; then
local PASSWORD1 PASSWORD2 TMP_PASSWORD
for i in {1..3}; do
read -srep $'\nPlease, set a password for ssh connection: ' PASSWORD1
read -srep $'\nConfirm the password: ' PASSWORD2
if [[ $PASSWORD1 == "$PASSWORD2" ]]; then
TMP_PASSWORD=$PASSWORD1
break
else
printMessage "\nPasswords don't match"
fi
done
else
TMP_PASSWORD=$REMOTE_SSH_PASSWORD
fi
if [ -z ${TMP_PASSWORD+x} ]; then
printMessage "\nThe password for ssh connection isn't set, operation is interrupted";
return 1;
fi
printMessage "\nTrying to set ssh connection:";
if ! checkSSHConnection "stransferPubkey"; then
if [ ! -f "$HOME/.ssh/stransfer.pub" ]; then
mkdir -m 700 -p "$HOME/.ssh/"
ssh-keygen -t rsa -b 4096 -C "stransfer_autogenerated_key" -N "" -f "$HOME/.ssh/stransfer" -q
fi
sshpass -p "$TMP_PASSWORD" ssh -oStrictHostKeyChecking=no -p ${SSH_PORT} "$REMOTE_SSH_CONNECTION" "mkdir -m 700 -p ~/.ssh/"
if [ $SSH_PORT == 22 ]; then
sshpass -p "$TMP_PASSWORD" ssh-copy-id -i "$HOME/.ssh/stransfer.pub" "$REMOTE_SSH_CONNECTION"
elif [ $OLD_SSH_VERSION == true ]
then
sshpass -p "$TMP_PASSWORD" ssh-copy-id -i "$HOME/.ssh/stransfer.pub" "-p $SSH_PORT $REMOTE_SSH_CONNECTION"
else
sshpass -p "$TMP_PASSWORD" ssh-copy-id -i "$HOME/.ssh/stransfer.pub" -p $SSH_PORT "$REMOTE_SSH_CONNECTION"
fi
else
printMessage "SSH connection is already established, it doesn't have anything to do. Use AUTH_TYPE=stransferPubkey to ssh connection with the created public key"
return 0
fi
if checkSSHConnection; then
printMessage "The SSH connection was successfully established. Use AUTH_TYPE=stransferPubkey to ssh connection with the created public key"
return 0
else
printMessage "Can't establish connection"
return 1
fi
}
function transfer(){
if [ -z "$1" ] || [ -z "$2" ]; then
return 1;
fi
if [[ $TRANSFER_METHOD == scp ]]; then
case "$AUTH_TYPE" in
stransferPubkey)
scp -P ${SSH_PORT} -i "$HOME/.ssh/stransfer" -r "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
sshpass)
sshpass -p "${REMOTE_SSH_PASSWORD}" scp -P ${SSH_PORT} -r "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
*)
scp -P ${SSH_PORT} -r "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
esac
else
case "$AUTH_TYPE" in
stransferPubkey)
rsync -chazP --stats --rsh="ssh -i $HOME/.ssh/stransfer -p"${SSH_PORT} "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
sshpass)
sshpass -p rsync -chazP --stats --rsh="ssh -p"${SSH_PORT} "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
*)
rsync -chazP --stats --rsh="ssh -p"${SSH_PORT} "$REMOTE_SSH_CONNECTION:$1". "$2"
;;
esac
fi
}
function copyDatabase() {
local VALIDATION_OUTPUT
VALIDATION_OUTPUT=$(validate LOCAL_DB_NAME LOCAL_DB_USER LOCAL_DB_PASSWORD REMOTE_DB_NAME REMOTE_DB_USER REMOTE_DB_PASSWORD LOCAL_DUMP_PATH REMOTE_DUMP_PATH REMOTE_SSH_CONNECTION)
if [ $? -ne 0 ]; then
printMessage "Necessary options aren't set: \n${VALIDATION_OUTPUT}"
else
printMessage "A database dump creating:"
runSSHCommand "mkdir -p ${REMOTE_DUMP_PATH} && mysqldump -u ${REMOTE_DB_USER} --password=${REMOTE_DB_PASSWORD} ${REMOTE_DB_NAME} > ${REMOTE_DUMP_PATH}dump.sql"
if runSSHCommand "test -f ${REMOTE_DUMP_PATH}dump.sql" ; then
printMessage "The dump is successfully created\nTrying to transfer the dump:"
transfer ${REMOTE_DUMP_PATH} ${LOCAL_DUMP_PATH}
if [ -f "${LOCAL_DUMP_PATH}dump.sql" ]; then
printMessage "The dump is successfully transfered\nTrying to import the dump:"
mysql -u ${LOCAL_DB_USER} --password=${LOCAL_DB_PASSWORD} -e "CREATE DATABASE IF NOT EXISTS ${LOCAL_DB_NAME}"
mysql -u ${LOCAL_DB_USER} --password=${LOCAL_DB_PASSWORD} ${LOCAL_DB_NAME} < ${LOCAL_DUMP_PATH}dump.sql
if [ $? -ne 0 ]; then
printMessage "The dump isn't imported"
else
printMessage "The dump is imported"
fi
rm -r "$LOCAL_DUMP_PATH"
runSSHCommand "rm -r ${REMOTE_DUMP_PATH}"
else
printMessage "The dump isn't transfered, the operation is stoped"
return 1;
fi
else
printMessage "The dump isn't created, the operation is stoped"
return 1;
fi
fi
}
function copyFiles() {
local VALIDATION_OUTPUT
VALIDATION_OUTPUT=$(validate REMOTE_PATH LOCAL_PATH REMOTE_SSH_CONNECTION)
if [ $? -ne 0 ]; then
printMessage "Necessary options aren't set: \n${VALIDATION_OUTPUT}"
printMessage "Please, set this options in your configuration file and repeat the operation"
else
if [[ $CLEAR_LOCAL_DIR == true ]]; then
find "${LOCAL_PATH}" -mindepth 1 -exec rm -rf {} \;
fi
transfer "$REMOTE_PATH" "$LOCAL_PATH"
fi
}
function operationTitle() {
local OPERATION_TITLE
if [ -z "$1" ]; then
OPERATION_TITLE="A selected operation"
else
OPERATION_TITLE="The operation \"$1\""
fi
clear
printMessage "\n"
printf %"$(tput cols)"s |tr " " "-"
printMessage "$OPERATION_TITLE is run\n"
}
function operationEpilog() {
printMessage "\nDone."
printf %"$(tput cols)"s |tr " " "-"
printMessage "\n"
}
function mainScreen() {
local OPERATION
clear
printMessage "\n\t\tAllowed operations:\n"
printMessage "\t\t1. Create a rsa public key and add it to the remote server"
printMessage "\t\t2. Copy files from the remote server using rsync or scp"
printMessage "\t\t3. Copy database from the remote server"
printMessage "\t\t4. Exit\n"
read -rep $'\t\tEnter your choice: ' OPERATION
case "$OPERATION" in
1)
operationTitle "addStransferPubKey"
addStransferPubKey
operationEpilog
;;
2)
operationTitle "copyFiles"
copyFiles
operationEpilog
;;
3)
operationTitle "copyDatabase"
copyDatabase
operationEpilog
;;
4)
printMessage "\n"
exit 0
;;
*)
printMessage "\n\t\tOperation doesn't found.\n"
;;
esac
read -rep $'\t\tEnter anything to return at the menu: ' OPERATION
printMessage "\n"
mainScreen
}
while getopts 'f:s:h-:' flag; do
case "${flag}" in
-)
case "${OPTARG}" in
*)
printUsage
exit 1
;;
esac;;
s)
STEPS+=("$OPTARG")
;;
f)
CONFIG="${OPTARG}"
;;
h)
printUsage
exit 1
;;
*)
printUsage
exit 1
;;
esac
done
. $(readlink -f "$CONFIG")
if [ ${#STEPS[@]} -ne 0 ]; then
for i in "${STEPS[@]}"
do
if [ "$i" == "addStransferPubKey" ]; then
operationTitle "addStransferPubKey"
addStransferPubKey
operationEpilog
elif [ "$i" == "copyDatabase" ]
then
operationTitle "copyDatabase"
copyDatabase
operationEpilog
elif [ "$i" == "copyFiles" ]
then
operationTitle "copyFiles"
copyFiles
operationEpilog
fi
done
else
mainScreen
fi