Serghey Rodin пре 13 година
родитељ
комит
bbba9aeb34

+ 2 - 1
bin/v-add-user-backup

@@ -26,6 +26,7 @@ validate_format 'user'
 is_system_enabled "$BACKUP_SYSTEM"
 is_object_valid 'user' 'USER' "$user"
 is_backup_enabled
+is_backup_scheduled
 
 
 #----------------------------------------------------------#
@@ -33,7 +34,7 @@ is_backup_enabled
 #----------------------------------------------------------#
 
 # Adding backup to pipe
-echo "$user" >> $VESTA/data/queue/backup.pipe
+echo "$BIN/v-backup-user $user yes" >> $VESTA/data/queue/backup.pipe
 
 
 #----------------------------------------------------------#

+ 145 - 65
bin/v-backup-user

@@ -1,6 +1,6 @@
 #!/bin/bash
 # info: backup system user with all its objects
-# options: USER
+# options: USER NOTIFY
 #
 # The call is used for backing up user with all its domains and databases.
 
@@ -11,6 +11,7 @@
 
 # Argument defenition
 user=$1
+notify=${2-no}
 
 # Includes
 source $VESTA/conf/vesta.conf
@@ -18,104 +19,109 @@ source $VESTA/func/main.sh
 source $VESTA/func/domain.sh
 source $VESTA/func/db.sh
 
-subj="Backup for user $user failed"
-email=$(grep CONTACT $VESTA/data/users/admin/user.conf |cut -f 2 -d \')
-
 
 #----------------------------------------------------------#
 #                    Verifications                         #
 #----------------------------------------------------------#
 
-check_args '1' "$#" 'USER'
+check_args '1' "$#" 'USER [NOTIFY]'
 validate_format 'user'
 is_system_enabled "$BACKUP_SYSTEM"
 is_object_valid 'user' 'USER' "$user"
 is_object_unsuspended 'user' 'USER' "$user"
 is_backup_enabled
-la=$(cat /proc/loadavg |cut -f 1 -d ' '|cut -f 1 -d '.')
+
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Get current time
+start_time=$(date '+%s')
+
+# Set notification email and subject
+if [ "$notify" != 'no' ]; then
+    subj="$user → backup failed"
+    email=$(get_user_value '$CONTACT')
+else
+    subj="$user → backup failed"
+    email=$(grep CONTACT $VESTA/data/users/admin/user.conf | cut -f 2 -d \')
+fi
+if [ -e "$VESTA/web/inc/mail-wrapper.php" ]; then
+    mail="$VESTA/web/inc/mail-wrapper.php"
+else
+    mail=$(which mail)
+fi
+
+# Check load average
+la=$(cat /proc/loadavg | cut -f 1 -d ' ' | cut -f 1 -d '.')
 i=0
 while [ "$la" -ge "$BACKUP_LA_LIMIT" ]; do
     echo "$(date "+%F %T") Load Average $la"
     echo
     sleep 60
     if [ "$i" -ge "15" ]; then
-        echo "LoadAverage $i is above threshold" | mail -s "$subj" $email
+        echo "LoadAverage $i is above threshold" | $mail -s "$subj" $email
         echo "Error: LA is too high"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
         log_event "$E_LA" "$EVENT"
         exit $E_LA
     fi
     (( ++i))
 done
 
-
-#----------------------------------------------------------#
-#                       Action                             #
-#----------------------------------------------------------#
-
-# Get current time
-start_time=$(date '+%s')
-
-# Creating temporary random directory
+# Creating temporary directory
 tmpdir=$(mktemp -p $BACKUP -d)
 if [ "$?" -ne 0 ]; then
-    echo "Can't create tmp dir $tmpdir" | mail -s "$subj" $email
+    echo "Can't create tmp dir $tmpdir" | $mail -s "$subj" $email
     echo "Error: can't create tmp dir"
     log_event "$E_NOTEXIST" "$EVENT"
 fi
 
-# Prinitng status
-echo "$(date "+%F %T") System backup for user $user"
-echo "TMPDIR is $tmpdir"
-echo
-
-# Vesta
-echo "-- VESTA --"
-vst='yes'
+# Backingup system configs
+echo -e "-- SYSTEM --"
+msg="-- SYSTEM --"
 mkdir $tmpdir/vesta
 
-# Backingup vesta configs
-echo -e "$(date "+%F %T") user.conf"
-
+echo -e "$(date "+%F %T") $user.conf"
+msg="$msg\n$(date "+%F %T") $user.conf"
 cp -r $USER_DATA/user.conf $tmpdir/vesta/
 
 if [ -e "$USER_DATA/stats.log" ]; then
     echo -e "$(date "+%F %T") stats.log"
+    msg="$msg\n$(date "+%F %T") stats.log"
     cp -r $USER_DATA/stats.log $tmpdir/vesta/
 fi
 
 if [ -e "$USER_DATA/history.log" ]; then
     echo -e "$(date "+%F %T") history.log"
+    msg="$msg\n$(date "+%F %T") history.log"
     cp -r $USER_DATA/history.log $tmpdir/vesta/
 fi
 
 if [ -e "$USER_DATA/backup.excludes" ]; then
     echo -e "$(date "+%F %T") backup.excludes"
+    msg="$msg\n$(date "+%F %T") backup.excludes"
     cp -r $USER_DATA/backup.excludes $tmpdir/vesta/
 fi
 
-echo
-
-# PAM
-echo "-- PAM --"
+# Backup PAM
 mkdir $tmpdir/pam
-echo -e "$(date "+%F %T") passwd / shadow /group"
+echo -e "$(date "+%F %T") pam"
+msg="$msg\n$(date "+%F %T") pam"
 grep "^$user:" /etc/passwd > $tmpdir/pam/passwd
 grep "^$user:" /etc/shadow > $tmpdir/pam/shadow
 grep "^$user:" /etc/group > $tmpdir/pam/group
 echo
+msg="$msg\n"
 
-# Checking excludes
+# Parsing excludes
 OLD_IFS="$IFS"
 IFS=$'\n'
 if [ -e "$USER_DATA/backup.excludes" ]; then
-    echo "-- Excludes --"
-
     for exclude in $(cat $USER_DATA/backup.excludes); do
-        echo -e "$exclude"
-        # Indirect variable references (a bit of black magic)
         eval ${exclude%%=*}=${exclude#*=}
     done
-    echo
 fi
 IFS="$OLD_IFS"
 
@@ -123,6 +129,7 @@ IFS="$OLD_IFS"
 if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB_SYSTEM" != 'no' ] && [ "$WEB" != '*' ]
 then
     echo "-- WEB --"
+    msg="$msg\n-- WEB --"
     mkdir $tmpdir/web/
 
     # Parsing unsuspeneded domains
@@ -135,8 +142,11 @@ then
     done
     web_list=$(echo "$web_list" | sed -e "s/  */\ /g" -e "s/^ //")
 
+    i=0
     for domain in $web_list; do
+        ((i ++))
         echo -e "$(date "+%F %T") $domain"
+        msg="$msg\n$(date "+%F %T") $domain"
         mkdir -p $tmpdir/web/$domain/conf
         mkdir -p $tmpdir/web/$domain/vesta
 
@@ -202,13 +212,22 @@ then
             gzip -$BACKUP_GZIP $tmpdir/web/$domain/domain_data.tar
         fi
     done
+    if [ "$i" -eq 1 ]; then
+        echo -e "$(date "+%F %T") $i domain"
+        msg="$msg\n$(date "+%F %T") $i domain"
+    else
+        echo -e "$(date "+%F %T") $i domains"
+        msg="$msg\n$(date "+%F %T") $i domains"
+    fi
     echo
+    msg="$msg\n"
 fi
 
 # DNS domains
 if [ ! -z "$DNS_SYSTEM" ] && [ "$DNS_SYSTEM" != 'no' ] && [ "$DNS" != '*' ]
 then
     echo "-- DNS --"
+    msg="$msg\n-- DNS --"
     mkdir $tmpdir/dns/
 
     # Parsing unsuspeneded domains
@@ -220,8 +239,12 @@ then
     done
     dns_list=$(echo "$dns_list" | sed -e "s/  */\ /g" -e "s/^ //")
 
+    i=0
     for domain in $dns_list; do
+        ((i ++))
         echo -e "$(date "+%F %T") $domain"
+        msg="$msg\n$(date "+%F %T") $domain"
+
         # Building directory tree
         mkdir -p $tmpdir/dns/$domain/conf
         mkdir -p $tmpdir/dns/$domain/vesta
@@ -235,14 +258,22 @@ then
         cp $USER_DATA/dns/$domain.conf vesta/$domain.conf
         cp $HOMEDIR/$user/conf/dns/$domain.db conf/$domain.db
     done
+    if [ "$i" -eq 1 ]; then
+        echo -e "$(date "+%F %T") $i domain"
+        msg="$msg\n$(date "+%F %T") $i domain"
+    else
+        echo -e "$(date "+%F %T") $i domains"
+        msg="$msg\n$(date "+%F %T") $i domains"
+    fi
     echo
+    msg="$msg\n"
 fi
 
-
 # Mail domains
 if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL_SYSTEM" != 'no' ] && [ "$MAIL" != '*' ]
 then
     echo "-- MAIL --"
+    msg="$msg\n-- MAIL --"
     mkdir $tmpdir/mail/
 
     # Parsing unsuspeneded domains
@@ -255,8 +286,11 @@ then
     done
     mail_list=$(echo "$mail_list" | sed -e "s/  */\ /g" -e "s/^ //")
 
+    i=0
     for domain in $mail_list; do
+        ((i ++))
         echo -e "$(date "+%F %T") $domain"
+        msg="$msg\n$(date "+%F %T") $domain"
         mkdir -p $tmpdir/mail/$domain/conf
         mkdir -p $tmpdir/mail/$domain/vesta
 
@@ -283,13 +317,22 @@ then
             gzip -$BACKUP_GZIP $tmpdir/mail/$domain/accounts.tar
         fi
     done
+    if [ "$i" -eq 1 ]; then
+        echo -e "$(date "+%F %T") $i domain"
+        msg="$msg\n$(date "+%F %T") $i domain"
+    else
+        echo -e "$(date "+%F %T") $i domains"
+        msg="$msg\n$(date "+%F %T") $i domains"
+    fi
     echo
+    msg="$msg\n"
 fi
 
 
 # DatbaBases
 if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ] && [ "$DB" != '*' ]; then
     echo "-- DB --"
+    msg="$msg\n-- DB --"
     mkdir $tmpdir/db/
 
     # Parsing unsuspeneded domains
@@ -301,18 +344,22 @@ if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ] && [ "$DB" != '*' ]; then
     done
     db_list=$(echo "$db_list" | sed -e "s/  */\ /g" -e "s/^ //")
 
+    i=0
     for database in $db_list; do
+        ((i ++))
+        echo -e "$(date "+%F %T") $TYPE $database"
+        msg="$msg\n$(date "+%F %T") $TYPE $database"
+
         mkdir -p $tmpdir/db/$database/conf
         mkdir -p $tmpdir/db/$database/vesta
-        cd $tmpdir/db/$database/
 
         conf="$USER_DATA/db.conf"
+        cd $tmpdir/db/$database/
         grep "DB='$database'" $conf > vesta/db.conf
 
         get_database_values
         dump="$tmpdir/db/$database/$database.$TYPE.sql"
         grants="$tmpdir/db/$database/conf/$database.$TYPE.$DBUSER"
-        echo -e "$(date "+%F %T") $database $TYPE"
         case $TYPE in
             mysql) dump_mysql_database ;;
             pgsql) dump_pgsql_database ;;
@@ -321,25 +368,44 @@ if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'no' ] && [ "$DB" != '*' ]; then
             gzip -$BACKUP_GZIP $dump
         fi
     done
+    if [ "$i" -eq 1 ]; then
+        echo -e "$(date "+%F %T") $i database"
+        msg="$msg\n$(date "+%F %T") $i database"
+    else
+        echo -e "$(date "+%F %T") $i databases"
+        msg="$msg\n$(date "+%F %T") $i databases"
+    fi
     echo
+    msg="$msg\n"
 fi
 
 # Cron jobs
 if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON_SYSTEM" != 'no' ] && [ "$CRON" != '*' ]
 then
     echo "-- CRON --"
+    msg="$msg\n-- CRON --"
     mkdir $tmpdir/cron/
 
     # Backingup cron recods
     echo -e "$(date "+%F %T") cron.conf"
+    msg="$msg\n$(date "+%F %T") cron.conf"
+
     cp $USER_DATA/cron.conf $tmpdir/cron/
-    echo -e "$(date "+%F %T") system cron"
+    cron_record=$(wc -l $USER_DATA/cron.conf|cut -f 1 -d ' ')
 
     if [ -e "/var/spool/cron/$user" ]; then
         cron_list='yes'
         cp /var/spool/cron/$user $tmpdir/cron/
     fi
+    if [ "$cron_record" -eq 1 ]; then
+        echo -e "$(date "+%F %T") $cron_record record"
+        msg="$msg\n$(date "+%F %T") $cron_record record"
+    else
+        echo -e "$(date "+%F %T") $cron_record records"
+    msg="$msg\n$(date "+%F %T") $cron_record records"
+    fi
     echo
+    msg="$msg\n"
 fi
 
 # Get backup size
@@ -353,13 +419,11 @@ TIME=$(date +%T)
 
 # Defining local storage function
 local_backup(){
-    echo "-- STORAGE --"
-    echo -e "$(date "+%F %T") ARCHIVE $BACKUP/$user.$DATE.tar"
-
     # Removing dublicate for this day
     if [ -e "$BACKUP/$user.$DATE.tar" ]; then
         deprecated="$DATE"
-        echo -e "Deleting old backup for $DATE"
+        echo -e "$(date "+%F %T") Deleted old backup: $user.$DATE.tar"
+        msg="$msg\n$(date "+%F %T") Deleted old backup: $user.$DATE.tar"
         rm -f $BACKUP/$user.$DATE.tar
     fi
 
@@ -374,7 +438,8 @@ local_backup(){
             # Removing old backup
             backup_date=$(echo $backup | sed -e "s/$user.//" -e "s/.tar$//")
             deprecated="$deprecated $backup_date"
-            echo -e "\tDeleteing old backup for $backup_date"
+            echo -e "$(date "+%F %T") Deleted old backup: $backup_date"
+            msg="$msg\n$(date "+%F %T") Deleted old backup: $backup_date"
             rm -f $BACKUP/$backup
         done
     fi
@@ -384,8 +449,9 @@ local_backup(){
 
     if [ "$disk_usage" -ge "$BACKUP_DISK_LIMIT" ]; then
         rm -rf $tmpdir
-        echo "Not enough disk space to run backup" | mail -s "$subj" $email
+        echo "Not enough disk space to run backup" | $mail -s "$subj" $email
         echo "Error: Not enough disk space"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
         log_event "$E_DISK" "$EVENT"
         exit $E_DISK
     fi
@@ -396,9 +462,9 @@ local_backup(){
     chmod 640 $BACKUP/$user.$DATE.tar
     chown admin:$user $BACKUP/$user.$DATE.tar
     localbackup='yes'
-    echo
-
-    U_BACKUPS=$(ls $BACKUP/|grep "^$user."|wc -l)
+    echo -e "$(date "+%F %T") Archived: $BACKUP/$user.$DATE.tar"
+    msg="$msg\n$(date "+%F %T") Archived: $BACKUP/$user.$DATE.tar"
+    U_BACKUPS=$(ls $BACKUP/ | grep "^$user." | wc -l)
     update_user_value "$user" '$U_BACKUPS' "$U_BACKUPS"
 }
 
@@ -417,22 +483,21 @@ EOF
 
 # Defining ftp storage function
 ftp_backup(){
-    echo "-- FTP --"
-
     # Checking config
     source $VESTA/conf/ftp.backup.conf
     if [ -z "$HOST" ] || [ -z "$USERNAME" ] || [ -z "$PASSWORD" ] ||\
         [ -z "$BPATH" ]; then
         rm -rf $tmpdir
-        echo "Can't parse ftp backup configuration" | mail -s "$subj" $email
+        echo "Can't parse ftp backup configuration" | $mail -s "$subj" $email
         echo "Error: Parsing error"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
         log_event "$E_PARSING" "$EVENT"
         exit $E_PARSING
     fi
 
     # Debug info
-    echo -ne "$(date "+%F %T") "
-    echo -e "ftp://$USERNAME@$HOST$BPATH/$user.$DATE.tar"
+    echo -e "$(date "+%F %T") FTP ftp://$HOST$BPATH/$user.$DATE.tar"
+    msg="$msg\n$(date "+%F %T") FTP ftp://$HOST$BPATH/$user.$DATE.tar"
 
     # Checking ftp permission
     ftmpdir=$(mktemp -u -p $BPATH)
@@ -441,8 +506,9 @@ ftp_backup(){
              rm $ftmpdir"
     if [ ! -z "$(ftpc "$command")" ] ; then
         rm -rf $tmpdir
-        echo "Can't login to ftp://$USERNAME@$HOST" | mail -s "$subj" $email
+        echo "Can't login to ftp://$USERNAME@$HOST" | $mail -s "$subj" $email
         echo "Error: FTP error"
+        sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
         log_event "$E_FTP" "$EVENT"
         exit $E_FTP
     fi
@@ -455,7 +521,8 @@ ftp_backup(){
         for backup in $(echo "$backup_list" | head -n $backups_rm_number); do 
             backup_date=$(echo $backup | sed -e "s/$user.//" -e "s/.tar$//")
             deprecated="$deprecated $backup"
-            echo -e "\tDeleteing old backup for $backup_date"
+            echo -e "$(date "+%F %T") Deleted old ftp backup: $backup_date"
+            msg="$msg\n$(date "+%F %T") Deleted old ftp backup: $backup_date"
             ftpc "delete $backup"
         done
     fi
@@ -471,9 +538,11 @@ ftp_backup(){
         ftpc "put $user.$DATE.tar"
         rm -f $user.$DATE.tar
     fi
-    echo
 }
 
+echo "-- SUMMARY --"
+msg="$msg\n-- SUMMARY --"
+
 # Switching on backup system types
 for backup_type in $(echo -e "${BACKUP_SYSTEM//,/\n}"); do
     case $backup_type in
@@ -493,14 +562,15 @@ current_time=$(date "+%T")
 if [ "$run_time" -lt 1 ]; then
     run_time=1
 fi
-
 min=miutes
 if [ "$run_time" -eq 1 ]; then
     min=minute
 fi
-echo "$(date "+%F %T") Backup took $run_time $min"
-echo
-echo
+
+echo "$(date "+%F %T") Size: $size Mb"
+msg="$msg\n$(date "+%F %T") Size: $size Mb"
+echo "$(date "+%F %T") RUNTIME: $run_time $min"
+msg="$msg\n$(date "+%F %T") RUNTIME: $run_time $min"
 
 
 #----------------------------------------------------------#
@@ -517,7 +587,7 @@ done
 # Concatenating string
 backup_str="BACKUP='$user.$DATE.tar'"
 backup_str="$backup_str TYPE='$BACKUP_SYSTEM' SIZE='$size'"
-backup_str="$backup_str VESTA='$vst'"
+backup_str="$backup_str VESTA='yes'"
 backup_str="$backup_str WEB='${web_list// /,}'"
 backup_str="$backup_str DNS='${dns_list// /,}'"
 backup_str="$backup_str MAIL='${mail_list// /,}'"
@@ -527,6 +597,16 @@ backup_str="$backup_str RUNTIME='$run_time' TIME='$TIME' DATE='$DATE'"
 echo "$backup_str" >> $USER_DATA/backup.conf
 chmod 660 $USER_DATA/backup.conf
 
+# Clean backup queue
+sed -i "/ $user /d" $VESTA/data/queue/backup.pipe
+
+# Send notification
+if [ "$notify" != 'no' ]; then
+    subj="$user → backup has been completed"
+    email=$(get_user_value '$CONTACT')
+    echo -e "$msg" | $mail -s "$subj" $email
+fi
+
 # Logging
 log_event "$OK" "$EVENT"
 

+ 6 - 1
bin/v-backup-users

@@ -24,8 +24,13 @@ source $VESTA/func/main.sh
 
 for user in $(ls $VESTA/data/users); do
     check_suspend=$(grep "SUSPENDED='no'" $VESTA/data/users/$user/user.conf)
+    log=$VESTA/log/backup.log
     if [ ! -z "$check_suspend" ]; then
-        $BIN/v-backup-user $user >> $VESTA/log/backup.log 2>&1
+        echo -e "================================" >> $log
+        echo -e "$user" >> $log
+        echo -e "--------------------------------\n" >> $log
+        $BIN/v-backup-user $user >> $log 2>&1
+        echo -e "\n--------------------------------\n\n" >> $log
     fi
 done
 

+ 6 - 1
bin/v-update-sys-queue

@@ -32,6 +32,11 @@ PATH=$PATH:$BIN
 #----------------------------------------------------------#
 
 check_args '1' "$#" 'QUEUE'
+b_task=$(ps auxf |grep -v "grep" |grep "$VESTA/bin/v-update-sys-queue backup")
+b_task=$(echo "$b_task" |grep -v sudo |wc -l)
+if [ "$b_task" -gt 2 ]; then
+    exit
+fi
 
 
 #----------------------------------------------------------#
@@ -44,7 +49,7 @@ case $queue in
                 rm $VESTA/data/queue/restart.pipe;
                 touch $VESTA/data/queue/restart.pipe;;
     webstats)   bash $VESTA/data/queue/webstats.pipe > /dev/null 2>&1 ;;
-    backup)     bash $VESTA/data/queue/backup.pipe;;
+    backup)     bash $VESTA/data/queue/backup.pipe > /dev/null 2>&1 ;;
     disk)       bash $VESTA/data/queue/disk.pipe;;
     traffic)    bash $VESTA/data/queue/traffic.pipe;;
     *)          check_args '1' '0' 'QUEUE'

+ 6 - 6
func/db.sh

@@ -331,7 +331,7 @@ dump_mysql_database() {
     eval $host_str
     if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ] || [ -z $PORT ]; then
         rm -rf $tmpdir
-        echo "Can't parse mysql config" | mail -s "$subj" $email
+        echo "Can't parse mysql config" | $mail -s "$subj" $email
         echo "Error: mysql config parsing failed"
         log_event "$E_PARSING" "$EVENT"
         exit $E_PARSING
@@ -341,7 +341,7 @@ dump_mysql_database() {
     mysql -h $HOST -u $USER -p$PASSWORD -P $PORT -e "$query" &> /dev/null
     if [ '0' -ne "$?" ]; then
         rm -rf $tmpdir
-        echo "Can't connect to mysql server $HOST" | mail -s "$subj" $email
+        echo "Can't connect to mysql server $HOST" | $mail -s "$subj" $email
         echo "Error: Connection failed"
         log_event  "$E_DB $EVENT"
         exit $E_DB
@@ -350,7 +350,7 @@ dump_mysql_database() {
     mysqldump -h $HOST -u $USER -p$PASSWORD -P$PORT -r $dump $database
     if [ '0' -ne "$?" ]; then
         rm -rf $tmpdir
-        echo "Can't dump mysql database $database" | mail -s "$subj" $email
+        echo "Can't dump mysql database $database" | $mail -s "$subj" $email
         echo "Error: dump $database failed"
         log_event  "$E_DB $EVENT"
         exit $E_DB
@@ -372,7 +372,7 @@ dump_pgsql_database() {
     export PGPASSWORD="$PASSWORD"
     if [ -z $HOST ] || [ -z $USER ] || [ -z $PASSWORD ] || [ -z $TPL ]; then
         rm -rf $tmpdir
-        echo "Can't parse pgsql config" | mail -s "$subj" $email
+        echo "Can't parse pgsql config" | $mail -s "$subj" $email
         echo "Error: postgresql config parsing failed"
         log_event "$E_PARSING" "$EVENT"
         exit $E_PARSING
@@ -382,7 +382,7 @@ dump_pgsql_database() {
     psql -h $HOST -U $USER -p $PORT -c "$query" &> /dev/null
     if [ '0' -ne "$?" ];  then
         rm -rf $tmpdir
-        echo "Can't connect to pgsql server $HOST" | mail -s "$subj" $email
+        echo "Can't connect to pgsql server $HOST" | $mail -s "$subj" $email
         echo "Error: Connection failed"
         log_event "$E_DB" "$EVENT"
         exit $E_DB
@@ -393,7 +393,7 @@ dump_pgsql_database() {
 
     if [ '0' -ne "$?" ]; then
         rm -rf $tmpdir
-        echo "Can't dump pgsql database $database" | mail -s "$subj" $email
+        echo "Can't dump pgsql database $database" | $mail -s "$subj" $email
         echo "Error: dump $database failed"
         log_event  "$E_DB $EVENT"
         exit $E_DB

+ 12 - 0
func/main.sh

@@ -158,6 +158,18 @@ is_backup_enabled() {
     fi
 }
 
+# Check user backup settings
+is_backup_scheduled() {
+    if [ -e "$VESTA/data/queue/backup.pipe" ]; then
+        check_backup=$(grep " $user " $VESTA/data/queue/backup.pipe)
+        if [ ! -z "$check_backup" ]; then
+            echo "Error: backup is already scheduled"
+            log_event "$E_EXISTS" "$EVENT"
+            exit $E_EXISTS
+        fi
+    fi
+}
+
 # Check if object is free and can be created
 is_object_free() {
     if [ $2 = 'USER' ]; then

+ 1 - 1
install/vst-install.sh

@@ -744,7 +744,7 @@ $VESTA/bin/v-add-cron-job 'admin' '10' '00' '*' '*' '*' "$command"
 command='sudo /usr/local/vesta/bin/v-update-sys-queue webstats'
 $VESTA/bin/v-add-cron-job 'admin' '30' '03' '*' '*' '*' "$command"
 command='sudo /usr/local/vesta/bin/v-update-sys-queue backup'
-$VESTA/bin/v-add-cron-job 'admin' '*/30' '*' '*' '*' '*' "$command"
+$VESTA/bin/v-add-cron-job 'admin' '*/5' '*' '*' '*' '*' "$command"
 command='sudo /usr/local/vesta/bin/v-backup-users'
 $VESTA/bin/v-add-cron-job 'admin' '10' '05' '*' '*' '*' "$command"
 command='sudo /usr/local/vesta/bin/v-update-user-stats'

+ 25 - 0
web/add/backup/index.php

@@ -0,0 +1,25 @@
+<?php
+// Init
+error_reporting(NULL);
+ob_start();
+session_start();
+include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
+
+$v_username = escapeshellarg($user);
+exec (VESTA_CMD."v-add-user-backup ".$v_username, $output, $return_var);
+if ($return_var == 0) {
+    $_SESSION['backup_msg'] = _('BACKUP_SCHEDULED');
+} else {
+    $_SESSION['backup_msg'] = implode('<br>', $output);
+    if (empty($_SESSION['backup_msg'])) {
+        $_SESSION['backup_msg'] = _('Error: vesta did not return any output.');
+    }
+
+    if ($return_var == 4) {
+        $_SESSION['backup_msg'] = _('BACKUP_EXISTS');
+    }
+
+}
+unset($output);
+header("Location: /list/backup/");
+exit;

+ 3 - 0
web/inc/i18n/en.php

@@ -145,6 +145,7 @@ $LANG['en'] = array(
     'SSH Access'  => 'SSH Access',
     'IP Addresses'  => 'IP Addresses',
     'Backups'  => 'Backups',
+    'Backup System'  => 'Backup System',
     'template'  => 'template',
     'SSL Support'  => 'SSL Support',
     'SSL Home Directory'  => 'SSL Home',
@@ -362,6 +363,8 @@ $LANG['en'] = array(
     'Error code:'  => 'Error code: %s',
     'SERVICE_ACTION_FAILED'  => '"%s" "%s" failed',
     'IP address is in use' => 'IP address is in use',
+    'BACKUP_SCHEDULED'  => 'Task has been added to the queue. You will receive an email notification when your backup is ready for download.',
+    'BACKUP_EXISTS'  => 'An existing backup is already running. Please wait for that backup to finish.',
 
     'Welcome to Vesta Control Panel'  => 'Welcome to Vesta Control Panel',
     'MAIL_FROM'  => 'Vesta Control Panel <noreply@%s>',

+ 3 - 0
web/inc/i18n/es.php

@@ -144,6 +144,7 @@ $LANG['es'] = array(
     'SSH Access'  => 'Acceso SSH',
     'IP Addresses'  => 'Dirección IP',
     'Backups'  => 'Respaldos',
+    'Backup System'  => 'Sistema de Respaldo',
     'template'  => 'plantilla',
     'SSL Support'  => 'Soporte SSL',
     'SSL Home Directory'  => 'SSL Home',
@@ -361,6 +362,8 @@ $LANG['es'] = array(
     'Error code:'  => 'Código de Error:',
     'SERVICE_ACTION_FAILED'  => '"%s" "%s" fallo',
     'IP address is in use' => 'La IP esta en uso',
+    'BACKUP_SCHEDULED'  => 'Task has been added to the queue. You will receive an email notification when your backup is ready for download.',
+    'BACKUP_EXISTS'  => 'An existing backup is already running. Please wait for that backup to finish.',
 
     'Welcome to Vesta Control Panel'  => 'Bienvenido al Panel de Control Vesta',
     'MAIL_FROM'  => 'Panel de Control Vesta <noreply@%s>',

+ 3 - 0
web/inc/i18n/ru.php

@@ -146,6 +146,7 @@ $LANG['ru'] = array(
     'SSH Access' => 'Доступ по SSH',
     'IP Addresses' => 'IP адреса',
     'Backups' => 'Резервные копии',
+    'Backup System'  => 'Система резервного копирования',
     'template' => 'шаблон',
     'SSL Support' => 'Поддержка SSL',
     'SSL Home Directory' => 'Директория SSL',
@@ -363,6 +364,8 @@ $LANG['ru'] = array(
     'Error code:' => 'Код ошибки: %s',
     'SERVICE_ACTION_FAILED' => 'Не удалось "%s" "%s"',
     'IP address is in use' => 'IP адрес используется',
+    'BACKUP_SCHEDULED'  => 'Задание успешно добавлено в очередь. После завершения вы получите полный отчет по почте.',
+    'BACKUP_EXISTS'  => 'Резервное копирование уже выполняется, полжалуйста дождитесь окончания.',
 
     'Welcome to Vesta Control Panel' => 'Добро пожаловать в панель управления Vesta',
     'MAIL_FROM' => 'Vesta Control Panel <noreply@%s>',

+ 36 - 0
web/inc/mail-wrapper.php

@@ -0,0 +1,36 @@
+#!/usr/local/vesta/php/bin/php
+<?php
+
+if (empty($argv[1])) {
+    echo "Error: not enough arguments\n";
+    exit(3);
+}
+
+$options = getopt("s:f:");
+
+
+define('NO_AUTH_REQUIRED',true);
+include("/usr/local/vesta/web/inc/main.php");
+
+// Set system language
+exec (VESTA_CMD . "v-list-sys-config json", $output, $return_var);
+$data = json_decode(implode('', $output), true);
+if (!empty( $data['config']['LANGUAGE'])) {
+    $_SESSION['language'] = $data['config']['LANGUAGE'];
+} else {
+    $_SESSION['language'] = 'en';
+}
+require_once('/usr/local/vesta/web/inc/i18n/'.$_SESSION['language'].'.php');
+
+// Define vars
+$from = 'Vesta Control Panel <vesta@'.$_SERVER["HOSTNAME"].'>';
+$to = $argv[3]."\n";
+$subject = $argv[2]."\n";
+$mailtext = file_get_contents("php://stdin");
+
+// Send email
+if ((!empty($to)) && (!empty($subject))) {
+    send_email($to,$subject,$mailtext,$from);
+}
+
+?>

+ 26 - 1
web/templates/admin/list_backup.html

@@ -2,7 +2,7 @@
                                     <tr>
                                         <td style="padding: 2px 0 0 6px">
                                             <div class="submenu-button-block">
-                                                <button class="submenu-button" > <?php print _('Create Backup');?> </button>
+                                                <button class="submenu-button" onclick="location.href='/add/backup/'"> <?php print _('Create Backup');?> </button>
                                             </div>
                                             <div class="submenu-search-block">
                                                 <form action="/search/" method="get">
@@ -19,6 +19,31 @@
                                                 </select>
                                                 <input type="submit" name="ok" value="›" class="submenu-button" style="width: 36px;">
                                             </div>
+                                            <?php
+                                                if (!empty($_SESSION['backup_msg'])) {
+                                            ?>
+                                            <div>
+                                                <script type="text/javascript">
+                                                    $(function() {
+                                                        $( "#dialog:ui-dialog" ).dialog( "destroy" );
+                                                        $( "#dialog-message" ).dialog({
+                                                            modal: true,
+                                                            buttons: {
+                                                                Ok: function() {
+                                                                    $( this ).dialog( "close" );
+                                                                }
+                                                            }
+                                                        });
+                                                    });
+                                                </script>
+                                                <div id="dialog-message" title="<?php print _('Backup System') ?>">
+                                                    <p><?php echo $_SESSION['backup_msg'] ?></p>
+                                                </div>
+                                            </div>
+                                            <?php
+                                                    unset($_SESSION['backup_msg']);
+                                                }
+                                            ?>
                                         </td>
                                     </tr>
                                 </table>