Naposledy aktivní 1697445670 Unlisted

Backup system user (without backups enabled in plan) with all its objects

sahsanu revidoval tento gist 1697445670. Přejít na revizi

Žádné změny

sahsanu revidoval tento gist 1697390153. Přejít na revizi

1 file changed, 0 insertions, 0 deletions

v-backup-user-without-backups přejmenováno na v-backup-user-without-backups.sh

Soubor přejmenován beze změn

sahsanu revidoval tento gist 1697390106. Přejít na revizi

1 file changed, 808 insertions

v-backup-user-without-backups(vytvořil soubor)

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