v-backup-user 30 KB

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