diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 2f4d7db3a47265fef8a138bc5c5330fd0635199e..41cb03c4fff2238af5c0513de932a351f1dbf7f2 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -16,6 +16,7 @@ firewall=bastille loglevel=2 admin_notify_events=1 backup_dir=/var/backup +backup_tmp=/tmp backup_dir_is_mount=n backup_mode=rootgz backup_time=0:00 diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 70aac48e0787e06835b32a6773012e1cf213ec16..93094629ac934d1259ce78a951cca93b10d3f266 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -183,6 +183,20 @@ $form["tabs"]['server'] = array( 'width' => '40', 'maxlength' => '255' ), + 'backup_tmp' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '/tmp/', + 'validators' => array( 0 => array('type' => 'NOTEMPTY', + 'errmsg' => 'tmpdir_path_error_empty'), + 1 => array ( 'type' => 'REGEX', + 'regex' => '/^\/[a-zA-Z0-9\.\-\_\/]{5,128}$/', + 'errmsg'=> 'tmpdir_path_error_regex'), + ), + 'value' => '', + 'width' => '40', + 'maxlength' => '255' + ), 'backup_dir_is_mount' => array( 'datatype' => 'VARCHAR', 'formtype' => 'CHECKBOX', diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index 2656243d6aa05abfabb2fb47ab88c0ba676a72f2..ee55d43bb8b238fd397fbb5e19aff4797b0b16d3 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -81,6 +81,7 @@ $wb['awstats_data_dir_txt'] = 'AWStats Datenverzeichnis'; $wb['awstats_pl_txt'] = 'AWStats awstats.pl Script'; $wb['awstats_buildstaticpages_pl_txt'] = 'AWStats awstats_buildstaticpages.pl Script'; $wb['backup_dir_txt'] = 'Backupverzeichnis'; +$wb['backup_tmp_txt'] = 'Backup tmp-Dir (zip)'; $wb['named_conf_local_path_txt'] = 'BIND named.conf.local Pfad'; $wb['php_ini_path_cgi_txt'] = 'CGI php.ini Pfad'; $wb['php_ini_path_apache_txt'] = 'Apache php.ini Pfad'; @@ -103,6 +104,8 @@ $wb['nginx_user_txt'] = 'Nginx Benutzer'; $wb['nginx_group_txt'] = 'Nginx Gruppe'; $wb['nginx_cgi_socket_txt'] = 'Nginx CGI Socket'; $wb['backup_dir_error_empty'] = 'Backup Verzeichnis ist leer.'; +$wb['tmpdir_path_error_empty'] = 'Tmp-Dir Pfad ist leer.'; +$wb['tmpdir_path_error_regex'] = 'Invalid Tmp-Dir Pfad.'; $wb['maildir_path_error_empty'] = 'Maildir Pfad ist leer.'; $wb['homedir_path_error_empty'] = 'Homedir Pfad ist leer.'; $wb['mailuser_uid_error_empty'] = 'Mail Benutzer UID ist leer.'; diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index 80849cb5a795f23962d6a1e90849fa656b9c4cd5..7f7e2c8f85e594fd676f5a11cd5215eb9634ef0f 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -90,6 +90,7 @@ $wb["awstats_data_dir_txt"] = 'awstats data folder'; $wb["awstats_pl_txt"] = 'awstats.pl script'; $wb["awstats_buildstaticpages_pl_txt"] = 'awstats_buildstaticpages.pl script'; $wb["backup_dir_txt"] = 'Backup directory'; +$wb["backup_tmp_txt"] = 'Backup tmp directory for zip'; $wb["named_conf_local_path_txt"] = 'BIND named.conf.local path'; $wb["php_ini_path_cgi_txt"] = 'CGI php.ini path'; $wb["php_ini_path_apache_txt"] = 'Apache php.ini path'; @@ -101,6 +102,8 @@ $wb["fastcgi_config_syntax_txt"] = 'FastCGI config syntax'; $wb["backup_mode_txt"] = 'Backup mode'; $wb["backup_mode_userzip"] = 'Backup web files owned by web user as zip'; $wb["backup_mode_rootgz"] = 'Backup all files in web directory as root user'; +$wb['tmpdir_path_error_empty'] = 'tmp-dir Path is empty.'; +$wb['tmpdir_path_error_regex'] = 'Invalid tmp-dir path.'; $wb["backup_time_txt"] = 'Backup time'; $wb["server_type_txt"] = 'Server Type'; $wb["nginx_vhost_conf_dir_txt"] = 'Nginx Vhost config dir'; diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm index 7868e87568d91797de16192f7d2deb16cce45885..e034fa53b9236d00d7970e72dc8bd12e23d7578d 100644 --- a/interface/web/admin/templates/server_config_server_edit.htm +++ b/interface/web/admin/templates/server_config_server_edit.htm @@ -63,6 +63,10 @@ {tmpl_var name='backup_mode'} </select></div> </div> + <div class="form-group"> + <label for="backup_tmp" class="col-sm-3 control-label">{tmpl_var name='backup_tmp_txt'}</label> + <div class="col-sm-9"><input type="text" name="backup_tmp" id="backup_tmp" value="{tmpl_var name='backup_tmp'}" class="form-control" /></div> + </div> <div class="form-group"> <label for="backup_time" class="col-sm-3 control-label">{tmpl_var name='backup_time_txt'}</label> <div class="col-sm-3"><select name="backup_time" id="backup_time" class="form-control"> diff --git a/server/lib/classes/cron.d/500-backup.inc.php b/server/lib/classes/cron.d/500-backup.inc.php index 5dcb2d5fc3973ec07abee3d9ee861808bd8a860e..fa574311164630cc933539b914e6ca71b5b6c6fa 100644 --- a/server/lib/classes/cron.d/500-backup.inc.php +++ b/server/lib/classes/cron.d/500-backup.inc.php @@ -54,6 +54,7 @@ class cronjob_backup extends cronjob { $global_config = $app->getconf->get_global_config('sites'); $backup_dir = trim($server_config['backup_dir']); $backup_mode = $server_config['backup_mode']; + $backup_tmp = trim($server_config['backup_tmp']); if($backup_mode == '') $backup_mode = 'userzip'; $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); @@ -77,6 +78,15 @@ class cronjob_backup extends cronjob { if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $run_backups = false; if($run_backups){ $web_array = array(); + + system('which pigz > /dev/null', $ret); + if($ret === 0) { + $use_pigz = true; + $zip_cmd = 'pigz'; // db-backups + } else { + $use_pigz = false; + $zip_cmd = 'gzip'; // db-backups + } //* backup only active domains $sql = "SELECT * FROM web_domain WHERE server_id = ? AND (type = 'vhost' OR type = 'vhostsubdomain' OR type = 'vhostalias') AND active = 'y'"; @@ -117,12 +127,16 @@ class cronjob_backup extends cronjob { if($backup_mode == 'userzip') { //* Create a .zip backup as web user and include also files owned by apache / nginx user $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.zip'; - exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -group '.escapeshellarg($web_group).' -print 2> /dev/null | zip -b /tmp --exclude=./backup\*'.$backup_excludes.' --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); - if($retval == 0 || $retval == 12) exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -user '.escapeshellarg($http_server_user).' -print 2> /dev/null | zip -b /tmp --exclude=./backup\*'.$backup_excludes.' --update --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); + exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -group '.escapeshellarg($web_group).' -print 2> /dev/null | zip -b '.escapeshellarg($backup_tmp).' --exclude=./backup\*'.$backup_excludes.' --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); + if($retval == 0 || $retval == 12) exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -user '.escapeshellarg($http_server_user).' -print 2> /dev/null | zip -b '.escapeshellarg($backup_tmp).' --exclude=./backup\*'.$backup_excludes.' --update --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@', $tmp_output, $retval); } else { //* Create a tar.gz backup as root user $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.tar.gz'; - exec('tar pczf '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' --exclude=./backup\*'.$backup_excludes.' --directory '.escapeshellarg($web_path).' .', $tmp_output, $retval); + if ($use_pigz) { + exec('tar pcf - --directory '.escapeshellarg($web_path).' . --exclude=./backup\*'.$backup_excludes.' | pigz > '.escapeshellarg($web_backup_dir.'/'.$web_backup_file), $tmp_output, $retval); + } else { + exec('tar pczf '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' --exclude=./backup\*'.$backup_excludes.' --directory '.escapeshellarg($web_path).' .', $tmp_output, $retval); +} } if($retval == 0 || ($backup_mode != 'userzip' && $retval == 1) || ($backup_mode == 'userzip' && $retval == 12)) { // tar can return 1, zip can return 12(due to harmless warings) and still create valid backups if(is_file($web_backup_dir.'/'.$web_backup_file)){ @@ -241,8 +255,8 @@ class cronjob_backup extends cronjob { $command = "mysqldump -h ".escapeshellarg($clientdb_host)." -u ".escapeshellarg($clientdb_user)." -p".escapeshellarg($clientdb_password)." -c --add-drop-table --create-options --quick --max_allowed_packet=512M --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'"; exec($command, $tmp_output, $retval); - //* Compress the backup with gzip - if($retval == 0) exec("gzip -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'", $tmp_output, $retval); + //* Compress the backup with gzip / pigz + if($retval == 0) exec("$zip_cmd -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'", $tmp_output, $retval); if($retval == 0){ if(is_file($db_backup_dir.'/'.$db_backup_file.'.gz')){ diff --git a/server/lib/classes/cron.d/500-backup_mail.inc.php b/server/lib/classes/cron.d/500-backup_mail.inc.php index 5e84fb3417890a18d716d9ef011d1bb5b42d6d44..a6807021df866ab9f7d29986134e4bb3c7a0460f 100644 --- a/server/lib/classes/cron.d/500-backup_mail.inc.php +++ b/server/lib/classes/cron.d/500-backup_mail.inc.php @@ -59,6 +59,7 @@ class cronjob_backup_mail extends cronjob { $backup_mode = $server_config['backup_mode']; if($backup_mode == '') $backup_mode = 'userzip'; + $backup_tmp = trim($server_config['backup_tmp']); if($backup_dir != '') { $run_backups = true; @@ -72,7 +73,12 @@ class cronjob_backup_mail extends cronjob { } else { chmod(escapeshellcmd($backup_dir), $backup_dir_permissions); } - + system('which pigz > /dev/null', $ret); + if($ret === 0) { + $use_pigz = true; + } else { + $use_pigz = false; + } foreach($records as $rec) { //* Do the mailbox backup $email = $rec['email']; @@ -120,11 +126,15 @@ class cronjob_backup_mail extends cronjob { if($backup_mode == 'userzip') { $mail_backup_file.='.zip'; - exec('cd '.$this->tmp_backup_dir.' && zip '.$mail_backup_dir.'/'.$mail_backup_file.' -b /tmp -r backup > /dev/null && rm -rf backup', $tmp_output, $retval); + exec('cd '.$this->tmp_backup_dir.' && zip '.$mail_backup_dir.'/'.$mail_backup_file.' -b '.escapeshellarg($backup_tmp).' -r backup > /dev/null && rm -rf backup', $tmp_output, $retval); } else { $mail_backup_file.='.tar.gz'; - exec(escapeshellcmd('tar pczf '.$mail_backup_dir.'/'.$mail_backup_file.' --directory '.$this->tmp_backup_dir.' backup && rm -rf '.$this->tmp_backup_dir.'/backup'), $tmp_output, $retval); + if ($use_pigz) { + exec('tar pcf - --directory '.escapeshellarg($this->tmp_backup_dir).' backup | pigz > '.$mail_backup_dir.'/'.$mail_backup_file.' && rm -rf '.$this->tmp_backup_dir.'/backup', $tmp_output, $retval); + } else { + exec(escapeshellcmd('tar pczf '.$mail_backup_dir.'/'.$mail_backup_file.' --directory '.$this->tmp_backup_dir.' backup && rm -rf '.$this->tmp_backup_dir.'/backup'), $tmp_output, $retval); + } } if ($retval != 0) { @@ -144,11 +154,15 @@ class cronjob_backup_mail extends cronjob { //* create archives if($backup_mode == 'userzip') { $mail_backup_file.='.zip'; - exec('cd '.$domain_dir.' && zip '.$mail_backup_dir.'/'.$mail_backup_file.' -b /tmp -r '.$source_dir.' > /dev/null', $tmp_output, $retval); + exec('cd '.$domain_dir.' && zip '.$mail_backup_dir.'/'.$mail_backup_file.' -b '.escapeshellarg($backup_tmp).' -r '.$source_dir.' > /dev/null', $tmp_output, $retval); } else { /* Create a tar.gz backup */ $mail_backup_file.='.tar.gz'; - exec(escapeshellcmd('tar pczf '.$mail_backup_dir.'/'.$mail_backup_file.' --directory '.$domain_dir.' '.$source_dir), $tmp_output, $retval); + if ($use_pigz) { + exec('tar pcf - --directory '.escapeshellarg($domain_dir).' '.escapeshellarg($source_dir).' | pigz > '.$mail_backup_dir.'/'.$mail_backup_file, $tmp_output, $retval); + } else { + exec(escapeshellcmd('tar pczf '.$mail_backup_dir.'/'.$mail_backup_file.' --directory '.$domain_dir.' '.$source_dir), $tmp_output, $retval); + } } }