backup.sh 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. #!/bin/bash
  2. # Local storage
  3. # Defining local storage function
  4. local_backup(){
  5. rm -f $BACKUP/$user.$backup_new_date.tar
  6. # Checking retention
  7. backup_list=$(ls -lrt $BACKUP/ |awk '{print $9}' |grep "^$user\." | grep ".tar")
  8. backups_count=$(echo "$backup_list" |wc -l)
  9. if [ "$BACKUPS" -le "$backups_count" ]; then
  10. backups_rm_number=$((backups_count - BACKUPS + 1))
  11. # Removing old backup
  12. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  13. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar$//")
  14. echo -e "$(date "+%F %T") Rotated: $backup_date" |\
  15. tee -a $BACKUP/$user.log
  16. rm -f $BACKUP/$backup
  17. done
  18. fi
  19. # Checking disk space
  20. disk_usage=$(df $BACKUP |tail -n1 |tr ' ' '\n' |grep % |cut -f 1 -d %)
  21. if [ "$disk_usage" -ge "$BACKUP_DISK_LIMIT" ]; then
  22. rm -rf $tmpdir
  23. rm -f $BACKUP/$user.log
  24. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  25. echo "Not enough disk space" | $SENDMAIL -s "$subj" "$email" "yes"
  26. check_result "$E_DISK" "Not enough dsk space"
  27. fi
  28. # Creating final tarball
  29. cd $tmpdir
  30. tar -cf $BACKUP/$user.$backup_new_date.tar .
  31. chmod 640 $BACKUP/$user.$backup_new_date.tar
  32. chown admin:$user $BACKUP/$user.$backup_new_date.tar
  33. localbackup='yes'
  34. echo -e "$(date "+%F %T") Local: $BACKUP/$user.$backup_new_date.tar" |\
  35. tee -a $BACKUP/$user.log
  36. }
  37. # FTP Functions
  38. # Defining ftp command function
  39. ftpc() {
  40. /usr/bin/ftp -np $HOST $PORT <<EOF
  41. quote USER $USERNAME
  42. quote PASS $PASSWORD
  43. binary
  44. $1
  45. $2
  46. $3
  47. quit
  48. EOF
  49. }
  50. # Defining ftp storage function
  51. ftp_backup() {
  52. # Checking config
  53. if [ ! -e "$HESTIA/conf/ftp.backup.conf" ]; then
  54. error="ftp.backup.conf doesn't exist"
  55. echo "$error" |$SENDMAIL -s "$subj" $email "yes"
  56. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  57. echo "$error"
  58. errorcode="$E_NOTEXIST"
  59. return "$E_NOTEXIST"
  60. fi
  61. # Parse config
  62. source_conf "$HESTIA/conf/ftp.backup.conf"
  63. # Set default port
  64. if [ -z "$(grep 'PORT=' $HESTIA/conf/ftp.backup.conf)" ]; then
  65. PORT='21'
  66. fi
  67. # Checking variables
  68. if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
  69. error="Can't parse ftp backup configuration"
  70. echo "$error" |$SENDMAIL -s "$subj" $email "yes"
  71. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  72. echo "$error"
  73. errorcode="$E_PARSING"
  74. return "$E_PARSING"
  75. fi
  76. # Debug info
  77. echo -e "$(date "+%F %T") Remote: ftp://$HOST$BPATH/$user.$backup_new_date.tar"
  78. # Checking ftp connection
  79. fconn=$(ftpc)
  80. ferror=$(echo $fconn |grep -i -e failed -e error -e "Can't" -e "not conn")
  81. if [ -n "$ferror" ]; then
  82. error="Error: can't login to ftp ftp://$USERNAME@$HOST"
  83. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  84. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  85. echo "$error"
  86. errorcode="$E_CONNECT"
  87. return "$E_CONNECT"
  88. fi
  89. # Check ftp permissions
  90. if [ -z $BPATH ]; then
  91. ftmpdir="vst.bK76A9SUkt"
  92. else
  93. ftpc "mkdir $BPATH" > /dev/null 2>&1
  94. ftmpdir="$BPATH/vst.bK76A9SUkt"
  95. fi
  96. ftpc "mkdir $ftmpdir" "rm $ftmpdir"
  97. ftp_result=$(ftpc "mkdir $ftmpdir" "rm $ftmpdir" |grep -v Trying)
  98. if [ -n "$ftp_result" ] ; then
  99. error="Can't create ftp backup folder ftp://$HOST$BPATH"
  100. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  101. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  102. echo "$error"
  103. errorcode="$E_FTP"
  104. return "$E_FTP"
  105. fi
  106. # Checking retention
  107. if [ -z $BPATH ]; then
  108. backup_list=$(ftpc "ls" |awk '{print $9}' |grep "^$user\.")
  109. else
  110. backup_list=$(ftpc "cd $BPATH" "ls" |awk '{print $9}' |grep "^$user\.")
  111. fi
  112. backups_count=$(echo "$backup_list" |wc -l)
  113. if [ "$backups_count" -ge "$BACKUPS" ]; then
  114. backups_rm_number=$((backups_count - BACKUPS + 1))
  115. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  116. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar$//")
  117. echo -e "$(date "+%F %T") Rotated ftp backup: $backup_date" |\
  118. tee -a $BACKUP/$user.log
  119. if [ -z $BPATH ]; then
  120. ftpc "delete $backup"
  121. else
  122. ftpc "cd $BPATH" "delete $backup"
  123. fi
  124. done
  125. fi
  126. # Uploading backup archive
  127. if [ "$localbackup" = 'yes' ]; then
  128. cd $BACKUP
  129. if [ -z $BPATH ]; then
  130. ftpc "put $user.$backup_new_date.tar"
  131. else
  132. ftpc "cd $BPATH" "put $user.$backup_new_date.tar"
  133. fi
  134. else
  135. cd $tmpdir
  136. tar -cf $BACKUP/$user.$backup_new_date.tar .
  137. cd $BACKUP/
  138. if [ -z $BPATH ]; then
  139. ftpc "put $user.$backup_new_date.tar"
  140. else
  141. ftpc "cd $BPATH" "put $user.$backup_new_date.tar"
  142. fi
  143. rm -f $user.$backup_new_date.tar
  144. fi
  145. }
  146. # FTP backup download function
  147. ftp_download() {
  148. source_conf "$HESTIA/conf/ftp.backup.conf"
  149. if [ -z "$PORT" ]; then
  150. PORT='21'
  151. fi
  152. if [ -z $BPATH ]; then
  153. ftpc "get $1"
  154. else
  155. ftpc "cd $BPATH" "get $1"
  156. fi
  157. }
  158. #FTP Delete function
  159. ftp_delete() {
  160. source_conf "$HESTIA/conf/ftp.backup.conf"
  161. if [ -z "$PORT" ]; then
  162. PORT='21'
  163. fi
  164. if [ -z $BPATH ]; then
  165. ftpc "delete $1"
  166. else
  167. ftpc "cd $BPATH" "delete $1"
  168. fi
  169. }
  170. # SFTP Functions
  171. # sftp command function
  172. sftpc() {
  173. expect -f "-" <<EOF "$@"
  174. set timeout 60
  175. set count 0
  176. spawn /usr/bin/sftp -o StrictHostKeyChecking=no \
  177. -o Port=$PORT $USERNAME@$HOST
  178. expect {
  179. -nocase "password:" {
  180. send "$PASSWORD\r"
  181. exp_continue
  182. }
  183. -re "Couldn't|(.*)disconnect|(.*)stalled|(.*)not found" {
  184. set count \$argc
  185. set output "Disconnected."
  186. set rc $E_FTP
  187. exp_continue
  188. }
  189. -re ".*denied.*(publickey|password)." {
  190. set output "Permission denied, wrong publickey or password."
  191. set rc $E_CONNECT
  192. }
  193. -re "\[0-9]*%" {
  194. exp_continue
  195. }
  196. "sftp>" {
  197. if {\$count < \$argc} {
  198. set arg [lindex \$argv \$count]
  199. send "\$arg\r"
  200. incr count
  201. } else {
  202. send "exit\r"
  203. set output "Disconnected."
  204. if {[info exists rc] != 1} {
  205. set rc $OK
  206. }
  207. }
  208. exp_continue
  209. }
  210. timeout {
  211. set output "Connection timeout."
  212. set rc $E_CONNECT
  213. }
  214. }
  215. if {[info exists output] == 1} {
  216. puts "\$output"
  217. }
  218. exit \$rc
  219. EOF
  220. }
  221. # SFTP backup download function
  222. sftp_download() {
  223. source_conf "$HESTIA/conf/sftp.backup.conf"
  224. if [ -z "$PORT" ]; then
  225. PORT='22'
  226. fi
  227. cd $BACKUP
  228. if [ -z $BPATH ]; then
  229. sftpc "get $1" > /dev/null 2>&1
  230. else
  231. sftpc "cd $BPATH" "get $1" > /dev/null 2>&1
  232. fi
  233. }
  234. sftp_delete() {
  235. echo "$1"
  236. source_conf "$HESTIA/conf/sftp.backup.conf"
  237. if [ -z "$PORT" ]; then
  238. PORT='22'
  239. fi
  240. echo $BPATH
  241. if [ -z $BPATH ]; then
  242. sftpc "rm $1" > /dev/null 2>&1
  243. else
  244. sftpc "cd $BPATH" "rm $1" > /dev/null 2>&1
  245. fi
  246. }
  247. sftp_backup() {
  248. # Checking config
  249. if [ ! -e "$HESTIA/conf/sftp.backup.conf" ]; then
  250. error="Can't open sftp.backup.conf"
  251. echo "$error" |$SENDMAIL -s "$subj" $email "yes"
  252. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  253. echo "$error"
  254. errorcode="$E_NOTEXIST"
  255. return "$E_NOTEXIST"
  256. fi
  257. # Parse config
  258. source_conf "$HESTIA/conf/sftp.backup.conf"
  259. # Set default port
  260. if [ -z "$(grep 'PORT=' $HESTIA/conf/sftp.backup.conf)" ]; then
  261. PORT='22'
  262. fi
  263. # Checking variables
  264. if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
  265. error="Can't parse sftp backup configuration"
  266. echo "$error" |$SENDMAIL -s "$subj" $email "yes"
  267. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  268. echo "$error"
  269. errorcode="$E_PARSING"
  270. return "$E_PARSING"
  271. fi
  272. # Debug info
  273. echo -e "$(date "+%F %T") Remote: sftp://$HOST/$BPATH/$user.$backup_new_date.tar" |\
  274. tee -a $BACKUP/$user.log
  275. # Checking network connection and write permissions
  276. if [ -z $BPATH ]; then
  277. sftmpdir="vst.bK76A9SUkt"
  278. else
  279. sftmpdir="$BPATH/vst.bK76A9SUkt"
  280. fi
  281. sftpc "mkdir $BPATH" > /dev/null 2>&1
  282. sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
  283. rc=$?
  284. if [[ "$rc" != 0 ]]; then
  285. case $rc in
  286. $E_CONNECT) error="Can't login to sftp host $HOST" ;;
  287. $E_FTP) error="Can't create temp folder on sftp $HOST" ;;
  288. esac
  289. echo "$error" |$SENDMAIL -s "$subj" $email "yes"
  290. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  291. echo "$error"
  292. errorcode="$rc"
  293. return "$rc"
  294. fi
  295. # Checking retention
  296. if [ -z $BPATH ]; then
  297. backup_list=$(sftpc "ls -l" |awk '{print $9}'|grep "^$user\.")
  298. else
  299. backup_list=$(sftpc "cd $BPATH" "ls -l" |awk '{print $9}'|grep "^$user\.")
  300. fi
  301. backups_count=$(echo "$backup_list" |wc -l)
  302. if [ "$backups_count" -ge "$BACKUPS" ]; then
  303. backups_rm_number=$((backups_count - BACKUPS + 1))
  304. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  305. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar.*$//")
  306. echo -e "$(date "+%F %T") Rotated sftp backup: $backup_date" |\
  307. tee -a $BACKUP/$user.log
  308. if [ -z $BPATH ]; then
  309. sftpc "rm $backup" > /dev/null 2>&1
  310. else
  311. sftpc "cd $BPATH" "rm $backup" > /dev/null 2>&1
  312. fi
  313. done
  314. fi
  315. # Uploading backup archive
  316. echo "$(date "+%F %T") Uploading $user.$backup_new_date.tar"|tee -a $BACKUP/$user.log
  317. if [ "$localbackup" = 'yes' ]; then
  318. cd $BACKUP
  319. if [ -z $BPATH ]; then
  320. sftpc "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  321. else
  322. sftpc "cd $BPATH" "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  323. fi
  324. else
  325. cd $tmpdir
  326. tar -cf $BACKUP/$user.$backup_new_date.tar .
  327. cd $BACKUP/
  328. if [ -z $BPATH ]; then
  329. sftpc "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  330. else
  331. sftpc "cd $BPATH" "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  332. fi
  333. rm -f $user.$backup_new_date.tar
  334. fi
  335. }
  336. # Google backup download function
  337. google_backup() {
  338. # Defining google settings
  339. source_conf "$HESTIA/conf/google.backup.conf"
  340. gsutil="$HESTIA/3rdparty/gsutil/gsutil"
  341. export BOTO_CONFIG="$HESTIA/conf/.google.backup.boto"
  342. # Debug info
  343. echo -e "$(date "+%F %T") Remote: gs://$BUCKET/$BPATH/$user.$backup_new_date.tar"
  344. # Checking retention
  345. backup_list=$(${gsutil} ls gs://$BUCKET/$BPATH/$user.* 2>/dev/null)
  346. backups_count=$(echo "$backup_list" |wc -l)
  347. if [ "$backups_count" -ge "$BACKUPS" ]; then
  348. backups_rm_number=$((backups_count - BACKUPS))
  349. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  350. echo -e "$(date "+%F %T") Rotated gcp backup: $backup"
  351. $gsutil rm $backup > /dev/null 2>&1
  352. done
  353. fi
  354. # Uploading backup archive
  355. echo -e "$(date "+%F %T") Uploading $user.$backup_new_date.tar ..."
  356. if [ "$localbackup" = 'yes' ]; then
  357. cd $BACKUP
  358. ${gsutil} cp $user.$backup_new_date.tar gs://$BUCKET/$BPATH/ > /dev/null 2>&1
  359. else
  360. cd $tmpdir
  361. tar -cf $BACKUP/$user.$backup_new_date.tar .
  362. cd $BACKUP/
  363. ${gsutil} cp $user.$backup_new_date.tar gs://$BUCKET/$BPATH/ > /dev/null 2>&1
  364. rc=$?
  365. rm -f $user.$backup_new_date.tar
  366. if [ "$rc" -ne 0 ]; then
  367. check_result "$E_CONNECT" "gsutil failed to upload $user.$backup_new_date.tar"
  368. fi
  369. fi
  370. }
  371. google_download() {
  372. source_conf "$HESTIA/conf/google.backup.conf"
  373. gsutil="$HESTIA/3rdparty/gsutil/gsutil"
  374. export BOTO_CONFIG="$HESTIA/conf/.google.backup.boto"
  375. ${gsutil} cp gs://$BUCKET/$BPATH/$1 $BACKUP/ > /dev/null 2>&1
  376. if [ "$?" -ne 0 ]; then
  377. check_result "$E_CONNECT" "gsutil failed to download $1"
  378. fi
  379. }
  380. # BackBlaze B2 backup function
  381. b2_backup() {
  382. # Defining backblaze b2 settings
  383. source_conf "$HESTIA/conf/b2.backup.conf"
  384. # Recreate backblaze auth file ~/.b2_account_info (for situation when key was changed in b2.backup.conf)
  385. b2 clear-account > /dev/null 2>&1
  386. b2 authorize-account $B2_KEYID $B2_KEY > /dev/null 2>&1
  387. # Uploading backup archive
  388. echo -e "$(date "+%F %T") Upload to B2: $user/$user.$backup_new_date.tar"
  389. if [ "$localbackup" = 'yes' ]; then
  390. cd $BACKUP
  391. b2 upload-file $BUCKET $user.$backup_new_date.tar $user/$user.tar
  392. else
  393. cd $tmpdir
  394. tar -cf $BACKUP/$user.$backup_new_date.tar .
  395. cd $BACKUP/
  396. b2 upload-file $BUCKET $user.$backup_new_date.tar $user/$user.tar
  397. rc=$?
  398. rm -f $user.$backup_new_date.tar
  399. if [ "$rc" -ne 0 ]; then
  400. check_result "$E_CONNECT" "b2 failed to upload $user.$backup_new_date.tar"
  401. fi
  402. fi
  403. # Checking retention
  404. backup_list=$(b2 ls --long $BUCKET $user | cut -f 1 -d ' ' 2>/dev/null)
  405. backups_count=$(echo "$backup_list" |wc -l)
  406. if [ "$backups_count" -ge "$BACKUPS" ]; then
  407. backups_rm_number=$((backups_count - BACKUPS))
  408. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  409. backup_file_name=$(b2 get-file-info $backup | grep fileName | cut -f 4 -d '"' 2>/dev/null)
  410. echo -e "$(date "+%F %T") Rotated b2 backup: $backup_file_name"
  411. b2 delete-file-version $backup > /dev/null 2>&1
  412. done
  413. fi
  414. }
  415. b2_download() {
  416. # Defining backblaze b2 settings
  417. source_conf "$HESTIA/conf/b2.backup.conf"
  418. # Recreate backblaze auth file ~/.b2_account_info (for situation when key was changed in b2.backup.conf)
  419. b2 clear-account > /dev/null 2>&1
  420. b2 authorize-account $B2_KEYID $B2_KEY > /dev/null 2>&1
  421. cd $BACKUP
  422. b2 download-file-by-name $BUCKET $user/$1 $1 > /dev/null 2>&1
  423. if [ "$?" -ne 0 ]; then
  424. check_result "$E_CONNECT" "b2 failed to download $user.$1"
  425. fi
  426. }