From 79049468627780fe14ff2378b338b02cdd8bcb88 Mon Sep 17 00:00:00 2001 From: "Michael Kaufmann (d00p)" Date: Tue, 27 Jan 2015 23:04:46 +0100 Subject: [PATCH] push some upcoming changes (still holding back db changes b/c of version jump to rc2) Signed-off-by: Michael Kaufmann (d00p) --- actions/admin/settings/125.cronjob.php | 8 ++ .../preconfig/0.9/preconfig_0.9.inc.php | 7 ++ lib/cron_init.php | 101 ++++++++++-------- lib/functions/output/function.dieWithMail.php | 69 ++++++++++++ lng/english.lng.php | 2 + lng/german.lng.php | 2 + 6 files changed, 142 insertions(+), 47 deletions(-) create mode 100644 lib/functions/output/function.dieWithMail.php diff --git a/actions/admin/settings/125.cronjob.php b/actions/admin/settings/125.cronjob.php index e23a2379..077be68a 100644 --- a/actions/admin/settings/125.cronjob.php +++ b/actions/admin/settings/125.cronjob.php @@ -29,6 +29,14 @@ return array( 'default' => '/etc/cron.d/froxlor', 'save_method' => 'storeSettingField', ), + 'system_send_cron_errors' => array( + 'label' => $lng['serversettings']['system_send_cron_errors'], + 'settinggroup' => 'system', + 'varname' => 'send_cron_errors', + 'type' => 'bool', + 'default' => false, + 'save_method' => 'storeSettingField', + ), 'system_croncmdline' => array( 'label' => $lng['serversettings']['system_croncmdline'], 'settinggroup' => 'system', diff --git a/install/updates/preconfig/0.9/preconfig_0.9.inc.php b/install/updates/preconfig/0.9/preconfig_0.9.inc.php index 47c48bae..42e0921d 100644 --- a/install/updates/preconfig/0.9/preconfig_0.9.inc.php +++ b/install/updates/preconfig/0.9/preconfig_0.9.inc.php @@ -679,4 +679,11 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version) { } } + if (versionInUpdate($current_version, '0.9.33-rc2')) { + $has_preconfig = true; + $description = 'You can chose whether you want to receive an e-mail on cronjob errors. Keep in mind that this can lead to an e-mail being sent every 5 minutes.

'; + $question = 'Do you want to receive cron-errors via mail? (default: no): '; + $question.= makeyesno('system_send_cron_errors', '1', '0', '0').'
'; + eval("\$return.=\"" . getTemplate("update/preconfigitem") . "\";"); + } } diff --git a/lib/cron_init.php b/lib/cron_init.php index f1084ddc..64a77e78 100644 --- a/lib/cron_init.php +++ b/lib/cron_init.php @@ -32,12 +32,14 @@ if (function_exists("date_default_timezone_set") } $basename = basename($_SERVER['PHP_SELF'], '.php'); +$crontype = ""; if (isset($argv) && is_array($argv) && count($argv) > 1) { for($x=1;$x < count($argv);$x++) { if (substr(strtolower($argv[$x]), 0, 2) == '--' && strlen($argv[$x]) > 3 ) { - $basename .= "-".substr(strtolower($argv[$x]), 2); + $crontype = substr(strtolower($argv[$x]), 2); + $basename .= "-".$crontype; break; } } @@ -52,57 +54,15 @@ $lockfile = $lockdir . $lockfName; // froxlor installation isn't in /var/www/froxlor define('FROXLOR_INSTALL_DIR', dirname(dirname(__FILE__))); + // create and open the lockfile! $keepLockFile = false; $debugHandler = fopen($lockfile, 'w'); fwrite($debugHandler, 'Setting Lockfile to ' . $lockfile . "\n"); fwrite($debugHandler, 'Setting Froxlor installation path to ' . FROXLOR_INSTALL_DIR . "\n"); -// open the lockfile directory and scan for existing lockfiles -$lockDirHandle = opendir($lockdir); - -while ($fName = readdir($lockDirHandle)) { - - if ($lockFilename == substr($fName, 0, strlen($lockFilename)) - && $lockfName != $fName - ) { - // Check if last run jailed out with an exception - $croncontent = file($lockdir . $fName); - $lastline = $croncontent[(count($croncontent) - 1)]; - - if ($lastline == '=== Keep lockfile because of exception ===') { - fclose($debugHandler); - unlink($lockfile); - die('Last cron jailed out with an exception. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $fName . '* for more information!' . "\n"); - } - - // Check if cron is running or has died. - $check_pid = substr(strstr($fName, "-"), 1); - system("kill -CHLD " . (int)$check_pid . " 1> /dev/null 2> /dev/null", $check_pid_return); - - if ($check_pid_return == 1) { - // Result: Existing lockfile/pid isnt running - // Most likely it has died - // - // Action: Remove it and continue - // - fwrite($debugHandler, 'Previous cronjob didn\'t exit clean. PID: ' . $check_pid . "\n"); - fwrite($debugHandler, 'Removing lockfile: ' . $lockdir . $fName . "\n"); - unlink($lockdir . $fName); - - } else { - // Result: A Cronscript with this pid - // is still running - // Action: remove my own Lock and die - // - // close the current lockfile - fclose($debugHandler); - - // ... and delete it - unlink($lockfile); - die('There is already a Cronjob in progress. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $lockFilename . '* for more information!' . "\n"); - } - } +if (!file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) { + die("Froxlor does not seem to be installed yet - skipping cronjob"); } // Includes the Usersettings eg. MySQL-Username/Passwort etc. @@ -139,6 +99,53 @@ try { fwrite($debugHandler, 'Database-connection established' . "\n"); +// open the lockfile directory and scan for existing lockfiles +$lockDirHandle = opendir($lockdir); + +while ($fName = readdir($lockDirHandle)) { + + if ($lockFilename == substr($fName, 0, strlen($lockFilename)) + && $lockfName != $fName + ) { + // Check if last run jailed out with an exception + $croncontent = file($lockdir . $fName); + $lastline = $croncontent[(count($croncontent) - 1)]; + + if ($lastline == '=== Keep lockfile because of exception ===') { + fclose($debugHandler); + unlink($lockfile); + dieWithMail('Last cron jailed out with an exception. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $fName . '* for more information!' . "\n"); + } + + // Check if cron is running or has died. + $check_pid = substr(strstr($fName, "-"), 1); + system("kill -CHLD " . (int)$check_pid . " 1> /dev/null 2> /dev/null", $check_pid_return); + + if ($check_pid_return == 1) { + // Result: Existing lockfile/pid isnt running + // Most likely it has died + // + // Action: Remove it and continue + // + fwrite($debugHandler, 'Previous cronjob didn\'t exit clean. PID: ' . $check_pid . "\n"); + fwrite($debugHandler, 'Removing lockfile: ' . $lockdir . $fName . "\n"); + unlink($lockdir . $fName); + + } else { + // Result: A Cronscript with this pid + // is still running + // Action: remove my own Lock and die + // + // close the current lockfile + fclose($debugHandler); + + // ... and delete it + unlink($lockfile); + dieWithMail('There is already a Cronjob for '.$crontype.' in progress. Exiting...' . "\n" . 'Take a look into the contents of ' . $lockdir . $lockFilename . '* for more information!' . "\n"); + } + } +} + /** * if using fcgid or fpm for froxlor-vhost itself, we have to check * whether the permission of the files are still correct @@ -185,7 +192,7 @@ if (Settings::Get('panel.version') == null $errormessage.= "Possible reason: Froxlor update\n"; $errormessage.= "Information: Current version in database: ".Settings::Get('panel.version')." - version of Froxlor files: ".$version."\n"; $errormessage.= "Solution: Please visit your Foxlor admin interface for further information.\n"; - die($errormessage); + dieWithMail($errormessage); } if (Settings::Get('system.cron_allowautoupdate') == 1) { diff --git a/lib/functions/output/function.dieWithMail.php b/lib/functions/output/function.dieWithMail.php new file mode 100644 index 00000000..77ac2604 --- /dev/null +++ b/lib/functions/output/function.dieWithMail.php @@ -0,0 +1,69 @@ + + * @author Froxlor team (2010-) + * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt + * @package Cron + * + * @since 0.9.33 + * + */ + +/** + * Cronjob function to end a cronjob in a critical condition + * but not without sending a notification mail to the admin + * + * @param string $message + * @param string $subject + * + * @return void + */ +function dieWithMail($message, $subject = "[froxlor] Cronjob error") { + + if (Settings::Get('system.send_cron_errors') == '1') { + + $_mail = new PHPMailer(true); + $_mail->CharSet = "UTF-8"; + + if (PHPMailer::ValidateAddress(Settings::Get('panel.adminmail')) !== false) { + // set return-to address and custom sender-name, see #76 + $_mail->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname')); + if (Settings::Get('panel.adminmail_return') != '') { + $_mail->AddReplyTo(Settings::Get('panel.adminmail_return'), Settings::Get('panel.adminmail_defname')); + } + } + + $_mailerror = false; + try { + $_mail->Subject = $subject; + $_mail->AltBody = $message; + $_mail->MsgHTML(nl2br($message)); + $_mail->AddAddress(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname')); + $_mail->Send(); + } catch (phpmailerException $e) { + $mailerr_msg = $e->errorMessage(); + $_mailerror = true; + } catch (Exception $e) { + $mailerr_msg = $e->getMessage(); + $_mailerror = true; + } + + $_mail->ClearAddresses(); + + if ($_mailerror) { + echo 'Error sending mail: ' . $mailerr_msg . "\n"; + } + } + + die($message); + +} diff --git a/lng/english.lng.php b/lng/english.lng.php index 6f662030..130fd0c3 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -1836,3 +1836,5 @@ $lng['domains']['import_description'] = 'Detailed information about the structur $lng['usersettings']['custom_notes']['title'] = 'Custom notes'; $lng['usersettings']['custom_notes']['description'] = 'Feel free to put any notes you want/need in here. They will show up in the admin/customer overview for the corresponding user.'; $lng['usersettings']['custom_notes']['show'] = 'Show your notes on the dashboard of the user'; +$lng['serversettings']['system_send_cron_errors']['title'] = 'Send cron-errors to froxlor-admin via e-mail'; +$lng['serversettings']['system_send_cron_errors']['description'] = 'Chose whether you want to receive an e-mail on cronjob errors. Keep in mind that this can lead to an e-mail being sent every 5 minutes depending on the error and your cronjob settings.'; diff --git a/lng/german.lng.php b/lng/german.lng.php index e5dc845b..0da2d2bb 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1563,3 +1563,5 @@ $lng['domains']['import_description'] = 'Detaillierte Informationen über den Au $lng['usersettings']['custom_notes']['title'] = 'Eigene Notizen'; $lng['usersettings']['custom_notes']['description'] = 'Hier können Notizen je nach Lust und Laune eingetragen werden. Diese werden in der Administrator/Kunden-Übersicht bei dem jeweiligen Benutzer angezeigt.'; $lng['usersettings']['custom_notes']['show'] = 'Zeige die Notizen auf dem Dashboard des Benutzers'; +$lng['serversettings']['system_send_cron_errors']['title'] = 'Sende Cron-Fehler via E-Mail an den Froxlor-Admin'; +$lng['serversettings']['system_send_cron_errors']['description'] = 'Gib an, ob bei einem Cron-Fehler eine E-Mail versendet werden soll. Beachte das es je nach Fehler und Cronjob-Einstellungen dazu kommen kann, dass diese E-Mail alle 5 Minuten gesendet wird.';