v-backup-user 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  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/func/backup.sh
  19. source $HESTIA/conf/hestia.conf
  20. #----------------------------------------------------------#
  21. # Verifications #
  22. #----------------------------------------------------------#
  23. check_args '1' "$#" 'USER [NOTIFY]'
  24. is_format_valid 'user'
  25. is_system_enabled "$BACKUP_SYSTEM" 'BACKUP_SYSTEM'
  26. is_object_valid 'user' 'USER' "$user"
  27. is_object_unsuspended 'user' 'USER' "$user"
  28. is_backup_enabled
  29. #----------------------------------------------------------#
  30. # Action #
  31. #----------------------------------------------------------#
  32. check_backup_conditions
  33. # Set backup directory if undefined
  34. if [ -z "$BACKUP" ]; then
  35. BACKUP=/backup
  36. fi
  37. mkdir -p $BACKUP
  38. # Get current time
  39. start_time=$(date '+%s')
  40. # Set notification email and subject
  41. subj="$user → backup failed"
  42. email=$(grep CONTACT $HESTIA/data/users/admin/user.conf |cut -f 2 -d \')
  43. # Validate available disk space (take usage * 2, due to the backup handling)
  44. let u_disk=$(grep "U_DISK=" $HESTIA/data/users/$user/user.conf |cut -f 2 -d \')*2
  45. let v_disk=$(($(stat -f --format="%a*%S" $BACKUP)))/1024/1024
  46. if [ "$u_disk" -gt "$v_disk" ]; then
  47. echo "not enough diskspace available to perform the backup." |$SENDMAIL -s "$subj" $email $notify
  48. check_result $E_LIMIT "not enough diskspace available to perform the backup."
  49. fi
  50. if [ -z "$BACKUP_TEMP" ]; then
  51. BACKUP_TEMP=$BACKUP
  52. fi
  53. # Creating temporary directory
  54. tmpdir=$(mktemp -p $BACKUP_TEMP -d)
  55. if [ "$?" -ne 0 ]; then
  56. echo "Can't create tmp dir $tmpdir" |$SENDMAIL -s "$subj" $email $notify
  57. check_result $E_NOTEXIST "can't create tmp dir"
  58. fi
  59. # Backup sys configs
  60. echo "-- SYSTEM --" |tee $BACKUP/$user.log
  61. mkdir $tmpdir/hestia
  62. echo -e "$(date "+%F %T") $user.conf" |tee -a $BACKUP/$user.log
  63. cp -r $USER_DATA/user.conf $tmpdir/hestia/
  64. cp -r $USER_DATA/ssl $tmpdir/hestia/
  65. if [ -e "$USER_DATA/stats.log" ]; then
  66. echo -e "$(date "+%F %T") stats.log" |tee -a $BACKUP/$user.log
  67. cp -r $USER_DATA/stats.log $tmpdir/hestia/
  68. fi
  69. if [ -e "$USER_DATA/history.log" ]; then
  70. echo -e "$(date "+%F %T") history.log" |tee -a $BACKUP/$user.log
  71. cp -r $USER_DATA/history.log $tmpdir/hestia/
  72. fi
  73. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  74. echo -e "$(date "+%F %T") backup-excludes.conf" |tee -a $BACKUP/$user.log
  75. cp -r $USER_DATA/backup-excludes.conf $tmpdir/hestia/
  76. fi
  77. # Backup PAM
  78. mkdir $tmpdir/pam
  79. echo -e "$(date "+%F %T") pam" |tee -a $BACKUP/$user.log
  80. grep "^$user:" /etc/passwd > $tmpdir/pam/passwd
  81. grep "^$user:" /etc/shadow > $tmpdir/pam/shadow
  82. grep "^$user:" /etc/group > $tmpdir/pam/group
  83. echo
  84. # Parsing excludes
  85. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  86. source $USER_DATA/backup-excludes.conf
  87. fi
  88. # WEB domains
  89. if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB" != '*' ]; then
  90. echo -e "\n-- WEB --" |tee -a $BACKUP/$user.log
  91. mkdir $tmpdir/web/
  92. # Parsing domain exclusions
  93. conf="$USER_DATA/web.conf"
  94. for domain in $(search_objects 'web' 'SUSPENDED' "*" 'DOMAIN'); do
  95. exclusion=$(echo -e "$WEB" |tr ',' '\n' |grep "^$domain$")
  96. if [ -z "$exclusion" ]; then
  97. web_list="$web_list $domain"
  98. else
  99. echo "$(date "+%F %T") excluding $domain"|tee -a $BACKUP/$user.log
  100. fi
  101. done
  102. web_list=$(echo "$web_list" |sed -e "s/ */\ /g" -e "s/^ //")
  103. i=0
  104. for domain in $web_list; do
  105. check_backup_conditions
  106. ((i ++))
  107. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  108. mkdir -p $tmpdir/web/$domain/conf
  109. mkdir -p $tmpdir/web/$domain/hestia
  110. # Get domain variables
  111. domain_idn=$domain
  112. format_domain_idn
  113. get_domain_values 'web'
  114. # Backup web.conf
  115. cd $tmpdir/web/$domain/
  116. conf="$USER_DATA/web.conf"
  117. grep "DOMAIN='$domain'" $conf > hestia/web.conf
  118. # Backup vhost config
  119. if [ -e "$HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.conf" ]; then
  120. cp $HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.conf* conf/
  121. elif [ -e "$HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.conf" ]; then
  122. cp $HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.conf* conf/
  123. else
  124. # legacy format: all domain configs in single file
  125. tpl_file="$WEBTPL/$WEB_SYSTEM/$WEB_BACKEND/$TPL.tpl"
  126. conf="$HOMEDIR/$user/conf/web/$WEB_SYSTEM.conf"
  127. get_web_config_lines $tpl_file $conf
  128. sed -n "$top_line,$bottom_line p" $conf > conf/$WEB_SYSTEM.conf
  129. fi
  130. # Backup ssl vhost
  131. if [ "$SSL" = 'yes' ]; then
  132. if [ -e "$HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.ssl.conf" ]; then
  133. cp $HOMEDIR/$user/conf/web/$domain/$WEB_SYSTEM.ssl.conf* conf/
  134. elif [ -e "$HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.ssl.conf" ]; then
  135. cp $HOMEDIR/$user/conf/web/$domain.$WEB_SYSTEM.ssl.conf* conf/
  136. else
  137. # legacy format: all domain configs in single file
  138. tpl_file="$WEBTPL/$WEB_SYSTEM/$WEB_BACKEND/$TPL.stpl"
  139. conf="$HOMEDIR/$user/conf/web/s$WEB_SYSTEM.conf"
  140. get_web_config_lines $tpl_file $conf
  141. sed -n "$top_line,$bottom_line p" $conf > \
  142. conf/s$WEB_SYSTEM.conf
  143. fi
  144. fi
  145. # Backup proxy config
  146. if [ ! -z "$PROXY_SYSTEM" ] && [ ! -z "$PROXY" ]; then
  147. if [ -e "$HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.conf" ]; then
  148. cp $HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.conf* conf/
  149. elif [ -e "$HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.conf" ]; then
  150. cp $HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.conf* conf/
  151. else
  152. # legacy format: all domain configs in single file
  153. tpl_file="$WEBTPL/$PROXY_SYSTEM/$PROXY.tpl"
  154. conf="$HOMEDIR/$user/conf/web/$PROXY_SYSTEM.conf"
  155. get_web_config_lines $tpl_file $conf
  156. sed -n "$top_line,$bottom_line p" $conf > \
  157. conf/$PROXY_SYSTEM.conf
  158. fi
  159. fi
  160. # Backup ssl proxy config
  161. if [ ! -z "$PROXY_SYSTEM" ] && [ ! -z "$PROXY" ] && [ "$SSL" = 'yes' ]; then
  162. if [ -e "$HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.ssl.conf" ]; then
  163. cp $HOMEDIR/$user/conf/web/$domain/$PROXY_SYSTEM.ssl.conf* conf/
  164. elif [ -e "$HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.ssl.conf" ]; then
  165. cp $HOMEDIR/$user/conf/web/$domain.$PROXY_SYSTEM.ssl.conf* conf/
  166. else
  167. # legacy format: all domain configs in single file
  168. tpl_file="$WEBTPL/$PROXY_SYSTEM/$PROXY.stpl"
  169. conf="$HOMEDIR/$user/conf/web/s$PROXY_SYSTEM.conf"
  170. get_web_config_lines $tpl_file $conf
  171. sed -n "$top_line,$bottom_line p" $conf >\
  172. conf/s$PROXY_SYSTEM.conf
  173. fi
  174. fi
  175. domain_conf=$(grep "DOMAIN='$domain'" $conf)
  176. parse_object_kv_list_non_eval domain_conf
  177. mkdir template/
  178. mkdir template/$WEB_SYSTEM/
  179. mkdir template/php-fpm/
  180. if [ $WEB_BACKEND == 'php-fpm' ]; then
  181. cp $HESTIA/data/templates/web/$WEB_SYSTEM/php-fpm/$TPL.tpl template/$WEB_SYSTEM/
  182. cp $HESTIA/data/templates/web/$WEB_SYSTEM/php-fpm/$TPL.stpl template/$WEB_SYSTEM/
  183. cp $HESTIA/data/templates/web/php-fpm/$BACKEND.tpl template/php-fpm/
  184. else
  185. cp $HESTIA/data/templates/web/$WEB_SYSTEM/$TPL.tpl template/$WEB_SYSTEM/
  186. cp $HESTIA/data/templates/web/$WEB_SYSTEM/$TPL.stpl template/$WEB_SYSTEM/
  187. fi
  188. if [ ! -z "$PROXY_SYSTEM" ] && [ ! -z "$PROXY" ]; then
  189. mkdir template/$PROXY_SYSTEM
  190. cp $HESTIA/data/templates/web/$PROXY_SYSTEM/$PROXY.tpl template/$PROXY_SYSTEM/
  191. cp $HESTIA/data/templates/web/$PROXY_SYSTEM/$PROXY.stpl. template/$PROXY_SYSTEM/
  192. fi
  193. # Backup custom config / backup LE config
  194. for sconfig in $(ls $HOMEDIR/$user/conf/web/|grep ".$domain.conf"); do
  195. cp $HOMEDIR/$user/conf/web/$sconfig conf/
  196. done
  197. # Backup ssl certificates
  198. if [ "$SSL" = 'yes' ] ; then
  199. cp $HOMEDIR/$user/conf/web/$domain/ssl/$domain.* conf/
  200. cp $USER_DATA/ssl/$domain.* hestia/
  201. fi
  202. # Changin dir to documentroot
  203. cd $HOMEDIR/$user/web/$domain
  204. # Define exclude arguments
  205. exlusion=$(echo -e "$WEB" |tr ',' '\n' |grep "^$domain:")
  206. set -f
  207. fargs=()
  208. fargs+=(--exclude='./logs/*')
  209. if [ ! -z "$exlusion" ]; then
  210. xdirs="$(echo -e "$exlusion" |tr ':' '\n' |grep -v $domain)"
  211. for xpath in $xdirs; do
  212. if [ -d "$xpath" ]; then
  213. fargs+=(--exclude=$xpath/*)
  214. echo "$(date "+%F %T") excluding directory $xpath"
  215. msg="$msg\n$(date "+%F %T") excluding directory $xpath"
  216. else
  217. echo "$(date "+%F %T") excluding file $xpath"
  218. msg="$msg\n$(date "+%F %T") excluding file $xpath"
  219. fargs+=(--exclude=$xpath)
  220. fi
  221. done
  222. fi
  223. set +f
  224. # Backup files
  225. if [ "$BACKUP_MODE" = 'zstd' ]; then
  226. tar ${fargs[@]} -cpf- * | zstd -$BACKUP_GZIP - > $tmpdir/web/$domain/domain_data.tar.zst
  227. else
  228. tar ${fargs[@]} -cpf- * | gzip -$BACKUP_GZIP - > $tmpdir/web/$domain/domain_data.tar.gz
  229. fi
  230. done
  231. # Print total
  232. if [ "$i" -eq 1 ]; then
  233. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  234. else
  235. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  236. fi
  237. fi
  238. # DNS domains
  239. if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS" != '*' ]; then
  240. echo -e "\n-- DNS --" |tee -a $BACKUP/$user.log
  241. mkdir $tmpdir/dns/
  242. # Parsing domain exclusions
  243. for domain in $(search_objects 'dns' 'SUSPENDED' "*" 'DOMAIN'); do
  244. exclusion=$(echo "$DNS" |tr ',' '\n' |grep "^$domain$")
  245. if [ -z "$exclusion" ]; then
  246. dns_list="$dns_list $domain"
  247. else
  248. echo "$(date "+%F %T") excluding $domain"
  249. msg="$msg\n$(date "+%F %T") excluding $domain"
  250. fi
  251. done
  252. dns_list=$(echo "$dns_list" |sed -e "s/ */\ /g" -e "s/^ //")
  253. i=0
  254. for domain in $dns_list; do
  255. ((i ++))
  256. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  257. # Building directory tree
  258. mkdir -p $tmpdir/dns/$domain/conf
  259. mkdir -p $tmpdir/dns/$domain/hestia
  260. # Backup dns.conf
  261. cd $tmpdir/dns/$domain/
  262. conf="$USER_DATA/dns.conf"
  263. grep "DOMAIN='$domain'" $conf > hestia/dns.conf
  264. # Backup dns recods
  265. cp $USER_DATA/dns/$domain.conf hestia/$domain.conf
  266. if [ "$DNS_SYSTEM" != 'remote' ]; then
  267. cp $HOMEDIR/$user/conf/dns/$domain.db conf/$domain.db
  268. fi
  269. done
  270. # Print total
  271. if [ "$i" -eq 1 ]; then
  272. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  273. else
  274. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  275. fi
  276. fi
  277. # Mail domains
  278. if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL" != '*' ]; then
  279. echo -e "\n-- MAIL --" |tee -a $BACKUP/$user.log
  280. mkdir $tmpdir/mail/
  281. # Parsing domain exclusions
  282. conf="$USER_DATA/mail.conf"
  283. for domain in $(search_objects 'mail' 'SUSPENDED' "*" 'DOMAIN'); do
  284. check_exl=$(echo "$MAIL" |tr ',' '\n' |grep "^$domain$")
  285. if [ -z "$check_exl" ]; then
  286. mail_list="$mail_list $domain"
  287. else
  288. echo "$(date "+%F %T") excluding $domain"|tee -a $BACKUP/$user.log
  289. fi
  290. done
  291. mail_list=$(echo "$mail_list" |sed -e "s/ */\ /g" -e "s/^ //")
  292. i=0
  293. for domain in $mail_list; do
  294. check_backup_conditions
  295. ((i ++))
  296. echo -e "$(date "+%F %T") $domain" |tee -a $BACKUP/$user.log
  297. mkdir -p $tmpdir/mail/$domain/conf
  298. mkdir -p $tmpdir/mail/$domain/hestia
  299. domain_idn=$domain
  300. format_domain_idn
  301. # Backup exim config
  302. if [[ "$MAIL_SYSTEM" =~ exim ]]; then
  303. cd $tmpdir/mail/$domain/
  304. cp -r $HOMEDIR/$user/conf/mail/$domain/* conf/
  305. fi
  306. # Backup mail.conf
  307. conf="$USER_DATA/mail.conf"
  308. grep "DOMAIN='$domain'" $conf > hestia/mail.conf
  309. cp $USER_DATA/mail/$domain.* hestia/
  310. if [ ! -z "$(ls $USER_DATA/mail/|grep *@$domain)" ]; then
  311. cp $USER_DATA/mail/*@$domain.* hestia/
  312. fi
  313. # Backup emails
  314. cd $HOMEDIR/$user/mail/$domain_idn
  315. accounts=()
  316. for account in $(ls); do
  317. exclusion=$(echo "$MAIL" |tr ',' '\n' |grep "$domain:")
  318. exclusion=$(echo "$exclusion" |tr ':' '\n' |grep "^$account$")
  319. # Checking exlusions
  320. if [ -z "$exclusion" ] && [[ "$MAIL_SYSTEM" =~ exim ]]; then
  321. accounts+=($account)
  322. else
  323. echo "$(date "+%F %T") excluding mail account $account" |\
  324. tee -a $BACKUP/$user.log
  325. fi
  326. done
  327. # Compress archive
  328. if [ ${#accounts[@]} -gt 0 ]; then
  329. if [ "$BACKUP_MODE" = 'zstd' ]; then
  330. tar -cpf- ${accounts[@]} | zstd -$BACKUP_GZIP - > $tmpdir/mail/$domain/accounts.tar.zst
  331. else
  332. tar -cpf- ${accounts[@]} | gzip -$BACKUP_GZIP - > $tmpdir/mail/$domain/accounts.tar.gz
  333. fi
  334. fi
  335. done
  336. # Print total
  337. if [ "$i" -eq 1 ]; then
  338. echo -e "$(date "+%F %T") *** $i domain ***" |tee -a $BACKUP/$user.log
  339. else
  340. echo -e "$(date "+%F %T") *** $i domains ***"|tee -a $BACKUP/$user.log
  341. fi
  342. fi
  343. # Databases
  344. if [ ! -z "$DB_SYSTEM" ] && [ "$DB" != '*' ]; then
  345. echo -e "\n-- DB --" |tee -a $BACKUP/$user.log
  346. mkdir $tmpdir/db/
  347. # Parsing database exclusions
  348. for database in $(search_objects 'db' 'SUSPENDED' "*" 'DB'); do
  349. exclusion=$(echo "$DB" |tr ',' '\n' |grep "^$database$")
  350. if [ -z "$exclusion" ]; then
  351. db_list="$db_list $database"
  352. else
  353. echo "$(date "+%F %T") excluding $database" |\
  354. tee -a $BACKUP/$user.log
  355. fi
  356. done
  357. i=0
  358. conf="$USER_DATA/db.conf"
  359. db_list=$(echo "$db_list" |sed -e "s/ */\ /g" -e "s/^ //")
  360. for database in $db_list; do
  361. check_backup_conditions
  362. ((i ++))
  363. get_database_values
  364. echo -e "$(date "+%F %T") $database ($TYPE)" |tee -a $BACKUP/$user.log
  365. mkdir -p $tmpdir/db/$database/conf
  366. mkdir -p $tmpdir/db/$database/hestia
  367. cd $tmpdir/db/$database/
  368. grep "DB='$database'" $conf > hestia/db.conf
  369. dump="$tmpdir/db/$database/$database.$TYPE.sql"
  370. if [ "$BACKUP_MODE" = 'zstd' ]; then
  371. dumpgz="$tmpdir/db/$database/$database.$TYPE.sql.zst"
  372. else
  373. dumpgz="$tmpdir/db/$database/$database.$TYPE.sql.gz"
  374. fi
  375. grants="$tmpdir/db/$database/conf/$database.$TYPE.$DBUSER"
  376. if [ ! -f "$dumpgz" ]; then
  377. WAIT_LOOP_ENTERED=0
  378. while true
  379. do
  380. if pgrep -x "mysqldump" > /dev/null
  381. then
  382. WAIT_LOOP_ENTERED=1
  383. echo "Wait other mysqldump to finish"
  384. sleep 1
  385. else
  386. if [ "$WAIT_LOOP_ENTERED" -eq 1 ]; then
  387. echo "We can use mysqldump now"
  388. fi
  389. break
  390. fi
  391. done
  392. case $TYPE in
  393. mysql) dump_mysql_database ;;
  394. pgsql) dump_pgsql_database ;;
  395. esac
  396. # Compress dump
  397. if [ "$BACKUP_MODE" = 'zstd' ]; then
  398. zstd -$BACKUP_GZIP $dump
  399. rm $dump;
  400. else
  401. gzip -$BACKUP_GZIP $dump
  402. fi
  403. fi
  404. done
  405. # Print total
  406. if [ "$i" -eq 1 ]; then
  407. echo -e "$(date "+%F %T") *** $i database ***" |\
  408. tee -a $BACKUP/$user.log
  409. else
  410. echo -e "$(date "+%F %T") *** $i databases ***"|\
  411. tee -a $BACKUP/$user.log
  412. fi
  413. fi
  414. # Cron jobs
  415. if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON" != '*' ]; then
  416. echo -e "\n-- CRON --" |tee -a $BACKUP/$user.log
  417. mkdir $tmpdir/cron/
  418. # Backup cron.conf
  419. cp $USER_DATA/cron.conf $tmpdir/cron/
  420. cron_record=$(wc -l $USER_DATA/cron.conf|cut -f 1 -d ' ')
  421. if [ -e "/var/spool/cron/$user" ]; then
  422. cron_list="$cron_record"
  423. cp /var/spool/cron/$user $tmpdir/cron/
  424. fi
  425. # Print total
  426. if [ "$cron_record" -eq 1 ]; then
  427. echo -e "$(date "+%F %T") *** $cron_record job ***" |\
  428. tee -a $BACKUP/$user.log
  429. else
  430. echo -e "$(date "+%F %T") *** $cron_record jobs ***" |\
  431. tee -a $BACKUP/$user.log
  432. fi
  433. fi
  434. # User Directories
  435. if [ "$USER" != '*' ]; then
  436. echo -e "\n-- User Dir --" |tee -a $BACKUP/$user.log
  437. mkdir $tmpdir/user_dir
  438. cd $HOMEDIR/$user
  439. # Parsing directory exlusions
  440. USER=''
  441. if [ -e "$USER_DATA/backup-excludes.conf" ]; then
  442. source $USER_DATA/backup-excludes.conf
  443. fi
  444. fargs=()
  445. for xpath in $(echo "$USER" |tr ',' '\n'); do
  446. if [ -d "$xpath" ]; then
  447. fargs+=(--exclude=$xpath/*)
  448. echo "$(date "+%F %T") excluding directory $xpath" |\
  449. tee -a $BACKUP/$user.log
  450. else
  451. echo "$(date "+%F %T") excluding file $xpath" |\
  452. tee -a $BACKUP/$user.log
  453. fargs+=(--exclude=$xpath)
  454. fi
  455. done
  456. IFS=$'\n'
  457. set -f
  458. i=0
  459. for udir in $(ls -a |egrep -v "^conf$|^web$|^dns$|^tmp$|^mail$|^\.\.$|^\.$"); do
  460. exclusion=$(echo "$USER" |tr ',' '\n' |grep "^$udir$")
  461. if [ -z "$exclusion" ]; then
  462. ((i ++))
  463. udir_list="$udir_list $udir"
  464. echo -e "$(date "+%F %T") adding $udir" |tee -a $BACKUP/$user.log
  465. check_backup_conditions
  466. # Backup files and dirs
  467. if [ "$BACKUP_MODE" = 'zstd' ]; then
  468. tar --anchored -cpf- ${fargs[@]} $udir | zstd -$BACKUP_GZIP - > $tmpdir/user_dir/$udir.tar.zst
  469. else
  470. tar --anchored -cpf- ${fargs[@]} $udir | gzip -$BACKUP_GZIP - > $tmpdir/user_dir/$udir.tar.gz
  471. fi
  472. fi
  473. done
  474. set +f
  475. udir_list=$(echo "$udir_list" |sed -e "s/ */\ /g" -e "s/^ //")
  476. # Print total
  477. if [ "$i" -eq 1 ]; then
  478. echo -e "$(date "+%F %T") *** $i user directory ***" |\
  479. tee -a $BACKUP/$user.log
  480. else
  481. echo -e "$(date "+%F %T") *** $i directories ***" |\
  482. tee -a $BACKUP/$user.log
  483. fi
  484. fi
  485. if [ "$BACKUP_MODE" = 'zstd' ]; then
  486. touch $tmpdir/.zstd
  487. fi
  488. # Get backup size
  489. size="$(du -shm $tmpdir |cut -f 1)"
  490. # Get current time
  491. end_time=$(date '+%s')
  492. time_n_date=$(date +'%T %F')
  493. time=$(echo "$time_n_date" |cut -f 1 -d \ )
  494. date=$(echo "$time_n_date" |cut -f 2 -d \ )
  495. backup_new_date=$(date +"%Y-%m-%d_%H-%M-%S")
  496. echo -e "\n-- SUMMARY --" |tee -a $BACKUP/$user.log
  497. # Switching on backup system types
  498. for backup_type in $(echo -e "${BACKUP_SYSTEM//,/\\n}"); do
  499. case $backup_type in
  500. local) local_backup ;;
  501. ftp) ftp_backup ;;
  502. sftp) sftp_backup ;;
  503. google) google_backup ;;
  504. esac
  505. done
  506. # Removing tmpdir
  507. rm -rf $tmpdir
  508. # Calculation run time
  509. run_time=$((end_time - start_time))
  510. run_time=$((run_time / 60))
  511. current_time=$(date "+%T")
  512. if [ "$run_time" -lt 1 ]; then
  513. run_time=1
  514. fi
  515. min=minutes
  516. if [ "$run_time" -eq 1 ]; then
  517. min=minute
  518. fi
  519. echo "$(date "+%F %T") Size: $size MB" |tee -a $BACKUP/$user.log
  520. echo "$(date "+%F %T") Runtime: $run_time $min" |tee -a $BACKUP/$user.log
  521. #----------------------------------------------------------#
  522. # Hestia #
  523. #----------------------------------------------------------#
  524. # Removing duplicate
  525. touch $USER_DATA/backup.conf
  526. sed -i "/$user.$backup_new_date.tar/d" $USER_DATA/backup.conf
  527. # Registering new backup
  528. backup_str="BACKUP='$user.$backup_new_date.tar'"
  529. backup_str="$backup_str TYPE='$BACKUP_SYSTEM' SIZE='$size'"
  530. backup_str="$backup_str WEB='${web_list// /,}'"
  531. backup_str="$backup_str DNS='${dns_list// /,}'"
  532. backup_str="$backup_str MAIL='${mail_list// /,}'"
  533. backup_str="$backup_str DB='${db_list// /,}'"
  534. backup_str="$backup_str CRON='$cron_list'"
  535. backup_str="$backup_str UDIR='${udir_list// /,}'"
  536. backup_str="$backup_str RUNTIME='$run_time' TIME='$time' DATE='$date'"
  537. echo "$backup_str" >> $USER_DATA/backup.conf
  538. # Removing old backups
  539. tail -n $BACKUPS $USER_DATA/backup.conf > $USER_DATA/backup.conf_
  540. mv -f $USER_DATA/backup.conf_ $USER_DATA/backup.conf
  541. chmod 660 $USER_DATA/backup.conf
  542. # Deleting task from queue
  543. sed -i "/v-backup-user $user /d" $HESTIA/data/queue/backup.pipe
  544. U_BACKUPS=$(grep BACKUP $USER_DATA/backup.conf |wc -l)
  545. update_user_value "$user" '$U_BACKUPS' "$U_BACKUPS"
  546. # Send notification
  547. if [ -e "$BACKUP/$user.log" ] && [ "$notify" = "yes" ]; then
  548. cd $BACKUP
  549. subj="$user → backup has been completed"
  550. email=$(get_user_value '$CONTACT')
  551. cat $BACKUP/$user.log |$SENDMAIL -s "$subj" $email $notify
  552. rm $BACKUP/$user.log
  553. $BIN/v-add-user-notification "$user" "Backup created successfully" "<b>Archive:</b> $user.$backup_new_date.tar"
  554. fi
  555. # Logging
  556. log_event "$OK" "$ARGUMENTS"
  557. exit