big renaming of CustomerBackup to DataDump / export for the real backup-feature to shine :P
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -41,22 +41,22 @@ use PDO;
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
class DataDump extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
|
||||
/**
|
||||
* add a new customer backup job
|
||||
* add a new data dump job
|
||||
*
|
||||
* @param string $path
|
||||
* path to store the backup to
|
||||
* path to store the dumped data to
|
||||
* @param string $pgp_public_key
|
||||
* optional pgp public key to encrypt the backup, default is empty
|
||||
* @param bool $backup_dbs
|
||||
* optional whether to backup databases, default is 0 (false)
|
||||
* @param bool $backup_mail
|
||||
* optional whether to backup mail-data, default is 0 (false)
|
||||
* @param bool $backup_web
|
||||
* optional whether to backup web-data, default is 0 (false)
|
||||
* optional pgp public key to encrypt the archive, default is empty
|
||||
* @param bool $dump_dbs
|
||||
* optional whether to include databases, default is 0 (false)
|
||||
* @param bool $dump_mail
|
||||
* optional whether to include mail-data, default is 0 (false)
|
||||
* @param bool $dump_web
|
||||
* optional whether to incoude web-data, default is 0 (false)
|
||||
* @param int $customerid
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
@@ -75,9 +75,9 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
|
||||
// parameter
|
||||
$pgp_public_key = $this->getParam('pgp_public_key', true, '');
|
||||
$backup_dbs = $this->getBoolParam('backup_dbs', true, 0);
|
||||
$backup_mail = $this->getBoolParam('backup_mail', true, 0);
|
||||
$backup_web = $this->getBoolParam('backup_web', true, 0);
|
||||
$dump_dbs = $this->getBoolParam('dump_dbs', true, 0);
|
||||
$dump_mail = $this->getBoolParam('dump_mail', true, 0);
|
||||
$dump_web = $this->getBoolParam('dump_web', true, 0);
|
||||
|
||||
// get customer data
|
||||
$customer = $this->getCustomerData();
|
||||
@@ -89,7 +89,7 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
|
||||
// path cannot be the customers docroot
|
||||
if ($path == FileDir::makeCorrectDir($customer['documentroot'])) {
|
||||
Response::standardError('backupfoldercannotbedocroot', '', true);
|
||||
Response::standardError('dumpfoldercannotbedocroot', '', true);
|
||||
}
|
||||
|
||||
// pgp public key validation
|
||||
@@ -105,16 +105,16 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
}
|
||||
}
|
||||
|
||||
if ($backup_dbs != '1') {
|
||||
$backup_dbs = '0';
|
||||
if ($dump_dbs != '1') {
|
||||
$dump_dbs = '0';
|
||||
}
|
||||
|
||||
if ($backup_mail != '1') {
|
||||
$backup_mail = '0';
|
||||
if ($dump_mail != '1') {
|
||||
$dump_mail = '0';
|
||||
}
|
||||
|
||||
if ($backup_web != '1') {
|
||||
$backup_web = '0';
|
||||
if ($dump_web != '1') {
|
||||
$dump_web = '0';
|
||||
}
|
||||
|
||||
$task_data = [
|
||||
@@ -124,62 +124,62 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
'loginname' => $customer['loginname'],
|
||||
'destdir' => $path,
|
||||
'pgp_public_key' => $pgp_public_key,
|
||||
'backup_dbs' => $backup_dbs,
|
||||
'backup_mail' => $backup_mail,
|
||||
'backup_web' => $backup_web
|
||||
'dump_dbs' => $dump_dbs,
|
||||
'dump_mail' => $dump_mail,
|
||||
'dump_web' => $dump_web
|
||||
];
|
||||
|
||||
// schedule backup job
|
||||
Cronjob::inserttask(TaskId::CREATE_CUSTOMER_BACKUP, $task_data);
|
||||
// schedule export job
|
||||
Cronjob::inserttask(TaskId::CREATE_CUSTOMER_DATADUMP, $task_data);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer data-dump job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
|
||||
return $this->response($task_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether backup is enabled systemwide and if accessible for customer (hide_options)
|
||||
* check whether data dump is enabled systemwide and if accessible for customer (hide_options)
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private function validateAccess()
|
||||
{
|
||||
if (Settings::Get('system.backupenabled') != 1) {
|
||||
if (Settings::Get('system.exportenabled') != 1) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.backup')) {
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'extras.export')) {
|
||||
throw new Exception("You cannot access this resource", 405);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot get a planned backup.
|
||||
* Try CustomerBackups.listing()
|
||||
* You cannot get a planned data export.
|
||||
* Try DataDump.listing()
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
throw new Exception('You cannot get a planned backup. Try CustomerBackups.listing()', 303);
|
||||
throw new Exception('You cannot get a planned data export. Try DataDump.listing()', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* You cannot update a planned backup.
|
||||
* You cannot update a planned data export.
|
||||
* You need to delete it and re-add it.
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
throw new Exception('You cannot update a planned backup. You need to delete it and re-add it.', 303);
|
||||
throw new Exception('You cannot update a planned data export. You need to delete it and re-add it.', 303);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all planned backup-jobs, if called from an admin, list all planned backup-jobs of all customers you are
|
||||
* list all planned data export jobs, if called from an admin, list all planned data export jobs of all customers you are
|
||||
* allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select backup-jobs of a specific customer by id
|
||||
* optional, admin-only, select data export jobs of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select backup-jobs of a specific customer by loginname
|
||||
* optional, admin-only, select data export jobs of a specific customer by loginname
|
||||
* @param array $sql_search
|
||||
* optional array with index = fieldname, and value = array with 'op' => operator (one of <, > or =),
|
||||
* LIKE is used if left empty and 'value' => searchvalue
|
||||
@@ -199,9 +199,9 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
$this->validateAccess();
|
||||
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.export');
|
||||
|
||||
// check whether there is a backup-job for this customer
|
||||
// check whether there is a data export job for this customer
|
||||
$query_fields = [];
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'" . $this->getSearchWhere($query_fields, true) . $this->getOrderBy() . $this->getLimit());
|
||||
Database::pexecute($sel_stmt, $query_fields, true, true);
|
||||
@@ -212,7 +212,7 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
$result[] = $entry;
|
||||
}
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] list customer-backups");
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_INFO, "[API] list customer data dump jobs");
|
||||
return $this->response([
|
||||
'count' => count($result),
|
||||
'list' => $result
|
||||
@@ -220,12 +220,12 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of planned backups
|
||||
* returns the total number of planned data exports
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select backup-jobs of a specific customer by id
|
||||
* optional, admin-only, select data export jobs of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select backup-jobs of a specific customer by loginname
|
||||
* optional, admin-only, select data export jobs of a specific customer by loginname
|
||||
*
|
||||
* @access admin, customer
|
||||
* @return string json-encoded response message
|
||||
@@ -235,9 +235,9 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
{
|
||||
$this->validateAccess();
|
||||
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.export');
|
||||
|
||||
// check whether there is a backup-job for this customer
|
||||
// check whether there is a data export job for this customer
|
||||
$result_count = 0;
|
||||
$sel_stmt = Database::prepare("SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20'");
|
||||
Database::pexecute($sel_stmt, null, true, true);
|
||||
@@ -251,10 +251,10 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
}
|
||||
|
||||
/**
|
||||
* delete a planned backup-jobs by id, if called from an admin you need to specify the customerid/loginname
|
||||
* delete a planned data export jobs by id, if called from an admin you need to specify the customerid/loginname
|
||||
*
|
||||
* @param int $backup_job_entry
|
||||
* id of backup job
|
||||
* @param int $job_entry
|
||||
* id of data export job
|
||||
* @param int $customerid
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
@@ -266,26 +266,26 @@ class CustomerBackups extends ApiCommand implements ResourceEntity
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
// get planned backups
|
||||
$result = $this->apiCall('CustomerBackups.listing', $this->getParamList());
|
||||
// get planned exports
|
||||
$result = $this->apiCall('DataDump.listing', $this->getParamList());
|
||||
|
||||
$entry = $this->getParam('backup_job_entry');
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.backup');
|
||||
$entry = $this->getParam('job_entry');
|
||||
$customer_ids = $this->getAllowedCustomerIds('extras.export');
|
||||
|
||||
if ($result['count'] > 0 && $entry > 0) {
|
||||
// prepare statement
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_TASKS . "` WHERE `id` = :tid");
|
||||
// check for the correct job
|
||||
foreach ($result['list'] as $backupjob) {
|
||||
if ($backupjob['id'] == $entry && in_array($backupjob['data']['customerid'], $customer_ids)) {
|
||||
foreach ($result['list'] as $exportjob) {
|
||||
if ($exportjob['id'] == $entry && in_array($exportjob['data']['customerid'], $customer_ids)) {
|
||||
Database::pexecute($del_stmt, [
|
||||
'tid' => $entry
|
||||
], true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
|
||||
$this->logger()->logAction($this->isAdmin() ? FroxlorLogger::ADM_ACTION : FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer data export job #" . $entry);
|
||||
return $this->response(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception('Backup job with id #' . $entry . ' could not be found', 404);
|
||||
throw new Exception('Data export job with id #' . $entry . ' could not be found', 404);
|
||||
}
|
||||
}
|
||||
@@ -20,27 +20,26 @@ trait Forkable
|
||||
|
||||
if ($pid == -1) {
|
||||
exit("Error forking...\n");
|
||||
} else if ($pid == 0) {
|
||||
} elseif ($pid == 0) {
|
||||
// re-create db
|
||||
Database::needRoot(false);
|
||||
$closure(...$closureAttributes);
|
||||
$closure($closureAttributes);
|
||||
exit();
|
||||
} else {
|
||||
$childrenPids[] = $pid;
|
||||
while(count($childrenPids) >= $concurrentChildren) {
|
||||
foreach($childrenPids as $key => $pid) {
|
||||
while (count($childrenPids) >= $concurrentChildren) {
|
||||
foreach ($childrenPids as $key => $pid) {
|
||||
$res = pcntl_waitpid($pid, $status, WNOHANG);
|
||||
|
||||
// If the process has already exited
|
||||
if($res == -1 || $res > 0)
|
||||
if ($res == -1 || $res > 0) {
|
||||
unset($childrenPids[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
while(pcntl_waitpid(0, $status) != -1);
|
||||
while (pcntl_waitpid(0, $status) != -1);
|
||||
} else {
|
||||
if (!defined('CRON_NOFORK_FLAG')) {
|
||||
if (extension_loaded('pcntl')) {
|
||||
@@ -51,7 +50,7 @@ trait Forkable
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, $msg . " Not forking " . self::class . ", this may take a long time!");
|
||||
}
|
||||
foreach ($attributes as $closureAttributes) {
|
||||
$closure(...$closureAttributes);
|
||||
$closure($closureAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class ExportCron extends FroxlorCron
|
||||
|
||||
public static function run()
|
||||
{
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'BackupCron: started - creating customer backup');
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'ExportCron: started - creating customer data export');
|
||||
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` = '20' ORDER BY `id` ASC
|
||||
@@ -65,11 +65,11 @@ class ExportCron extends FroxlorCron
|
||||
|
||||
// create folder if not exists
|
||||
if (!file_exists($row['data']['destdir']) && $row['data']['destdir'] != '/' && $row['data']['destdir'] != Settings::Get('system.documentroot_prefix') && $row['data']['destdir'] != $customerdocroot) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating backup-destination path for customer: ' . escapeshellarg($row['data']['destdir']));
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating data export destination path for customer: ' . escapeshellarg($row['data']['destdir']));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($row['data']['destdir']));
|
||||
}
|
||||
|
||||
self::createCustomerBackup($row['data'], $customerdocroot, $cronlog);
|
||||
self::createCustomerExport($row['data'], $customerdocroot, $cronlog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class ExportCron extends FroxlorCron
|
||||
}
|
||||
|
||||
/**
|
||||
* depending on the give choice, the customers web-data, email-data and databases are being backup'ed
|
||||
* depending on the give choice, the customers web-data, email-data and databases are being exported
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
@@ -88,19 +88,19 @@ class ExportCron extends FroxlorCron
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function createCustomerBackup($data = null, $customerdocroot = null, &$cronlog = null)
|
||||
private static function createCustomerExport($data = null, $customerdocroot = null, &$cronlog = null)
|
||||
{
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating Backup for user "' . $data['loginname'] . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating data export for user "' . $data['loginname'] . '"');
|
||||
|
||||
// create tmp folder
|
||||
$tmpdir = FileDir::makeCorrectDir($data['destdir'] . '/.tmp/');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating tmp-folder "' . $tmpdir . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg($tmpdir));
|
||||
$create_backup_tar_data = "";
|
||||
$create_export_tar_data = "";
|
||||
|
||||
// MySQL databases
|
||||
if ($data['backup_dbs'] == 1) {
|
||||
if ($data['dump_dbs'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mysql-folder "' . FileDir::makeCorrectDir($tmpdir . '/mysql') . '"');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mysql')));
|
||||
@@ -140,7 +140,7 @@ class ExportCron extends FroxlorCron
|
||||
}
|
||||
|
||||
if ($has_dbs) {
|
||||
$create_backup_tar_data .= './mysql ';
|
||||
$create_export_tar_data .= './mysql ';
|
||||
}
|
||||
|
||||
if (file_exists($mysqlcnf_file)) {
|
||||
@@ -151,7 +151,7 @@ class ExportCron extends FroxlorCron
|
||||
}
|
||||
|
||||
// E-mail data
|
||||
if ($data['backup_mail'] == 1) {
|
||||
if ($data['dump_mail'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating mail-folder "' . FileDir::makeCorrectDir($tmpdir . '/mail') . '"');
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/mail')));
|
||||
|
||||
@@ -171,41 +171,41 @@ class ExportCron extends FroxlorCron
|
||||
if (!empty($tar_file_list)) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfvz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/mail/' . $data['loginname'] . '-mail.tar.gz')) . ' -C ' . escapeshellarg($mail_homedir) . ' ' . trim($tar_file_list));
|
||||
$create_backup_tar_data .= './mail ';
|
||||
$create_export_tar_data .= './mail ';
|
||||
}
|
||||
}
|
||||
|
||||
// Web data
|
||||
if ($data['backup_web'] == 1) {
|
||||
if ($data['dump_web'] == 1) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'Creating web-folder "' . FileDir::makeCorrectDir($tmpdir . '/web') . '"');
|
||||
FileDir::safe_exec('mkdir -p ' . escapeshellarg(FileDir::makeCorrectDir($tmpdir . '/web')));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(FileDir::makeCorrectDir($tmpdir), 0, -1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg(FileDir::makeCorrectFile($tmpdir . '/web/' . $data['loginname'] . '-web.tar.gz')) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", FileDir::makeCorrectFile($tmpdir . '/*'))) . ' --exclude=' . escapeshellarg(str_replace($customerdocroot, "./", substr(FileDir::makeCorrectFile($tmpdir), 0, -1))) . ' -C ' . escapeshellarg($customerdocroot) . ' .');
|
||||
$create_backup_tar_data .= './web ';
|
||||
$create_export_tar_data .= './web ';
|
||||
}
|
||||
|
||||
if (!empty($create_backup_tar_data)) {
|
||||
if (!empty($create_export_tar_data)) {
|
||||
// set owner to customer
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('chown -R ' . (int)$data['uid'] . ':' . (int)$data['gid'] . ' ' . escapeshellarg($tmpdir));
|
||||
// create tar-file
|
||||
$backup_file = FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-backup_' . date('YmdHi', time()) . '.tar.gz' . (!empty($data['pgp_public_key']) ? '.gpg' : ''));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating backup-file "' . $backup_file . '"');
|
||||
$export_file = FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-export_' . date('YmdHi', time()) . '.tar.gz' . (!empty($data['pgp_public_key']) ? '.gpg' : ''));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating export-file "' . $export_file . '"');
|
||||
if (!empty($data['pgp_public_key'])) {
|
||||
// pack all archives in tmp-dir to one archive and encrypt it with gpg
|
||||
$recipient_file = FileDir::makeCorrectFile($tmpdir . '/' . $data['loginname'] . '-recipients.gpg');
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'Creating recipient-file "' . $recipient_file . '"');
|
||||
file_put_contents($recipient_file, $data['pgp_public_key']);
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz - -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data) . ' | gpg --encrypt --recipient-file ' . escapeshellarg($recipient_file) . ' --output ' . escapeshellarg($backup_file) . ' --trust-model always --batch --yes');
|
||||
FileDir::safe_exec('tar cfz - -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data) . ' | gpg --encrypt --recipient-file ' . escapeshellarg($recipient_file) . ' --output ' . escapeshellarg($backup_file) . ' --trust-model always --batch --yes', $return_value, ['|']);
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz - -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_export_tar_data) . ' | gpg --encrypt --recipient-file ' . escapeshellarg($recipient_file) . ' --output ' . escapeshellarg($export_file) . ' --trust-model always --batch --yes');
|
||||
FileDir::safe_exec('tar cfz - -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_export_tar_data) . ' | gpg --encrypt --recipient-file ' . escapeshellarg($recipient_file) . ' --output ' . escapeshellarg($export_file) . ' --trust-model always --batch --yes', $return_value, ['|']);
|
||||
} else {
|
||||
// pack all archives in tmp-dir to one archive
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg($backup_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_backup_tar_data));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> tar cfz ' . escapeshellarg($export_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_export_tar_data));
|
||||
FileDir::safe_exec('tar cfz ' . escapeshellarg($export_file) . ' -C ' . escapeshellarg($tmpdir) . ' ' . trim($create_export_tar_data));
|
||||
}
|
||||
// move to destination directory
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
FileDir::safe_exec('mv ' . escapeshellarg($backup_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> mv ' . escapeshellarg($export_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
FileDir::safe_exec('mv ' . escapeshellarg($export_file) . ' ' . escapeshellarg($data['destdir']));
|
||||
// remove tmp-files
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'shell> rm -rf ' . escapeshellarg($tmpdir));
|
||||
FileDir::safe_exec('rm -rf ' . escapeshellarg($tmpdir));
|
||||
|
||||
@@ -46,7 +46,7 @@ class TasksCron extends FroxlorCron
|
||||
* LOOK INTO TASKS TABLE TO SEE IF THERE ARE ANY UNDONE JOBS
|
||||
*/
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "TasksCron: Searching for tasks to do");
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer backup)
|
||||
// no type 99 (regenerate cron.d-file) and no type 20 (customer data export)
|
||||
// order by type descending to re-create bind and then webserver at the end
|
||||
$result_tasks_stmt = Database::query("
|
||||
SELECT `id`, `type`, `data` FROM `" . TABLE_PANEL_TASKS . "` WHERE `type` <> '99' AND `type` <> '20' ORDER BY `type` DESC, `id` ASC
|
||||
|
||||
@@ -82,9 +82,9 @@ final class TaskId
|
||||
const DELETE_DOMAIN_SSL = 12;
|
||||
|
||||
/**
|
||||
* TYPE=20 COSTUMERBACKUP
|
||||
* TYPE=20 CUSTUMER DATA DUMP
|
||||
*/
|
||||
const CREATE_CUSTOMER_BACKUP = 20;
|
||||
const CREATE_CUSTOMER_DATADUMP = 20;
|
||||
|
||||
/**
|
||||
* TYPE=99 REGENERATE CRON
|
||||
|
||||
@@ -211,10 +211,10 @@ class Cronjob
|
||||
'type' => TaskId::DELETE_DOMAIN_SSL,
|
||||
'data' => $data
|
||||
]);
|
||||
} elseif ($type == TaskId::CREATE_CUSTOMER_BACKUP && isset($params[0]) && is_array($params[0])) {
|
||||
} elseif ($type == TaskId::CREATE_CUSTOMER_DATADUMP && isset($params[0]) && is_array($params[0])) {
|
||||
$data = json_encode($params[0]);
|
||||
Database::pexecute($ins_stmt, [
|
||||
'type' => TaskId::CREATE_CUSTOMER_BACKUP,
|
||||
'type' => TaskId::CREATE_CUSTOMER_DATADUMP,
|
||||
'data' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -18,17 +18,16 @@
|
||||
use Froxlor\Settings;
|
||||
|
||||
return [
|
||||
'backup' => [
|
||||
'title' => lng('extras.backup'),
|
||||
'export' => [
|
||||
'title' => lng('extras.export'),
|
||||
'image' => 'fa-solid fa-server',
|
||||
'sections' => [
|
||||
'section_a' => [
|
||||
'title' => lng('extras.backup'),
|
||||
'image' => 'icons/backup_big.png',
|
||||
'title' => lng('extras.export'),
|
||||
'fields' => [
|
||||
'path' => [
|
||||
'label' => lng('panel.backuppath.title'),
|
||||
'desc' => lng('panel.backuppath.description') . '<br>' . (Settings::Get('panel.pathedit') != 'Dropdown' ? lng('panel.pathDescription') : null),
|
||||
'label' => lng('panel.exportpath.title'),
|
||||
'desc' => lng('panel.exportpath.description') . '<br>' . (Settings::Get('panel.pathedit') != 'Dropdown' ? lng('panel.pathDescription') : null),
|
||||
'type' => $pathSelect['type'],
|
||||
'select_var' => $pathSelect['select_var'] ?? '',
|
||||
'selected' => $pathSelect['value'],
|
||||
@@ -36,8 +35,8 @@ return [
|
||||
'note' => $pathSelect['note'] ?? '',
|
||||
],
|
||||
'pgp_public_key' => [
|
||||
'label' => lng('panel.backup_pgp_public_key.title'),
|
||||
'desc' => lng('panel.backup_pgp_public_key.description'),
|
||||
'label' => lng('panel.export_pgp_public_key.title'),
|
||||
'desc' => lng('panel.export_pgp_public_key.description'),
|
||||
'type' => 'textarea',
|
||||
],
|
||||
'path_protection_info' => [
|
||||
@@ -46,20 +45,20 @@ return [
|
||||
'value' => lng('extras.path_protection_info'),
|
||||
'classes' => 'fw-bold text-danger'
|
||||
],
|
||||
'backup_web' => [
|
||||
'label' => lng('extras.backup_web'),
|
||||
'dump_web' => [
|
||||
'label' => lng('extras.dump_web'),
|
||||
'type' => 'checkbox',
|
||||
'value' => '1',
|
||||
'checked' => true
|
||||
],
|
||||
'backup_mail' => [
|
||||
'label' => lng('extras.backup_mail'),
|
||||
'dump_mail' => [
|
||||
'label' => lng('extras.dump_mail'),
|
||||
'type' => 'checkbox',
|
||||
'value' => '1',
|
||||
'checked' => true
|
||||
],
|
||||
'backup_dbs' => [
|
||||
'label' => lng('extras.backup_dbs'),
|
||||
'dump_dbs' => [
|
||||
'label' => lng('extras.dump_dbs'),
|
||||
'type' => 'checkbox',
|
||||
'value' => '1',
|
||||
'checked' => true
|
||||
@@ -133,9 +133,9 @@ return [
|
||||
'show_element' => (Settings::Get('logger.enabled') == true) && (!Settings::IsInList('panel.customer_hide_options', 'extras.logger'))
|
||||
],
|
||||
[
|
||||
'url' => 'customer_extras.php?page=backup',
|
||||
'label' => lng('menue.extras.backup'),
|
||||
'show_element' => (Settings::Get('system.backupenabled') == true) && (!Settings::IsInList('panel.customer_hide_options', 'extras.backup'))
|
||||
'url' => 'customer_extras.php?page=export',
|
||||
'label' => lng('menue.extras.export'),
|
||||
'show_element' => (Settings::Get('system.exportenabled') == true) && (!Settings::IsInList('panel.customer_hide_options', 'extras.export'))
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
@@ -28,10 +28,10 @@ use Froxlor\UI\Callbacks\Text;
|
||||
use Froxlor\UI\Listing;
|
||||
|
||||
return [
|
||||
'backup_list' => [
|
||||
'title' => lng('error.customerhasongoingbackupjob'),
|
||||
'export_list' => [
|
||||
'title' => lng('error.customerhasongoingexportjob'),
|
||||
'icon' => 'fa-solid fa-server',
|
||||
'self_overview' => ['section' => 'extras', 'page' => 'backup'],
|
||||
'self_overview' => ['section' => 'extras', 'page' => 'export'],
|
||||
'default_sorting' => ['destdir' => 'asc'],
|
||||
'columns' => [
|
||||
'destdir' => [
|
||||
@@ -44,28 +44,28 @@ return [
|
||||
'field' => 'data.pgp_public_key',
|
||||
'callback' => [Text::class, 'boolean']
|
||||
],
|
||||
'backup_web' => [
|
||||
'label' => lng('extras.backup_web'),
|
||||
'field' => 'data.backup_web',
|
||||
'dump_web' => [
|
||||
'label' => lng('extras.dump_web'),
|
||||
'field' => 'data.dump_web',
|
||||
'callback' => [Text::class, 'boolean'],
|
||||
],
|
||||
'backup_mail' => [
|
||||
'label' => lng('extras.backup_mail'),
|
||||
'field' => 'data.backup_mail',
|
||||
'dump_mail' => [
|
||||
'label' => lng('extras.dump_mail'),
|
||||
'field' => 'data.dump_mail',
|
||||
'callback' => [Text::class, 'boolean'],
|
||||
],
|
||||
'backup_dbs' => [
|
||||
'label' => lng('extras.backup_dbs'),
|
||||
'field' => 'data.backup_dbs',
|
||||
'dump_dbs' => [
|
||||
'label' => lng('extras.dump_dbs'),
|
||||
'field' => 'data.dump_dbs',
|
||||
'callback' => [Text::class, 'boolean'],
|
||||
]
|
||||
],
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('backup_list', [
|
||||
'visible_columns' => Listing::getVisibleColumnsForListing('export_list', [
|
||||
'destdir',
|
||||
'pgp_public_key',
|
||||
'backup_web',
|
||||
'backup_mail',
|
||||
'backup_dbs'
|
||||
'dump_web',
|
||||
'dump_mail',
|
||||
'dump_dbs'
|
||||
]),
|
||||
'actions' => [
|
||||
'delete' => [
|
||||
Reference in New Issue
Block a user