forked from Wavyzz/dolibarr
Merge branch 'develop' into FIX---Max-size-send-backup
This commit is contained in:
@@ -52,8 +52,8 @@ class Utils
|
||||
* Purge files into directory of data files.
|
||||
* CAN BE A CRON TASK
|
||||
*
|
||||
* @param string $choices Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than $nbsecondsold seconds, 'logfiles', or mix of this). Note 'allfiles' is possible too but very dangerous.
|
||||
* @param int $nbsecondsold Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold'
|
||||
* @param string $choices Choice of purge mode ('tempfiles', 'tempfilesold' to purge temp older than $nbsecondsold seconds, 'logfiles', or mix of this). Note that 'allfiles' is also possible but very dangerous.
|
||||
* @param int $nbsecondsold Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold', or deletion of file if $choice is 'allfiles'
|
||||
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
|
||||
*/
|
||||
public function purgeFiles($choices = 'tempfilesold+logfiles', $nbsecondsold = 86400)
|
||||
@@ -67,6 +67,9 @@ class Utils
|
||||
if (empty($choices)) {
|
||||
$choices = 'tempfilesold+logfiles';
|
||||
}
|
||||
if ($choices == 'allfiles' && $nbsecondsold > 0) {
|
||||
$choices = 'allfilesold';
|
||||
}
|
||||
|
||||
dol_syslog("Utils::purgeFiles choice=".$choices, LOG_DEBUG);
|
||||
|
||||
@@ -77,6 +80,7 @@ class Utils
|
||||
|
||||
$choicesarray = preg_split('/[\+,]/', $choices);
|
||||
foreach ($choicesarray as $choice) {
|
||||
$now = dol_now();
|
||||
$filesarray = array();
|
||||
|
||||
if ($choice == 'tempfiles' || $choice == 'tempfilesold') {
|
||||
@@ -85,7 +89,6 @@ class Utils
|
||||
$filesarray = dol_dir_list($dolibarr_main_data_root, "directories", 1, '^temp$', '', 'name', SORT_ASC, 2, 0, '', 1); // Do not follow symlinks
|
||||
|
||||
if ($choice == 'tempfilesold') {
|
||||
$now = dol_now();
|
||||
foreach ($filesarray as $key => $val) {
|
||||
if ($val['date'] > ($now - ($nbsecondsold))) {
|
||||
unset($filesarray[$key]); // Discard temp dir not older than $nbsecondsold
|
||||
@@ -98,7 +101,14 @@ class Utils
|
||||
if ($choice == 'allfiles') {
|
||||
// Delete all files (except install.lock, do not follow symbolic links)
|
||||
if ($dolibarr_main_data_root) {
|
||||
$filesarray = dol_dir_list($dolibarr_main_data_root, "all", 0, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1);
|
||||
$filesarray = dol_dir_list($dolibarr_main_data_root, "all", 0, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1); // No need to use recursive, we will delete directory
|
||||
}
|
||||
}
|
||||
|
||||
if ($choice == 'allfilesold') {
|
||||
// Delete all files (except install.lock, do not follow symbolic links)
|
||||
if ($dolibarr_main_data_root) {
|
||||
$filesarray = dol_dir_list($dolibarr_main_data_root, "files", 1, '', 'install\.lock$', 'name', SORT_ASC, 0, 0, '', 1, $nbsecondsold); // No need to use recursive, we will delete directory
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,21 +148,23 @@ class Utils
|
||||
$countdeleted += $tmpcountdeleted;
|
||||
}
|
||||
} elseif ($filesarray[$key]['type'] == 'file') {
|
||||
// If (file that is not logfile) or (if mode is logfile)
|
||||
if ($filesarray[$key]['fullname'] != $filelog || $choice == 'logfile' || $choice == 'logfiles') {
|
||||
$result = dol_delete_file($filesarray[$key]['fullname'], 1, 1);
|
||||
if ($result) {
|
||||
$count++;
|
||||
$countdeleted++;
|
||||
} else {
|
||||
$counterror++;
|
||||
if ($choice != 'allfilesold' || $filesarray[$key]['date'] < ($now - $nbsecondsold)) {
|
||||
// If (file that is not logfile) or (if mode is logfile)
|
||||
if ($filesarray[$key]['fullname'] != $filelog || $choice == 'logfile' || $choice == 'logfiles') {
|
||||
$result = dol_delete_file($filesarray[$key]['fullname'], 1, 1);
|
||||
if ($result) {
|
||||
$count++;
|
||||
$countdeleted++;
|
||||
} else {
|
||||
$counterror++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update cachenbofdoc
|
||||
if (!empty($conf->ecm->enabled) && $choice == 'allfiles') {
|
||||
if (isModEnabled('ecm') && $choice == 'allfiles') {
|
||||
require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php';
|
||||
$ecmdirstatic = new EcmDirectory($this->db);
|
||||
$result = $ecmdirstatic->refreshcachenboffile(1);
|
||||
@@ -203,6 +215,9 @@ class Utils
|
||||
dol_syslog("Utils::dumpDatabase type=".$type." compression=".$compression." file=".$file, LOG_DEBUG);
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
|
||||
// Clean data
|
||||
$file = dol_sanitizeFileName($file);
|
||||
|
||||
// Check compression parameter
|
||||
if (!in_array($compression, array('none', 'gz', 'bz', 'zip', 'zstd'))) {
|
||||
$langs->load("errors");
|
||||
@@ -342,6 +357,8 @@ class Utils
|
||||
|
||||
$handle = '';
|
||||
|
||||
// If $lowmemorydump is set, it means we want to make the compression using an external pipe instead retreiving the
|
||||
// content of the dump in PHP memory array $output_arr and then print it into the PHP pipe open with xopen().
|
||||
$lowmemorydump = GETPOSTISSET("lowmemorydump") ? GETPOST("lowmemorydump") : getDolGlobalString('MAIN_LOW_MEMORY_DUMP');
|
||||
|
||||
// Start call method to execute dump
|
||||
@@ -359,23 +376,23 @@ class Utils
|
||||
}
|
||||
} else {
|
||||
if ($compression == 'none') {
|
||||
$fullcommandclear .= " > ".$outputfile;
|
||||
$fullcommandcrypted .= " > ".$outputfile;
|
||||
$fullcommandclear .= ' > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$fullcommandcrypted .= ' > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$handle = 1;
|
||||
} elseif ($compression == 'gz') {
|
||||
$fullcommandclear .= " | gzip > ".$outputfile;
|
||||
$fullcommandcrypted .= " | gzip > ".$outputfile;
|
||||
$paramcrypted.=" | gzip";
|
||||
$fullcommandclear .= ' | gzip > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$fullcommandcrypted .= ' | gzip > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$paramcrypted .= ' | gzip';
|
||||
$handle = 1;
|
||||
} elseif ($compression == 'bz') {
|
||||
$fullcommandclear .= " | bzip2 > ".$outputfile;
|
||||
$fullcommandcrypted .= " | bzip2 > ".$outputfile;
|
||||
$paramcrypted.=" | bzip2";
|
||||
$fullcommandclear .= ' | bzip2 > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$fullcommandcrypted .= ' | bzip2 > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$paramcrypted .= ' | bzip2';
|
||||
$handle = 1;
|
||||
} elseif ($compression == 'zstd') {
|
||||
$fullcommandclear .= " | zstd > ".$outputfile;
|
||||
$fullcommandcrypted .= " | zstd > ".$outputfile;
|
||||
$paramcrypted.=" | zstd";
|
||||
$fullcommandclear .= ' | zstd > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$fullcommandcrypted .= ' | zstd > "'.dol_sanitizePathName($outputfile).'"';
|
||||
$paramcrypted .= ' | zstd';
|
||||
$handle = 1;
|
||||
}
|
||||
}
|
||||
@@ -399,8 +416,8 @@ class Utils
|
||||
}
|
||||
|
||||
|
||||
// TODO Replace with executeCLI function but
|
||||
// we must first introduce a low memory mode
|
||||
// TODO Replace with Utils->executeCLI() function but
|
||||
// we must first introduce the variant with $lowmemorydump into this method.
|
||||
if ($execmethod == 1) {
|
||||
$output_arr = array();
|
||||
$retval = null;
|
||||
@@ -459,15 +476,16 @@ class Utils
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($compression == 'none') {
|
||||
fclose($handle);
|
||||
} elseif ($compression == 'gz') {
|
||||
gzclose($handle);
|
||||
} elseif ($compression == 'bz') {
|
||||
bzclose($handle);
|
||||
} elseif ($compression == 'zstd') {
|
||||
fclose($handle);
|
||||
if (!$lowmemorydump) {
|
||||
if ($compression == 'none') {
|
||||
fclose($handle);
|
||||
} elseif ($compression == 'gz') {
|
||||
gzclose($handle);
|
||||
} elseif ($compression == 'bz') {
|
||||
bzclose($handle);
|
||||
} elseif ($compression == 'zstd') {
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($conf->global->MAIN_UMASK)) {
|
||||
@@ -614,7 +632,7 @@ class Utils
|
||||
//if ($compression == 'bz')
|
||||
$paramcrypted = $param;
|
||||
$paramclear = $param;
|
||||
/*if (! empty($dolibarr_main_db_pass))
|
||||
/*if (!empty($dolibarr_main_db_pass))
|
||||
{
|
||||
$paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass);
|
||||
$paramclear.=" -W".$dolibarr_main_db_pass;
|
||||
@@ -652,7 +670,7 @@ class Utils
|
||||
* @param string $outputfile A path for an output file (used only when method is 2). For example: $conf->admin->dir_temp.'/out.tmp';
|
||||
* @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method
|
||||
* @param string $redirectionfile If defined, a redirection of output to this file is added.
|
||||
* @param int $noescapecommand 1=Do not escape command. Warning: Using this parameter need you alreay sanitized the command. if not, it will lead to security vulnerability.
|
||||
* @param int $noescapecommand 1=Do not escape command. Warning: Using this parameter needs you alreay have sanitized the command. if not, it will lead to security vulnerability.
|
||||
* This parameter is provided for backward compatibility with external modules. Always use 0 in core.
|
||||
* @param string $redirectionfileerr If defined, a redirection of error is added to this file instead of to channel 1.
|
||||
* @return array array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK.
|
||||
@@ -1339,4 +1357,74 @@ class Utils
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean unfinished cronjob in processing when pid is no longer present in the system
|
||||
* CAN BE A CRON TASK
|
||||
*
|
||||
* @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK)
|
||||
* @throws Exception
|
||||
*/
|
||||
public function cleanUnfinishedCronjob()
|
||||
{
|
||||
global $db, $user;
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Starting cleaning");
|
||||
|
||||
// Import Cronjob class if not present
|
||||
dol_include_once('/cron/class/cronjob.class.php');
|
||||
|
||||
// Get this job object
|
||||
$this_job = new Cronjob($db);
|
||||
$this_job->fetch(-1, 'Utils', 'cleanUnfinishedCronjob');
|
||||
if (empty($this_job->id) || !empty($this_job->error)) {
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Unable to fetch himself: ".$this_job->error, LOG_ERR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set this job processing to 0 to avoid being locked by his processing state
|
||||
$this_job->processing = 0;
|
||||
if ($this_job->update($user) < 0) {
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Unable to update himself: ".implode(', ', $this_job->errors), LOG_ERR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
$cron_job = new Cronjob($db);
|
||||
$cron_job->fetchAll('DESC', 't.rowid', 100, 0, 1, '', 1); // Fetch jobs that are currently running
|
||||
|
||||
// Iterate over all jobs in processing (this can't be this job since his state is set to 0 before)
|
||||
foreach ($cron_job->lines as $job_line) {
|
||||
// Avoid job with no PID
|
||||
if (empty($job_line->pid)) {
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." don't have a PID", LOG_DEBUG);
|
||||
continue;
|
||||
}
|
||||
|
||||
$job = new Cronjob($db);
|
||||
$job->fetch($job_line->id);
|
||||
if (empty($job->id) || !empty($job->error)) {
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." can't be fetch: ".$job->error, LOG_ERR);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calling posix_kill with the 0 kill signal will return true if the process is running, false otherwise.
|
||||
if (! posix_kill($job->pid, 0)) {
|
||||
// Clean processing and pid values
|
||||
$job->processing = 0;
|
||||
$job->pid = null;
|
||||
|
||||
// Set last result as an error and add the reason on the last output
|
||||
$job->lastresult = -1;
|
||||
$job->lastoutput = 'Job killed by job cleanUnfinishedCronjob';
|
||||
|
||||
if ($job->update($user) < 0) {
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." can't be updated: ".implode(', ', $job->errors), LOG_ERR);
|
||||
continue;
|
||||
}
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Cronjob ".$job_line->id." cleaned");
|
||||
}
|
||||
}
|
||||
|
||||
dol_syslog("Utils::cleanUnfinishedCronjob Cleaning completed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user