v-backup-user 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. #!/bin/bash
  2. # info: backup system user with all its objects
  3. # options: USER NOTIFY
  4. #
  5. # The call is used for backing up user with all its domains and databases.
  6. #----------------------------------------------------------#
  7. # Variable&Function #
  8. #----------------------------------------------------------#
  9. # Importing system variables
  10. source /etc/profile
  11. # Argument definition
  12. user=$1
  13. notify=${2-no}
  14. # Includes
  15. source $HESTIA/func/main.sh
  16. source $HESTIA/func/domain.sh
  17. source $HESTIA/func/db.sh
  18. source $HESTIA/conf/hestia.conf
  19. #----------------------------------------------------------#
  20. # Verifications #
  21. #----------------------------------------------------------#
  22. check_args '1' "$#" 'USER [NOTIFY]'
  23. is_format_valid 'user'
  24. is_system_enabled "$BACKUP_SYSTEM" 'BACKUP_SYSTEM'
  25. is_object_valid 'user' 'USER' "$user"
  26. is_object_unsuspended 'user' 'USER' "$user"
  27. is_backup_enabled
  28. #----------------------------------------------------------#
  29. # Action #
  30. #----------------------------------------------------------#
  31. # block backup if current hour is after 6 AM
  32. WAIT_LOOP_ENTERED=0
  33. if pgrep -x "v-backup-users" > /dev/null
  34. then
  35. hour=$(date +"%H");
  36. while [ "$hour" -gt "6" ]; do
  37. if [ "$WAIT_LOOP_ENTERED" -eq 0 ]; then
  38. $BIN/v-restart-web-backend
  39. fi
  40. WAIT_LOOP_ENTERED=1
  41. current_date_time="`date "+%Y-%m-%d %H:%M:%S"`";
  42. echo "$current_date_time - wait for backup user $user - hour $hour";
  43. sleep 300
  44. hour=$(date +"%H");
  45. done
  46. fi
  47. # Set backup directory if undefined
  48. if [ -z "$BACKUP" ]; then
  49. BACKUP=/backup
  50. fi
  51. mkdir -p $BACKUP
  52. # Get current time
  53. start_time=$(date '+%s')
  54. # Set notification email and subject
  55. subj="$user → backup failed"
  56. email=$(grep CONTACT $HESTIA/data/users/admin/user.conf |cut -f 2 -d \')
  57. # Checking load average
  58. la=$(cat /proc/loadavg |cut -f 1 -d ' ' |cut -f 1 -d '.')
  59. i=0
  60. while [ "$la" -ge "$BACKUP_LA_LIMIT" ]; do
  61. echo -e "$(date "+%F %T") Load Average $la"
  62. sleep 60
  63. if [ "$i" -ge "15" ]; then
  64. la_error="LoadAverage $la is above threshold"
  65. echo "$la_error" |$SENDMAIL -s "$subj" $email $notify
  66. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  67. check_result $E_LA "$la_error"
  68. fi
  69. la=$(cat /proc/loadavg |cut -f 1 -d ' ' |cut -f 1 -d '.')
  70. (( ++i))
  71. done
  72. if [ -z "$BACKUP_TEMP" ]; then
  73. BACKUP_TEMP=$BACKUP
  74. fi
  75. # Creating temporary directory
  76. tmpdir=$(mktemp -p $BACKUP_TEMP -d)
  77. if [ "$?" -ne 0 ]; then
  78. echo "Can't create tmp dir $tmpdir" |$SENDMAIL -s "$subj" $email $notify
  79. check_result $E_NOTEXIST "can't create tmp dir"
  80. fi
  81. # Backup sys configs
  82. echo "-- SYSTEM --" |tee $BACKUP/$user.log
  83. mkdir $tmpdir/hestia
  84. echo -e "$(date "+%F %T") $user.conf" |tee -a $BACKUP/$user.log
  85. cp -r $USER_DATA/user.conf $tmpdir/hestia/
  86. cp -r $USER_DATA/ssl $tmpdir/hestia/
  87. if [ -e "$USER_DATA/stats.log" ]; then
  88. echo -e "$(date "+%F %T") stats.log" |tee -a $BACKUP/$user.log
  89. cp -r $USER_DATA/stats.log $tmpdir/hestia/
  90. fi
  91. if [ -e "$USER_DATA/history.log" ]; then
  92. echo -e "$(date "+%F %T") history.log" |tee -a $BACKUP/$user.log
  93. cp -r $USER_DATA/history.log $tmpdir/hestia/
  94. fi
  95. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  96. echo -e "$(date "+%F %T") backup-excludes.conf" |tee -a $BACKUP/$user.log
  97. cp -r $USER_DATA/backup-excludes.conf $tmpdir/hestia/
  98. fi
  99. # Backup PAM
  100. mkdir $tmpdir/pam
  101. echo -e "$(date "+%F %T") pam" |tee -a $BACKUP/$user.log
  102. grep "^$user:" /etc/passwd > $tmpdir/pam/passwd
  103. grep "^$user:" /etc/shadow > $tmpdir/pam/shadow
  104. grep "^$user:" /etc/group > $tmpdir/pam/group
  105. echo
  106. # Parsing excludes
  107. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  108. source $USER_DATA/backup-excludes.conf
  109. fi
  110. # WEB domains
  111. if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB" != '*' ]; then
  112. echo -e "\n-- WEB --" |tee -a $BACKUP/$user.log
  113. mkdir $tmpdir/web/
  114. # Parsing domain exclusions
  115. conf="$USER_DATA/web.conf"
  116. for domain in $(search_objects 'web' 'SUSPENDED' "*" 'DOMAIN'); do
  117. exclusion=$(echo -e "$WEB" |tr ',' '\n' |grep "^$domain$")
  118. if [ -z "$exclusion" ]; then
  119. web_list="$web_list $domain"
  120. else
  121. echo "$(date "+%F %T") excluding $domain"|tee -a $BACKUP/$user.log
  122. fi
  123. done
  124. web_list=$(echo "$web_list" |sed -e "s/ */\ /g" -e "s/^ //")
  125. i=0
  126. for domain in $web_list; do
  127. ((i ++))
  128. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  129. mkdir -p $tmpdir/web/$domain/conf
  130. mkdir -p $tmpdir/web/$domain/hestia
  131. # Get domain variables
  132. domain_idn=$domain
  133. format_domain_idn
  134. get_domain_values 'web'
  135. # Backup web.conf
  136. cd $tmpdir/web/$domain/
  137. conf="$USER_DATA/web.conf"
  138. grep "DOMAIN='$domain'" $conf > hestia/web.conf
  139. # Backup vhost config
  140. conf=$HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.conf
  141. if [ -e "$conf" ]; then
  142. cp $conf conf/$WEB_SYSTEM.conf
  143. else
  144. # old style configs
  145. tpl_file="$WEBTPL/$WEB_SYSTEM/$WEB_BACKEND/$TPL.tpl"
  146. conf="$HOMEDIR/$user/conf/web/$WEB_SYSTEM.conf"
  147. get_web_config_lines $tpl_file $conf
  148. sed -n "$top_line,$bottom_line p" $conf > conf/$WEB_SYSTEM.conf
  149. fi
  150. # Backup ssl vhost
  151. if [ "$SSL" = 'yes' ]; then
  152. conf=$HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.ssl.conf
  153. if [ -e "$conf" ]; then
  154. cp $conf conf/$WEB_SYSTEM.ssl.conf
  155. else
  156. tpl_file="$WEBTPL/$WEB_SYSTEM/$WEB_BACKEND/$TPL.stpl"
  157. conf="$HOMEDIR/$user/conf/web/s$WEB_SYSTEM.conf"
  158. get_web_config_lines $tpl_file $conf
  159. sed -n "$top_line,$bottom_line p" $conf > \
  160. conf/s$WEB_SYSTEM.conf
  161. fi
  162. fi
  163. # Backup proxy config
  164. if [ ! -z "$PROXY_SYSTEM" ] && [ ! -z "$PROXY" ]; then
  165. conf=$HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.conf
  166. if [ -e "$conf" ]; then
  167. cp $conf conf/$PROXY_SYSTEM.conf
  168. else
  169. tpl_file="$WEBTPL/$PROXY_SYSTEM/$PROXY.tpl"
  170. conf="$HOMEDIR/$user/conf/web/$PROXY_SYSTEM.conf"
  171. get_web_config_lines $tpl_file $conf
  172. sed -n "$top_line,$bottom_line p" $conf > \
  173. conf/$PROXY_SYSTEM.conf
  174. fi
  175. fi
  176. # Backup ssl proxy config
  177. if [ ! -z "$PROXY_SYSTEM" ] && [ "$SSL" = 'yes' ]; then
  178. conf=$HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.ssl.conf
  179. if [ -e "$conf" ]; then
  180. cp $conf conf/$PROXY_SYSTEM.ssl.conf
  181. else
  182. tpl_file="$WEBTPL/$PROXY_SYSTEM/$PROXY.stpl"
  183. conf="$HOMEDIR/$user/conf/web/s$PROXY_SYSTEM.conf"
  184. get_web_config_lines $tpl_file $conf
  185. sed -n "$top_line,$bottom_line p" $conf >\
  186. conf/s$PROXY_SYSTEM.conf
  187. fi
  188. fi
  189. # Backup custom config / backup LE config
  190. for sconfig in $(ls $HOMEDIR/$user/conf/web/|grep ".$domain.conf"); do
  191. cp $HOMEDIR/$user/conf/web/$sconfig conf/
  192. done
  193. # Backup ssl certificates
  194. if [ "$SSL" = 'yes' ] ; then
  195. cp $HOMEDIR/$user/conf/web/ssl.$domain.* conf/
  196. cp $USER_DATA/ssl/$domain.* hestia/
  197. fi
  198. # Define exclude arguments
  199. exlusion=$(echo -e "$WEB" |tr ',' '\n' |grep "^$domain:")
  200. set -f
  201. fargs=()
  202. fargs+=(--exclude='logs/*')
  203. if [ ! -z "$exlusion" ]; then
  204. xdirs="$(echo -e "$exlusion" |tr ':' '\n' |grep -v $domain)"
  205. for xpath in $xdirs; do
  206. fargs+=(--exclude=$xpath/*)
  207. echo "$(date "+%F %T") excluding directory $xpath"
  208. msg="$msg\n$(date "+%F %T") excluding directory $xpath"
  209. done
  210. fi
  211. set +f
  212. # Backup files
  213. cd $HOMEDIR/$user/web/$domain
  214. tar -cpf- * ${fargs[@]} |gzip -$BACKUP_GZIP - > $tmpdir/web/$domain/domain_data.tar.gz
  215. done
  216. # Print total
  217. if [ "$i" -eq 1 ]; then
  218. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  219. else
  220. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  221. fi
  222. fi
  223. # DNS domains
  224. if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS" != '*' ]; then
  225. echo -e "\n-- DNS --" |tee -a $BACKUP/$user.log
  226. mkdir $tmpdir/dns/
  227. # Parsing domain exclusions
  228. for domain in $(search_objects 'dns' 'SUSPENDED' "*" 'DOMAIN'); do
  229. exclusion=$(echo "$DNS" |tr ',' '\n' |grep "^$domain$")
  230. if [ -z "$exclusion" ]; then
  231. dns_list="$dns_list $domain"
  232. else
  233. echo "$(date "+%F %T") excluding $domain"
  234. msg="$msg\n$(date "+%F %T") excluding $domain"
  235. fi
  236. done
  237. dns_list=$(echo "$dns_list" |sed -e "s/ */\ /g" -e "s/^ //")
  238. i=0
  239. for domain in $dns_list; do
  240. ((i ++))
  241. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  242. # Building directory tree
  243. mkdir -p $tmpdir/dns/$domain/conf
  244. mkdir -p $tmpdir/dns/$domain/hestia
  245. # Backup dns.conf
  246. cd $tmpdir/dns/$domain/
  247. conf="$USER_DATA/dns.conf"
  248. grep "DOMAIN='$domain'" $conf > hestia/dns.conf
  249. # Backup dns recods
  250. cp $USER_DATA/dns/$domain.conf hestia/$domain.conf
  251. if [ "$DNS_SYSTEM" != 'remote' ]; then
  252. cp $HOMEDIR/$user/conf/dns/$domain.db conf/$domain.db
  253. fi
  254. done
  255. # Print total
  256. if [ "$i" -eq 1 ]; then
  257. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  258. else
  259. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  260. fi
  261. fi
  262. # Mail domains
  263. if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL" != '*' ]; then
  264. echo -e "\n-- MAIL --" |tee -a $BACKUP/$user.log
  265. mkdir $tmpdir/mail/
  266. # Parsing domain exclusions
  267. conf="$USER_DATA/mail.conf"
  268. for domain in $(search_objects 'mail' 'SUSPENDED' "*" 'DOMAIN'); do
  269. check_exl=$(echo "$MAIL" |tr ',' '\n' |grep "^$domain$")
  270. if [ -z "$check_exl" ]; then
  271. mail_list="$mail_list $domain"
  272. else
  273. echo "$(date "+%F %T") excluding $domain"|tee -a $BACKUP/$user.log
  274. fi
  275. done
  276. mail_list=$(echo "$mail_list" |sed -e "s/ */\ /g" -e "s/^ //")
  277. i=0
  278. for domain in $mail_list; do
  279. ((i ++))
  280. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  281. mkdir -p $tmpdir/mail/$domain/conf
  282. mkdir -p $tmpdir/mail/$domain/hestia
  283. domain_idn=$domain
  284. format_domain_idn
  285. # Backup exim config
  286. if [[ "$MAIL_SYSTEM" =~ exim ]]; then
  287. cd $tmpdir/mail/$domain/
  288. cp $HOMEDIR/$user/conf/mail/$domain/* conf/
  289. fi
  290. # Backup mail.conf
  291. conf="$USER_DATA/mail.conf"
  292. grep "DOMAIN='$domain'" $conf > hestia/mail.conf
  293. cp $USER_DATA/mail/$domain.* hestia/
  294. if [ ! -z "$(ls $USER_DATA/mail/|grep *@$domain)" ]; then
  295. cp $USER_DATA/mail/*@$domain.* hestia/
  296. fi
  297. # Backup emails
  298. cd $HOMEDIR/$user/mail/$domain_idn
  299. accounts=()
  300. for account in $(ls); do
  301. exclusion=$(echo "$MAIL" |tr ',' '\n' |grep "$domain:")
  302. exclusion=$(echo "$exclusion" |tr ':' '\n' |grep "^$account$")
  303. # Checking exlusions
  304. if [ -z "$exclusion" ] && [[ "$MAIL_SYSTEM" =~ exim ]]; then
  305. accounts+=($account)
  306. else
  307. echo "$(date "+%F %T") excluding mail account $account" |\
  308. tee -a $BACKUP/$user.log
  309. fi
  310. done
  311. # Compress archive
  312. if [ ${#accounts[@]} -gt 0 ]; then
  313. tar -cpf- ${accounts[@]} |gzip -$BACKUP_GZIP - > $tmpdir/mail/$domain/accounts.tar.gz
  314. fi
  315. done
  316. # Print total
  317. if [ "$i" -eq 1 ]; then
  318. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  319. else
  320. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  321. fi
  322. fi
  323. # Databases
  324. if [ ! -z "$DB_SYSTEM" ] && [ "$DB" != '*' ]; then
  325. echo -e "\n-- DB --" |tee -a $BACKUP/$user.log
  326. mkdir $tmpdir/db/
  327. # Parsing database exclusions
  328. for database in $(search_objects 'db' 'SUSPENDED' "*" 'DB'); do
  329. exclusion=$(echo "$DB" |tr ',' '\n' |grep "^$database$")
  330. if [ -z "$exclusion" ]; then
  331. db_list="$db_list $database"
  332. else
  333. echo "$(date "+%F %T") excluding $database" |\
  334. tee -a $BACKUP/$user.log
  335. fi
  336. done
  337. i=0
  338. conf="$USER_DATA/db.conf"
  339. db_list=$(echo "$db_list" |sed -e "s/ */\ /g" -e "s/^ //")
  340. for database in $db_list; do
  341. ((i ++))
  342. get_database_values
  343. echo -e "$(date "+%F %T") $database ($TYPE)" |tee -a $BACKUP/$user.log
  344. mkdir -p $tmpdir/db/$database/conf
  345. mkdir -p $tmpdir/db/$database/hestia
  346. cd $tmpdir/db/$database/
  347. grep "DB='$database'" $conf > hestia/db.conf
  348. dump="$tmpdir/db/$database/$database.$TYPE.sql"
  349. dumpgz="$tmpdir/db/$database/$database.$TYPE.sql.gz"
  350. grants="$tmpdir/db/$database/conf/$database.$TYPE.$DBUSER"
  351. if [ ! -f "$dumpgz" ]; then
  352. case $TYPE in
  353. mysql) dump_mysql_database ;;
  354. pgsql) dump_pgsql_database ;;
  355. esac
  356. # Compress dump
  357. gzip -$BACKUP_GZIP $dump
  358. fi
  359. done
  360. # Print total
  361. if [ "$i" -eq 1 ]; then
  362. echo -e "$(date "+%F %T") *** $i database ***" |\
  363. tee -a $BACKUP/$user.log
  364. else
  365. echo -e "$(date "+%F %T") *** $i databases ***"|\
  366. tee -a $BACKUP/$user.log
  367. fi
  368. fi
  369. # Cron jobs
  370. if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON" != '*' ]; then
  371. echo -e "\n-- CRON --" |tee -a $BACKUP/$user.log
  372. mkdir $tmpdir/cron/
  373. # Backup cron.conf
  374. cp $USER_DATA/cron.conf $tmpdir/cron/
  375. cron_record=$(wc -l $USER_DATA/cron.conf|cut -f 1 -d ' ')
  376. if [ -e "/var/spool/cron/$user" ]; then
  377. cron_list="$cron_record"
  378. cp /var/spool/cron/$user $tmpdir/cron/
  379. fi
  380. # Print total
  381. if [ "$cron_record" -eq 1 ]; then
  382. echo -e "$(date "+%F %T") *** $cron_record job ***" |\
  383. tee -a $BACKUP/$user.log
  384. else
  385. echo -e "$(date "+%F %T") *** $cron_record jobs ***" |\
  386. tee -a $BACKUP/$user.log
  387. fi
  388. fi
  389. # User Directories
  390. if [ "$USER" != '*' ]; then
  391. echo -e "\n-- User Dir --" |tee -a $BACKUP/$user.log
  392. mkdir $tmpdir/user_dir
  393. cd $HOMEDIR/$user
  394. # Parsing directory exlusions
  395. USER=''
  396. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  397. source $USER_DATA/backup-excludes.conf
  398. fi
  399. fargs=()
  400. for xpath in $(echo "$USER" |tr ',' '\n'); do
  401. fargs+=(-not)
  402. fargs+=(-path)
  403. fargs+=("./$xpath*")
  404. echo "$(date "+%F %T") excluding directory $xpath" |\
  405. tee -a $BACKUP/$user.log
  406. done
  407. IFS=$'\n'
  408. set -f
  409. i=0
  410. for udir in $(ls -a |egrep -v "^conf$|^web$|^dns$|^mail$|^\.\.$|^\.$"); do
  411. exclusion=$(echo "$USER" |tr ',' '\n' |grep "^$udir$")
  412. if [ -z "$exclusion" ]; then
  413. ((i ++))
  414. udir_list="$udir_list $udir"
  415. echo -e "$(date "+%F %T") adding $udir" |tee -a $BACKUP/$user.log
  416. # Backup files and dirs
  417. tar -cpf- $udir |gzip -$BACKUP_GZIP - > $tmpdir/user_dir/$udir.tar.gz
  418. fi
  419. done
  420. set +f
  421. udir_list=$(echo "$udir_list" |sed -e "s/ */\ /g" -e "s/^ //")
  422. # Print total
  423. if [ "$i" -eq 1 ]; then
  424. echo -e "$(date "+%F %T") *** $i user directory ***" |\
  425. tee -a $BACKUP/$user.log
  426. else
  427. echo -e "$(date "+%F %T") *** $i directories ***" |\
  428. tee -a $BACKUP/$user.log
  429. fi
  430. fi
  431. # Get backup size
  432. size="$(du -shm $tmpdir |cut -f 1)"
  433. # Get current time
  434. end_time=$(date '+%s')
  435. time_n_date=$(date +'%T %F')
  436. time=$(echo "$time_n_date" |cut -f 1 -d \ )
  437. date=$(echo "$time_n_date" |cut -f 2 -d \ )
  438. backup_new_date=$(date +"%Y-%m-%d_%H-%M-%S")
  439. # Defining local storage function
  440. local_backup(){
  441. rm -f $BACKUP/$user.$backup_new_date.tar
  442. # Checking retention
  443. backup_list=$(ls -lrt $BACKUP/ |awk '{print $9}' |grep "^$user\." | grep ".tar")
  444. backups_count=$(echo "$backup_list" |wc -l)
  445. if [ "$BACKUPS" -le "$backups_count" ]; then
  446. backups_rm_number=$((backups_count - BACKUPS + 1))
  447. # Removing old backup
  448. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  449. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar$//")
  450. echo -e "$(date "+%F %T") Rotated: $backup_date" |\
  451. tee -a $BACKUP/$user.log
  452. rm -f $BACKUP/$backup
  453. done
  454. fi
  455. # Checking disk space
  456. disk_usage=$(df $BACKUP |tail -n1 |tr ' ' '\n' |grep % |cut -f 1 -d %)
  457. if [ "$disk_usage" -ge "$BACKUP_DISK_LIMIT" ]; then
  458. rm -rf $tmpdir
  459. rm -f $BACKUP/$user.log
  460. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  461. echo "Not enough disk space" |$SENDMAIL -s "$subj" $email $notify
  462. check_result "$E_DISK" "Not enough dsk space"
  463. fi
  464. # Creating final tarball
  465. cd $tmpdir
  466. tar -cf $BACKUP/$user.$backup_new_date.tar .
  467. chmod 640 $BACKUP/$user.$backup_new_date.tar
  468. chown admin:$user $BACKUP/$user.$backup_new_date.tar
  469. localbackup='yes'
  470. echo -e "$(date "+%F %T") Local: $BACKUP/$user.$backup_new_date.tar" |\
  471. tee -a $BACKUP/$user.log
  472. }
  473. # Defining ftp command function
  474. ftpc() {
  475. /usr/bin/ftp -np $HOST $PORT <<EOF
  476. quote USER $USERNAME
  477. quote PASS $PASSWORD
  478. binary
  479. $1
  480. $2
  481. $3
  482. quit
  483. EOF
  484. }
  485. # Defining ftp storage function
  486. ftp_backup() {
  487. # Checking config
  488. if [ ! -e "$HESTIA/conf/ftp.backup.conf" ]; then
  489. error="ftp.backup.conf doesn't exist"
  490. rm -rf $tmpdir
  491. rm -f $BACKUP/$user.log
  492. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  493. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  494. check_result "$E_NOTEXIST" "$error"
  495. fi
  496. # Parse config
  497. source $HESTIA/conf/ftp.backup.conf
  498. # Set default port
  499. if [ -z "$(grep 'PORT=' $HESTIA/conf/ftp.backup.conf)" ]; then
  500. PORT='21'
  501. fi
  502. # Checking variables
  503. if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
  504. error="Can't parse ftp backup configuration"
  505. rm -rf $tmpdir
  506. rm -f $BACKUP/$user.log
  507. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  508. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  509. check_result "$E_PARSING" "$error"
  510. fi
  511. # Debug info
  512. echo -e "$(date "+%F %T") Remote: ftp://$HOST$BPATH/$user.$backup_new_date.tar"
  513. # Checking ftp connection
  514. fconn=$(ftpc)
  515. ferror=$(echo $fconn |grep -i -e failed -e error -e "Can't" -e "not conn")
  516. if [ ! -z "$ferror" ]; then
  517. error="Error: can't login to ftp ftp://$USERNAME@$HOST"
  518. rm -rf $tmpdir
  519. rm -f $BACKUP/$user.log
  520. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  521. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  522. check_result "$E_CONNECT" "$error"
  523. fi
  524. # Check ftp permissions
  525. if [ -z $BPATH ]; then
  526. ftmpdir="vst.bK76A9SUkt"
  527. else
  528. ftpc "mkdir $BPATH" > /dev/null 2>&1
  529. ftmpdir="$BPATH/vst.bK76A9SUkt"
  530. fi
  531. ftpc "mkdir $ftmpdir" "rm $ftmpdir"
  532. ftp_result=$(ftpc "mkdir $ftmpdir" "rm $ftmpdir" |grep -v Trying)
  533. if [ ! -z "$ftp_result" ] ; then
  534. error="Can't create ftp backup folder ftp://$HOST$BPATH"
  535. rm -rf $tmpdir
  536. rm -f $BACKUP/$user.log
  537. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  538. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  539. check_result "$E_FTP" "$error"
  540. fi
  541. # Checking retention
  542. if [ -z $BPATH ]; then
  543. backup_list=$(ftpc "ls" |awk '{print $9}' |grep "^$user\.")
  544. else
  545. backup_list=$(ftpc "cd $BPATH" "ls" |awk '{print $9}' |grep "^$user\.")
  546. fi
  547. backups_count=$(echo "$backup_list" |wc -l)
  548. if [ "$backups_count" -ge "$BACKUPS" ]; then
  549. backups_rm_number=$((backups_count - BACKUPS + 1))
  550. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  551. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar$//")
  552. echo -e "$(date "+%F %T") Rotated ftp backup: $backup_date" |\
  553. tee -a $BACKUP/$user.log
  554. if [ -z $BPATH ]; then
  555. ftpc "delete $backup"
  556. else
  557. ftpc "cd $BPATH" "delete $backup"
  558. fi
  559. done
  560. fi
  561. # Uploading backup archive
  562. if [ "$localbackup" = 'yes' ]; then
  563. cd $BACKUP
  564. if [ -z $BPATH ]; then
  565. ftpc "put $user.$backup_new_date.tar"
  566. else
  567. ftpc "cd $BPATH" "put $user.$backup_new_date.tar"
  568. fi
  569. else
  570. cd $tmpdir
  571. tar -cf $BACKUP/$user.$backup_new_date.tar .
  572. cd $BACKUP/
  573. if [ -z $BPATH ]; then
  574. ftpc "put $user.$backup_new_date.tar"
  575. else
  576. ftpc "cd $BPATH" "put $user.$backup_new_date.tar"
  577. fi
  578. rm -f $user.$backup_new_date.tar
  579. fi
  580. }
  581. # sftp command function
  582. sftpc() {
  583. expect -f "-" <<EOF "$@"
  584. set timeout 60
  585. set count 0
  586. spawn /usr/bin/sftp -o StrictHostKeyChecking=no \
  587. -o Port=$PORT $USERNAME@$HOST
  588. expect {
  589. "password:" {
  590. send "$PASSWORD\r"
  591. exp_continue
  592. }
  593. -re "Couldn't|(.*)disconnect|(.*)stalled|(.*)not found" {
  594. set count \$argc
  595. set output "Disconnected."
  596. set rc $E_FTP
  597. exp_continue
  598. }
  599. -re ".*denied.*(publickey|password)." {
  600. set output "Permission denied, wrong publickey or password."
  601. set rc $E_CONNECT
  602. }
  603. -re "\[0-9]*%" {
  604. exp_continue
  605. }
  606. "sftp>" {
  607. if {\$count < \$argc} {
  608. set arg [lindex \$argv \$count]
  609. send "\$arg\r"
  610. incr count
  611. } else {
  612. send "exit\r"
  613. set output "Disconnected."
  614. if {[info exists rc] != 1} {
  615. set rc $OK
  616. }
  617. }
  618. exp_continue
  619. }
  620. timeout {
  621. set output "Connection timeout."
  622. set rc $E_CONNECT
  623. }
  624. }
  625. if {[info exists output] == 1} {
  626. puts "\$output"
  627. }
  628. exit \$rc
  629. EOF
  630. }
  631. sftp_backup() {
  632. # Checking config
  633. if [ ! -e "$HESTIA/conf/sftp.backup.conf" ]; then
  634. error="Can't open sftp.backup.conf"
  635. rm -rf $tmpdir
  636. rm -f $BACKUP/$user.log
  637. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  638. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  639. check_result "$E_NOTEXIST" "$error"
  640. fi
  641. # Parse config
  642. source $HESTIA/conf/sftp.backup.conf
  643. # Set default port
  644. if [ -z "$(grep 'PORT=' $HESTIA/conf/sftp.backup.conf)" ]; then
  645. PORT='22'
  646. fi
  647. # Checking variables
  648. if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
  649. error="Can't parse sftp backup configuration"
  650. rm -rf $tmpdir
  651. rm -f $BACKUP/$user.log
  652. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  653. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  654. check_result "$E_PARSING" "$error"
  655. fi
  656. # Debug info
  657. echo -e "$(date "+%F %T") Remote: sftp://$HOST/$BPATH/$user.$backup_new_date.tar" |\
  658. tee -a $BACKUP/$user.log
  659. # Checking network connection and write permissions
  660. if [ -z $BPATH ]; then
  661. sftmpdir="vst.bK76A9SUkt"
  662. else
  663. sftmpdir="$BPATH/vst.bK76A9SUkt"
  664. fi
  665. sftpc "mkdir $BPATH" > /dev/null 2>&1
  666. sftpc "mkdir $sftmpdir" "rmdir $sftmpdir" > /dev/null 2>&1
  667. rc=$?
  668. if [[ "$rc" != 0 ]]; then
  669. case $rc in
  670. $E_CONNECT) error="Can't login to sftp host $HOST" ;;
  671. $E_FTP) error="Can't create temp folder on sftp $HOST" ;;
  672. esac
  673. rm -rf $tmpdir
  674. rm -f $BACKUP/$user.log
  675. echo "$error" |$SENDMAIL -s "$subj" $email $notify
  676. sed -i "/ $user /d" $HESTIA/data/queue/backup.pipe
  677. check_result "$rc" "$error"
  678. fi
  679. # Checking retention
  680. if [ -z $BPATH ]; then
  681. backup_list=$(sftpc "ls -l" |awk '{print $9}'|grep "^$user\.")
  682. else
  683. backup_list=$(sftpc "cd $BPATH" "ls -l" |awk '{print $9}'|grep "^$user\.")
  684. fi
  685. backups_count=$(echo "$backup_list" |wc -l)
  686. if [ "$backups_count" -ge "$BACKUPS" ]; then
  687. backups_rm_number=$((backups_count - BACKUPS + 1))
  688. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  689. backup_date=$(echo $backup |sed -e "s/$user.//" -e "s/.tar.*$//")
  690. echo -e "$(date "+%F %T") Rotated sftp backup: $backup_date" |\
  691. tee -a $BACKUP/$user.log
  692. if [ -z $BPATH ]; then
  693. sftpc "rm $backup" > /dev/null 2>&1
  694. else
  695. sftpc "cd $BPATH" "rm $backup" > /dev/null 2>&1
  696. fi
  697. done
  698. fi
  699. # Uploading backup archive
  700. echo "$(date "+%F %T") Uploading $user.$backup_new_date.tar"|tee -a $BACKUP/$user.log
  701. if [ "$localbackup" = 'yes' ]; then
  702. cd $BACKUP
  703. if [ -z $BPATH ]; then
  704. sftpc "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  705. else
  706. sftpc "cd $BPATH" "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  707. fi
  708. else
  709. cd $tmpdir
  710. tar -cf $BACKUP/$user.$backup_new_date.tar .
  711. cd $BACKUP/
  712. if [ -z $BPATH ]; then
  713. sftpc "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  714. else
  715. sftpc "cd $BPATH" "put $user.$backup_new_date.tar" "chmod 0600 $user.$backup_new_date.tar" > /dev/null 2>&1
  716. fi
  717. rm -f $user.$backup_new_date.tar
  718. fi
  719. }
  720. google_backup() {
  721. # Defining google settings
  722. source $HESTIA/conf/google.backup.conf
  723. gsutil="$HESTIA/3rdparty/gsutil/gsutil"
  724. export BOTO_CONFIG="$HESTIA/conf/.google.backup.boto"
  725. # Debug info
  726. echo -e "$(date "+%F %T") Remote: gs://$BUCKET/$BPATH/$user.$backup_new_date.tar"
  727. # Checking retention
  728. backup_list=$(${gsutil} ls gs://$BUCKET/$BPATH/$user.* 2>/dev/null)
  729. backups_count=$(echo "$backup_list" |wc -l)
  730. if [ "$backups_count" -ge "$BACKUPS" ]; then
  731. backups_rm_number=$((backups_count - BACKUPS))
  732. for backup in $(echo "$backup_list" |head -n $backups_rm_number); do
  733. echo -e "$(date "+%F %T") Rotated gcp backup: $backup"
  734. $gsutil rm $backup > /dev/null 2>&1
  735. done
  736. fi
  737. # Uploading backup archive
  738. echo -e "$(date "+%F %T") Uploading $user.$backup_new_date.tar ..."
  739. if [ "$localbackup" = 'yes' ]; then
  740. cd $BACKUP
  741. ${gsutil} cp $user.$backup_new_date.tar gs://$BUCKET/$BPATH/ > /dev/null 2>&1
  742. else
  743. cd $tmpdir
  744. tar -cf $BACKUP/$user.$backup_new_date.tar .
  745. cd $BACKUP/
  746. ${gsutil} cp $user.$backup_new_date.tar gs://$BUCKET/$BPATH/ > /dev/null 2>&1
  747. rc=$?
  748. rm -f $user.$backup_new_date.tar
  749. if [ "$rc" -ne 0 ]; then
  750. check_result "$E_CONNECT" "gsutil failed to upload $user.$backup_new_date.tar"
  751. fi
  752. fi
  753. }
  754. echo -e "\n-- SUMMARY --" |tee -a $BACKUP/$user.log
  755. # Switching on backup system types
  756. for backup_type in $(echo -e "${BACKUP_SYSTEM//,/\\n}"); do
  757. case $backup_type in
  758. local) local_backup ;;
  759. ftp) ftp_backup ;;
  760. sftp) sftp_backup ;;
  761. google) google_backup ;;
  762. esac
  763. done
  764. # Removing tmpdir
  765. rm -rf $tmpdir
  766. # Calculation run time
  767. run_time=$((end_time - start_time))
  768. run_time=$((run_time / 60))
  769. current_time=$(date "+%T")
  770. if [ "$run_time" -lt 1 ]; then
  771. run_time=1
  772. fi
  773. min=minutes
  774. if [ "$run_time" -eq 1 ]; then
  775. min=minute
  776. fi
  777. echo "$(date "+%F %T") Size: $size MB" |tee -a $BACKUP/$user.log
  778. echo "$(date "+%F %T") Runtime: $run_time $min" |tee -a $BACKUP/$user.log
  779. #----------------------------------------------------------#
  780. # Hestia #
  781. #----------------------------------------------------------#
  782. # Removing duplicate
  783. touch $USER_DATA/backup.conf
  784. sed -i "/$user.$backup_new_date.tar/d" $USER_DATA/backup.conf
  785. # Registering new backup
  786. backup_str="BACKUP='$user.$backup_new_date.tar'"
  787. backup_str="$backup_str TYPE='$BACKUP_SYSTEM' SIZE='$size'"
  788. backup_str="$backup_str WEB='${web_list// /,}'"
  789. backup_str="$backup_str DNS='${dns_list// /,}'"
  790. backup_str="$backup_str MAIL='${mail_list// /,}'"
  791. backup_str="$backup_str DB='${db_list// /,}'"
  792. backup_str="$backup_str CRON='$cron_list'"
  793. backup_str="$backup_str UDIR='${udir_list// /,}'"
  794. backup_str="$backup_str RUNTIME='$run_time' TIME='$time' DATE='$date'"
  795. echo "$backup_str" >> $USER_DATA/backup.conf
  796. # Removing old backups
  797. tail -n $BACKUPS $USER_DATA/backup.conf > $USER_DATA/backup.conf_
  798. mv -f $USER_DATA/backup.conf_ $USER_DATA/backup.conf
  799. chmod 660 $USER_DATA/backup.conf
  800. # Deleting task from queue
  801. sed -i "/v-backup-user $user /d" $HESTIA/data/queue/backup.pipe
  802. U_BACKUPS=$(grep BACKUP $USER_DATA/backup.conf |wc -l)
  803. update_user_value "$user" '$U_BACKUPS' "$U_BACKUPS"
  804. # Send notification
  805. if [ -e "$BACKUP/$user.log" ]; then
  806. cd $BACKUP
  807. subj="$user → backup has been completed"
  808. email=$(get_user_value '$CONTACT')
  809. cat $BACKUP/$user.log |$SENDMAIL -s "$subj" $email $notify
  810. rm $BACKUP/$user.log
  811. fi
  812. # Logging
  813. log_event "$OK" "$ARGUMENTS"
  814. exit