make froxlor_master_cronkjob a froxlor-cli command; secure files/folders in froxlor-virtualhost;
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
@@ -62,14 +62,6 @@ return [
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
],
|
||||
'system_debug_cron' => [
|
||||
'label' => lng('serversettings.cron.debug'),
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'debug_cron',
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
@@ -33,6 +33,7 @@ use Froxlor\Cli\PhpSessionclean;
|
||||
use Froxlor\Cli\SwitchServerIp;
|
||||
use Froxlor\Cli\UpdateCommand;
|
||||
use Froxlor\Cli\InstallCommand;
|
||||
use Froxlor\Cli\MasterCron;
|
||||
use Froxlor\Froxlor;
|
||||
|
||||
// validate correct php version
|
||||
@@ -55,4 +56,5 @@ $application->add(new PhpSessionclean());
|
||||
$application->add(new SwitchServerIp());
|
||||
$application->add(new UpdateCommand());
|
||||
$application->add(new InstallCommand());
|
||||
$application->add(new MasterCron());
|
||||
$application->run();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Install\Update;
|
||||
@@ -105,15 +106,16 @@ if (Froxlor::isFroxlorVersion('0.10.99')) {
|
||||
"lng/lng_references.php",
|
||||
"lng/portugues.lng.php",
|
||||
"lng/swedish.lng.php",
|
||||
"scripts",
|
||||
);
|
||||
$disabled = explode(',', ini_get('disable_functions'));
|
||||
$exec_allowed = !in_array('exec', $disabled);
|
||||
$del_list = "";
|
||||
foreach ($to_clean as $filedir) {
|
||||
$complete_filedir = \Froxlor\Froxlor::getInstallDir() . $filedir;
|
||||
$complete_filedir = Froxlor::getInstallDir() . $filedir;
|
||||
if (file_exists($complete_filedir)) {
|
||||
if ($exec_allowed) {
|
||||
Froxlor\FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
|
||||
FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
|
||||
} else {
|
||||
$del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL;
|
||||
}
|
||||
@@ -154,6 +156,7 @@ if (Froxlor::isFroxlorVersion('0.10.99')) {
|
||||
'Česká republika' => 'cs'
|
||||
];
|
||||
Settings::Set('panel.standardlanguage', $lang_map[Settings::Get('panel_standardlanguage')] ?? 'en');
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'debug_cron'");
|
||||
Update::lastStepStatus(0);
|
||||
|
||||
Froxlor::updateToVersion($update_to);
|
||||
|
||||
@@ -64,10 +64,10 @@ if (Froxlor::isFroxlor()) {
|
||||
|
||||
$integrity = new IntegrityCheck();
|
||||
if (!$integrity->checkAll()) {
|
||||
Update::lastStepStatus(1, 'Monkeys ate the integrity');
|
||||
Update::showUpdateStep("Trying to remove monkeys, feeding bananas");
|
||||
Update::lastStepStatus(1, 'Integrity could not be validated');
|
||||
Update::showUpdateStep("Trying to automatically restore integrity");
|
||||
if (!$integrity->fixAll()) {
|
||||
Update::lastStepStatus(2, 'failed', 'Some monkeys just would not move, you should contact team@froxlor.org');
|
||||
Update::lastStepStatus(2, 'failed', 'Check "database validation" as admin on the left-side menu to see where the problem is');
|
||||
} else {
|
||||
Update::lastStepStatus(0, 'Integrity restored');
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
use Exception;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Settings;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -39,10 +41,42 @@ class CliCommand extends Command
|
||||
$output->writeln("<error>Could not find froxlor's userdata.inc.php file. You should use this script only with an installed froxlor system.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
||||
$output->writeln("<error>It seems that the froxlor files have been updated. Please login and finish the update procedure.</>");
|
||||
// try database connection
|
||||
try {
|
||||
Database::query("SELECT 1");
|
||||
} catch (Exception $e) {
|
||||
// Do not proceed further if no database connection could be established
|
||||
$output->writeln("<error>" . $e->getMessage() . "</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
||||
if ((int)Settings::Get('system.cron_allowautoupdate') == 1) {
|
||||
return $this->runUpdate($output);
|
||||
} else {
|
||||
$output->writeln("<error>It seems that the froxlor files have been updated. Please login and finish the update procedure.</>");
|
||||
return self::INVALID;
|
||||
}
|
||||
}
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function runUpdate(OutputInterface $output): int
|
||||
{
|
||||
$output->writeln('<comment>Automatic update is activated and we are going to proceed without any notices</>');
|
||||
include_once Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
define('_CRON_UPDATE', 1);
|
||||
ob_start([
|
||||
'this',
|
||||
'cleanUpdateOutput'
|
||||
]);
|
||||
include_once Froxlor::getInstallDir() . '/install/updatesql.php';
|
||||
ob_end_flush();
|
||||
$output->writeln('<info>Automatic update done - you should check your settings to be sure everything is fine</>');
|
||||
return self::SUCCCESS;
|
||||
}
|
||||
|
||||
private function cleanUpdateOutput($buffer)
|
||||
{
|
||||
return strip_tags(preg_replace("/<br\W*?\/>/", "\n", $buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ final class ConfigServices extends CliCommand
|
||||
// set is_configured flag
|
||||
Settings::Set('panel.is_configured', '1', true);
|
||||
// run cronjob at the end to ensure configs are all up to date
|
||||
exec('php ' . Froxlor::getInstallDir() . 'scripts/froxlor_master_cronjob.php --force');
|
||||
exec('php ' . Froxlor::getInstallDir() . 'bin/froxlor-cli froxlor:cron --force');
|
||||
// and done
|
||||
$output->writeln('<info>All services have been configured</>');
|
||||
return self::SUCCESS;
|
||||
|
||||
258
lib/Froxlor/Cli/MasterCron.php
Normal file
258
lib/Froxlor/Cli/MasterCron.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\System\Cronjob;
|
||||
use Froxlor\Cron\TaskId;
|
||||
use Froxlor\Cron\System\Extrausers;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
final class MasterCron extends CliCommand
|
||||
{
|
||||
private $lockFile = null;
|
||||
|
||||
private $cronLog = null;
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('froxlor:cron');
|
||||
$this->setDescription('Regulary perform tasks created by froxlor');
|
||||
$this->addArgument('job', InputArgument::IS_ARRAY, 'Job(s) to run');
|
||||
$this->addOption('run-task', 'r', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Run a specific task [1 = re-generate configs, 4 = re-generate dns zones, 10 = re-set quotas, 99 = re-create cron.d-file]')
|
||||
->addOption('force', 'f', InputOption::VALUE_NONE, 'Forces re-generating of config-files (webserver, nameserver, etc.)')
|
||||
->addOption('debug', 'd', InputOption::VALUE_NONE, 'Output debug information about what is going on to STDOUT.')
|
||||
->addOption('no-fork', 'N', InputOption::VALUE_NONE, 'Do not fork to background (traffic cron only).');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$result = self::SUCCESS;
|
||||
$result = $this->validateRequirements($input, $output);
|
||||
|
||||
$jobs = $input->getArgument('job');
|
||||
|
||||
// handle force option
|
||||
if ($input->getOption('force')) {
|
||||
// rebuild all config files
|
||||
Cronjob::inserttask(TaskId::REBUILD_VHOST);
|
||||
Cronjob::inserttask(TaskId::REBUILD_DNS);
|
||||
Cronjob::inserttask(TaskId::CREATE_QUOTA);
|
||||
Cronjob::inserttask(TaskId::REBUILD_CRON);
|
||||
array_push($jobs, 'tasks');
|
||||
define('CRON_IS_FORCED', 1);
|
||||
}
|
||||
// handle debug option
|
||||
if ($input->getOption('debug')) {
|
||||
define('CRON_DEBUG_FLAG', 1);
|
||||
}
|
||||
// handle no-fork option
|
||||
if ($input->getOption('no-fork')) {
|
||||
define('CRON_NOFORK_FLAG', 1);
|
||||
}
|
||||
// handle run-task option
|
||||
if ($input->getOption('run-task')) {
|
||||
$tasks_to_run = $input->getOption('run-task');
|
||||
foreach ($tasks_to_run as $ttr) {
|
||||
if (in_array($ttr, [1, 4, 10, 99])) {
|
||||
Cronjob::inserttask($ttr);
|
||||
array_push($jobs, 'tasks');
|
||||
} else {
|
||||
$output->writeln('<comment>Unknown task number "' . $ttr . '"</>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unique job-array
|
||||
$jobs = array_unique($jobs);
|
||||
|
||||
// check for given job(s) to execute and return if empty
|
||||
if (empty($jobs)) {
|
||||
$output->writeln('<error>No job given. Nothing to do.</>');
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
$this->validateOwnership($output);
|
||||
|
||||
$this->cronLog = FroxlorLogger::getInstanceOf([
|
||||
'loginname' => 'cronjob'
|
||||
]);
|
||||
$this->cronLog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
// check whether there are actual tasks to perform by 'tasks'-cron so
|
||||
// we dont regenerate files unnecessarily
|
||||
$tasks_cnt_stmt = Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// iterate through all needed jobs
|
||||
foreach ($jobs as $job) {
|
||||
// lock the job
|
||||
if ($this->lockJob($job, $output)) {
|
||||
// get FQDN of cron-class
|
||||
$cronfile = $this->getCronModule($job, $output);
|
||||
// validate
|
||||
if ($cronfile && class_exists($cronfile)) {
|
||||
// info
|
||||
$output->writeln('<info>Running "' . $job . '" job' . (defined('CRON_IS_FORCED') ? ' (forced)' : '') . (defined('CRON_DEBUG_FLAG') ? ' (debug)' : '') . (defined('CRON_NOFORK_FLAG') ? ' (not forking)' : '') . '</>');
|
||||
// update time of last run
|
||||
Cronjob::updateLastRunOfCron($job);
|
||||
// set logger
|
||||
$cronfile::setCronlog($this->cronLog);
|
||||
// run the job
|
||||
$cronfile::run();
|
||||
}
|
||||
// free the lockfile
|
||||
$this->unlockJob($job);
|
||||
}
|
||||
}
|
||||
|
||||
// regenerate nss-extrausers files / invalidate nscd cache (if used)
|
||||
$this->refreshUsers((int) $tasks_cnt['jobcnt']);
|
||||
|
||||
// we have to check the system's last guid with every cron run
|
||||
// in case the admin installed new software which added a new user
|
||||
//so users in the database don't conflict with system users
|
||||
$this->cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
Cronjob::checkLastGuid();
|
||||
|
||||
// check for cron.d-generation task and create it if necessary
|
||||
CronConfig::checkCrondConfigurationFile();
|
||||
|
||||
// reset cronlog-flag if set to "once"
|
||||
if ((int) Settings::Get('logger.log_cron') == 1) {
|
||||
FroxlorLogger::getInstanceOf()->setCronLog(0);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function refreshUsers(int $jobcount = 0)
|
||||
{
|
||||
if ($jobcount > 0) {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
Extrausers::generateFiles(self::$cronlog);
|
||||
return;
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
|
||||
$false_val = false;
|
||||
FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function validateOwnership(OutputInterface $output)
|
||||
{
|
||||
// when using fcgid or fpm for froxlor-vhost itself, we have to check
|
||||
// whether the permission of the files are still correct
|
||||
$output->write('Checking froxlor file permissions...');
|
||||
$_mypath = FileDir::makeCorrectDir(Froxlor::getInstallDir());
|
||||
|
||||
if (((int)Settings::Get('system.mod_fcgid') == 1 && (int)Settings::Get('system.mod_fcgid_ownvhost') == 1) || ((int)Settings::Get('phpfpm.enabled') == 1 && (int)Settings::Get('phpfpm.enabled_ownvhost') == 1)) {
|
||||
$user = Settings::Get('system.mod_fcgid_httpuser');
|
||||
$group = Settings::Get('system.mod_fcgid_httpgroup');
|
||||
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
}
|
||||
// all the files and folders have to belong to the local user
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
} else {
|
||||
// back to webserver permission
|
||||
$user = Settings::Get('system.httpuser');
|
||||
$group = Settings::Get('system.httpgroup');
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
}
|
||||
$output->writeln('OK');
|
||||
}
|
||||
|
||||
private function getCronModule(string $cronname, OutputInterface $output)
|
||||
{
|
||||
$upd_stmt = Database::prepare("
|
||||
SELECT `cronclass` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `cronfile` = :cron;
|
||||
");
|
||||
$cron = Database::pexecute_first($upd_stmt, [
|
||||
'cron' => $cronname
|
||||
]);
|
||||
if ($cron) {
|
||||
return $cron['cronclass'];
|
||||
}
|
||||
$output->writeln("<error>Requested cronjob '" . $cronname . "' could not be found.</>");
|
||||
return false;
|
||||
}
|
||||
|
||||
private function lockJob(string $job, OutputInterface $output): bool
|
||||
{
|
||||
|
||||
$this->lockFile = '/run/lock/froxlor_' . $job . '.lock';
|
||||
|
||||
if (file_exists($this->lockFile)) {
|
||||
$jobinfo = json_decode(file_get_contents($this->lockFile), true);
|
||||
$check_pid_return = null;
|
||||
// get status of process
|
||||
system("kill -CHLD " . (int)$jobinfo['pid'] . " 1> /dev/null 2> /dev/null", $check_pid_return);
|
||||
if ($check_pid_return == 1) {
|
||||
// Process does not seem to run, most likely it has died
|
||||
$this->unlockJob($job);
|
||||
} else {
|
||||
// cronjob still running, output info and stop
|
||||
$output->writeln([
|
||||
'<comment>Job "' . $jobinfo['job'] . '" is currently running.',
|
||||
'Started: ' . date('d.m.Y H:i', (int) $jobinfo['startts']),
|
||||
'PID: ' . $jobinfo['pid'] . '</>'
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$jobinfo = [
|
||||
'job' => $job,
|
||||
'startts' => time(),
|
||||
'pid' => getmypid()
|
||||
];
|
||||
file_put_contents($this->lockFile, json_encode($jobinfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
private function unlockJob(string $job): bool
|
||||
{
|
||||
return @unlink($this->lockFile);
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class CronConfig
|
||||
}
|
||||
|
||||
// create entry-line
|
||||
$cronfile .= "root " . $binpath . " " . FileDir::makeCorrectFile(Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";
|
||||
$cronfile .= "root " . $binpath . " " . FileDir::makeCorrectFile(Froxlor::getInstallDir() . "/bin/froxlor-cli") . " froxlor:cron " . escapeshellarg($row_cronentry['cronfile']) . " -q 1> /dev/null\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ class CronConfig
|
||||
$newcrontab = "";
|
||||
foreach ($crontablines as $ctl) {
|
||||
$ctl = trim($ctl);
|
||||
if (!empty($ctl) && !preg_match("/(.*)froxlor_master_cronjob\.php(.*)/", $ctl)) {
|
||||
if (!empty($ctl) && !preg_match("/(.*)froxlor\:cron(.*)/", $ctl)) {
|
||||
$newcrontab .= $ctl . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,4 +42,9 @@ abstract class FroxlorCron
|
||||
{
|
||||
static::$lockfile = $lockfile;
|
||||
}
|
||||
|
||||
public static function setCronlog($cronlog = null)
|
||||
{
|
||||
static::$cronlog = $cronlog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
namespace Froxlor\Cron\Http;
|
||||
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Cron\Http\Php\PhpInterface;
|
||||
use Froxlor\Customer\Customer;
|
||||
use Froxlor\Database\Database;
|
||||
@@ -161,6 +162,27 @@ class Apache extends HttpConfigBase
|
||||
}
|
||||
|
||||
if (!$is_redirect) {
|
||||
// protect lib/userdata.inc.php
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' <Directory "' . rtrim(Froxlor::getInstallDir(), "/") . '/lib/">' . "\n";
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' <Files "userdata.inc.php">' . "\n";
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' Require all denied' . "\n";
|
||||
} else {
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' Order deny,allow' . "\n";
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' deny from all' . "\n";
|
||||
}
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' </Files>' . "\n";
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' </Directory>' . "\n";
|
||||
// protect bin/
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' <Directory "' . rtrim(Froxlor::getInstallDir(), "/") . '/bin/">' . "\n";
|
||||
if (Settings::Get('system.apache24') == '1') {
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' Require all denied' . "\n";
|
||||
} else {
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' Order deny,allow' . "\n";
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' deny from all' . "\n";
|
||||
}
|
||||
$this->virtualhosts_data[$vhosts_filename] .= ' </Directory>' . "\n";
|
||||
|
||||
// create fcgid <Directory>-Part (starter is created in apache_fcgid)
|
||||
if (Settings::Get('system.mod_fcgid_ownvhost') == '1' && Settings::Get('system.mod_fcgid') == '1') {
|
||||
$configdir = FileDir::makeCorrectDir(Settings::Get('system.mod_fcgid_configdir') . '/froxlor.panel/' . Settings::Get('system.hostname'));
|
||||
|
||||
@@ -125,6 +125,15 @@ class Lighttpd extends HttpConfigBase
|
||||
}
|
||||
|
||||
if (!$is_redirect) {
|
||||
// protect lib/userdata.inc.php
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' $HTTP["host"] =~ "' . rtrim(Froxlor::getInstallDir(), "/") . '/lib" {' . "\n";
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' url.access-deny = ("userdata.inc.php")' . "\n";
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' }' . "\n";
|
||||
// protect bin/
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' $HTTP["host"] =~ "' . rtrim(Froxlor::getInstallDir(), "/") . '/bin" {' . "\n";
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' url.access-deny = ("")' . "\n";
|
||||
$this->lighttpd_data[$vhosts_filename] .= ' }' . "\n";
|
||||
|
||||
/**
|
||||
* dirprotection, see #72
|
||||
*
|
||||
|
||||
@@ -218,15 +218,25 @@ class Nginx extends HttpConfigBase
|
||||
$this->nginx_data[$vhost_filename] .= "\t" . 'index index.php index.html index.htm;' . "\n\n";
|
||||
$this->nginx_data[$vhost_filename] .= "\t" . 'location / {' . "\n";
|
||||
$this->nginx_data[$vhost_filename] .= "\t" . '}' . "\n";
|
||||
|
||||
// protect lib/userdata.inc.php
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . 'location = ' . rtrim(Froxlor::getInstallDir(), "/") . '/lib/userdata.inc.php {' . "\n";
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . ' deny all;' . "\n";
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . '}' . "\n";
|
||||
|
||||
// protect bin/
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . 'location = ' . rtrim(Froxlor::getInstallDir(), "/") . '/bin {' . "\n";
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . ' deny all;' . "\n";
|
||||
$this->nginx_data[$vhosts_filename] .= "\t" . '}' . "\n";
|
||||
}
|
||||
|
||||
if ($row_ipsandports['specialsettings'] != '' && ($row_ipsandports['ssl'] == '0' || ($row_ipsandports['ssl'] == '1' && Settings::Get('system.use_ssl') == '1' && $row_ipsandports['include_specialsettings'] == '1'))) {
|
||||
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['specialsettings'], [
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath
|
||||
], $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath
|
||||
], $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,11 +249,11 @@ class Nginx extends HttpConfigBase
|
||||
$this->nginx_data[$vhost_filename] .= $this->composeSslSettings($row_ipsandports);
|
||||
if ($row_ipsandports['ssl_specialsettings'] != '') {
|
||||
$this->nginx_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], [
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath
|
||||
], $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
|
||||
'domain' => Settings::Get('system.hostname'),
|
||||
'loginname' => Settings::Get('phpfpm.vhost_httpuser'),
|
||||
'documentroot' => $mypath,
|
||||
'customerroot' => $mypath
|
||||
], $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
use Exception;
|
||||
use Froxlor\Cron\System\Extrausers;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\System\Cronjob;
|
||||
use PDO;
|
||||
|
||||
class MasterCron extends FroxlorCron
|
||||
{
|
||||
|
||||
private static $argv = null;
|
||||
|
||||
private static $debugHandler = null;
|
||||
|
||||
private static $noncron_params = [
|
||||
'force',
|
||||
'debug',
|
||||
'no-fork',
|
||||
'run-task'
|
||||
];
|
||||
|
||||
public static function setArguments($argv = null)
|
||||
{
|
||||
self::$argv = $argv;
|
||||
}
|
||||
|
||||
public static function run()
|
||||
{
|
||||
self::init();
|
||||
|
||||
$jobs_to_run = [];
|
||||
|
||||
$argv = self::$argv;
|
||||
/**
|
||||
* check for --help
|
||||
*/
|
||||
if (count($argv) < 2 || (isset($argv[1]) && strtolower($argv[1]) == '--help')) {
|
||||
echo "\n*** Froxlor Master Cronjob ***\n\n";
|
||||
echo "Below are possible parameters for this file\n\n";
|
||||
echo "--[cronname]\t\tincludes the given cron-file\n";
|
||||
echo "--force\t\t\tforces re-generating of config-files (webserver, nameserver, etc.)\n";
|
||||
echo "--run-task\t\trun a specific task [1 = re-generate configs, 4 = re-generate dns zones, 10 = re-set quotas, 99 = re-create cron.d-file]\n";
|
||||
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
|
||||
echo "--no-fork\t\tdo not fork to backkground (traffic cron only).\n\n";
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* check for parameters
|
||||
*
|
||||
* --[cronname] include [cronname]
|
||||
* --force to include cron_tasks even if it's not its turn
|
||||
* --debug to output debug information
|
||||
*/
|
||||
for ($x = 1; $x < count($argv); $x++) {
|
||||
// check argument
|
||||
if (isset($argv[$x])) {
|
||||
// --force
|
||||
if (strtolower($argv[$x]) == '--force') {
|
||||
// really force re-generating of config-files by
|
||||
// inserting task 1
|
||||
Cronjob::inserttask(TaskId::REBUILD_VHOST);
|
||||
// bind (if enabled, \Froxlor\System\Cronjob::inserttask() checks this)
|
||||
Cronjob::inserttask(TaskId::REBUILD_DNS);
|
||||
// set quotas (if enabled)
|
||||
Cronjob::inserttask(TaskId::CREATE_QUOTA);
|
||||
// also regenerate cron.d-file
|
||||
Cronjob::inserttask(TaskId::REBUILD_CRON);
|
||||
array_push($jobs_to_run, 'tasks');
|
||||
define('CRON_IS_FORCED', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--debug') {
|
||||
define('CRON_DEBUG_FLAG', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--no-fork') {
|
||||
define('CRON_NOFORK_FLAG', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--run-task') {
|
||||
if (isset($argv[$x + 1]) && in_array($argv[$x + 1], [1, 4, 10, 99])) {
|
||||
Cronjob::inserttask($argv[$x + 1]);
|
||||
array_push($jobs_to_run, 'tasks');
|
||||
} else {
|
||||
echo "Invalid argument for --run-task\n";
|
||||
exit;
|
||||
}
|
||||
} elseif (substr(strtolower($argv[$x]), 0, 2) == '--') {
|
||||
// --[cronname]
|
||||
if (strlen($argv[$x]) > 3) {
|
||||
$cronname = substr(strtolower($argv[$x]), 2);
|
||||
array_push($jobs_to_run, $cronname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$jobs_to_run = array_unique($jobs_to_run);
|
||||
|
||||
self::$cronlog->setCronDebugFlag(defined('CRON_DEBUG_FLAG'));
|
||||
|
||||
$tasks_cnt_stmt = Database::query("SELECT COUNT(*) as jobcnt FROM `panel_tasks`");
|
||||
$tasks_cnt = $tasks_cnt_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// do we have anything to include?
|
||||
if (count($jobs_to_run) > 0) {
|
||||
// include all jobs we want to execute
|
||||
foreach ($jobs_to_run as $cron) {
|
||||
Cronjob::updateLastRunOfCron($cron);
|
||||
$cronfile = self::getCronModule($cron);
|
||||
if ($cronfile && class_exists($cronfile)) {
|
||||
$cronfile::run();
|
||||
}
|
||||
}
|
||||
self::refreshUsers($tasks_cnt['jobcnt']);
|
||||
}
|
||||
|
||||
/**
|
||||
* we have to check the system's last guid with every cron run
|
||||
* in case the admin installed new software which added a new user
|
||||
* so users in the database don't conflict with system users
|
||||
*/
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Checking system\'s last guid');
|
||||
Cronjob::checkLastGuid();
|
||||
|
||||
// shutdown cron
|
||||
self::shutdown();
|
||||
}
|
||||
|
||||
private static function init()
|
||||
{
|
||||
if (@php_sapi_name() != 'cli' && @php_sapi_name() != 'cgi' && @php_sapi_name() != 'cgi-fcgi') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
// ensure that default timezone is set
|
||||
if (function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get")) {
|
||||
@date_default_timezone_set(@date_default_timezone_get());
|
||||
}
|
||||
|
||||
$basename = basename($_SERVER['PHP_SELF'], '.php');
|
||||
$crontype = "";
|
||||
if (isset(self::$argv) && is_array(self::$argv) && count(self::$argv) > 1) {
|
||||
for ($x = 1; $x < count(self::$argv); $x++) {
|
||||
if (substr(self::$argv[$x], 0, 2) == '--' && strlen(self::$argv[$x]) > 3 && !in_array(substr(strtolower(self::$argv[$x]), 2), self::$noncron_params)) {
|
||||
$crontype = substr(strtolower(self::$argv[$x]), 2);
|
||||
$basename .= "-" . $crontype;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$lockdir = '/var/run/';
|
||||
$lockFilename = 'froxlor_' . $basename . '.lock-';
|
||||
$lockfName = $lockFilename . getmypid();
|
||||
$lockfile = $lockdir . $lockfName;
|
||||
self::setLockfile($lockfile);
|
||||
|
||||
// create and open the lockfile!
|
||||
self::$debugHandler = fopen($lockfile, 'w');
|
||||
fwrite(self::$debugHandler, 'Setting Lockfile to ' . $lockfile . "\n");
|
||||
fwrite(self::$debugHandler, 'Setting Froxlor installation path to ' . Froxlor::getInstallDir() . "\n");
|
||||
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/lib/userdata.inc.php')) {
|
||||
die("Froxlor does not seem to be installed yet - skipping cronjob");
|
||||
}
|
||||
|
||||
$sql = [];
|
||||
$sql_root = [];
|
||||
// Includes the Usersettings eg. MySQL-Username/Passwort etc.
|
||||
require Froxlor::getInstallDir() . '/lib/userdata.inc.php';
|
||||
fwrite(self::$debugHandler, 'Userdatas included' . "\n");
|
||||
|
||||
// Legacy sql-root-information
|
||||
if (isset($sql['root_user']) && isset($sql['root_password']) && (!isset($sql_root) || !is_array($sql_root))) {
|
||||
$sql_root = [
|
||||
0 => [
|
||||
'caption' => 'Default',
|
||||
'host' => $sql['host'],
|
||||
'user' => $sql['root_user'],
|
||||
'password' => $sql['root_password']
|
||||
]
|
||||
];
|
||||
unset($sql['root_user']);
|
||||
unset($sql['root_password']);
|
||||
}
|
||||
|
||||
require Froxlor::getInstallDir() . '/lib/functions.php';
|
||||
// Includes the MySQL-Tabledefinitions etc.
|
||||
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
fwrite(self::$debugHandler, 'Table definitions included' . "\n");
|
||||
|
||||
// try database connection, it will throw
|
||||
// and exception itself if failed
|
||||
try {
|
||||
Database::query("SELECT 1");
|
||||
} catch (Exception $e) {
|
||||
// Do not proceed further if no database connection could be established
|
||||
fclose(self::$debugHandler);
|
||||
unlink($lockfile);
|
||||
die($e->getMessage());
|
||||
}
|
||||
|
||||
fwrite(self::$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(self::$debugHandler);
|
||||
unlink($lockfile);
|
||||
Cronjob::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(strrchr($fName, "-"), 1);
|
||||
$check_pid_return = null;
|
||||
system("kill -CHLD " . (int)$check_pid . " 1> /dev/null 2> /dev/null", $check_pid_return);
|
||||
|
||||
if ($check_pid_return == 1) {
|
||||
// Result: Existing lockfile/pid isn't running
|
||||
// Most likely it has died
|
||||
//
|
||||
// Action: Remove it and continue
|
||||
//
|
||||
fwrite(self::$debugHandler, 'Previous cronjob didn\'t exit clean. PID: ' . $check_pid . "\n");
|
||||
fwrite(self::$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(self::$debugHandler);
|
||||
|
||||
// ... and delete it
|
||||
unlink($lockfile);
|
||||
Cronjob::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
|
||||
*/
|
||||
fwrite(self::$debugHandler, 'Checking froxlor file permissions' . "\n");
|
||||
$_mypath = FileDir::makeCorrectDir(Froxlor::getInstallDir());
|
||||
|
||||
if (((int)Settings::Get('system.mod_fcgid') == 1 && (int)Settings::Get('system.mod_fcgid_ownvhost') == 1) || ((int)Settings::Get('phpfpm.enabled') == 1 && (int)Settings::Get('phpfpm.enabled_ownvhost') == 1)) {
|
||||
$user = Settings::Get('system.mod_fcgid_httpuser');
|
||||
$group = Settings::Get('system.mod_fcgid_httpgroup');
|
||||
|
||||
if (Settings::Get('phpfpm.enabled') == 1) {
|
||||
$user = Settings::Get('phpfpm.vhost_httpuser');
|
||||
$group = Settings::Get('phpfpm.vhost_httpgroup');
|
||||
}
|
||||
// all the files and folders have to belong to the local user
|
||||
// now because we also use fcgid for our own vhost
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
} else {
|
||||
// back to webserver permission
|
||||
$user = Settings::Get('system.httpuser');
|
||||
$group = Settings::Get('system.httpgroup');
|
||||
FileDir::safe_exec('chown -R ' . $user . ':' . $group . ' ' . escapeshellarg($_mypath));
|
||||
}
|
||||
|
||||
// Initialize logging
|
||||
self::$cronlog = FroxlorLogger::getInstanceOf([
|
||||
'loginname' => 'cronjob'
|
||||
]);
|
||||
fwrite(self::$debugHandler, 'Logger has been included' . "\n");
|
||||
|
||||
if (Froxlor::hasUpdates() || Froxlor::hasDbUpdates()) {
|
||||
if (Settings::Get('system.cron_allowautoupdate') == null || Settings::Get('system.cron_allowautoupdate') == 0) {
|
||||
/**
|
||||
* Do not proceed further if the Database version is not the same as the script version
|
||||
*/
|
||||
fclose(self::$debugHandler);
|
||||
unlink($lockfile);
|
||||
$errormessage = "Version of file doesn't match version of database. Exiting...\n\n";
|
||||
$errormessage .= "Possible reason: Froxlor update\n";
|
||||
$errormessage .= "Information: Current version in database: " . Settings::Get('panel.version') . (!empty(Froxlor::BRANDING) ? "-" . Froxlor::BRANDING : "") . " (DB: " . Settings::Get('panel.db_version') . ") - version of Froxlor files: " . Froxlor::getVersionString() . ")\n";
|
||||
$errormessage .= "Solution: Please visit your Foxlor admin interface for further information.\n";
|
||||
Cronjob::dieWithMail($errormessage);
|
||||
}
|
||||
|
||||
if (Settings::Get('system.cron_allowautoupdate') == 1) {
|
||||
/**
|
||||
* let's walk the walk - do the dangerous shit
|
||||
*/
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update is activated and we are going to proceed without any notices');
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'all new settings etc. will be stored with the default value, that might not always be right for your system!');
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "If you don't want this to happen in the future consider removing the --allow-autoupdate flag from the cronjob");
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - Automatic update is activated and we are going to proceed without any notices' . "\n");
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - all new settings etc. will be stored with the default value, that might not always be right for your system!' . "\n");
|
||||
fwrite(self::$debugHandler, "*** WARNING *** - If you don't want this to happen in the future consider removing the --allow-autoupdate flag from the cronjob\n");
|
||||
// including update procedures
|
||||
define('_CRON_UPDATE', 1);
|
||||
include_once Froxlor::getInstallDir() . '/install/updatesql.php';
|
||||
// pew - everything went better than expected
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, 'Automatic update done - you should check your settings to be sure everything is fine');
|
||||
fwrite(self::$debugHandler, '*** WARNING *** - Automatic update done - you should check your settings to be sure everything is fine' . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(self::$debugHandler, 'Froxlor version and database version are correct' . "\n");
|
||||
}
|
||||
|
||||
private static function getCronModule($cronname)
|
||||
{
|
||||
$upd_stmt = Database::prepare("
|
||||
SELECT `cronclass` FROM `" . TABLE_PANEL_CRONRUNS . "` WHERE `cronfile` = :cron;
|
||||
");
|
||||
$cron = Database::pexecute_first($upd_stmt, [
|
||||
'cron' => $cronname
|
||||
]);
|
||||
if ($cron) {
|
||||
return $cron['cronclass'];
|
||||
}
|
||||
self::$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Requested cronjob '" . $cronname . "' could not be found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function refreshUsers($jobcount = 0)
|
||||
{
|
||||
if ($jobcount > 0) {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
Extrausers::generateFiles(self::$cronlog);
|
||||
}
|
||||
|
||||
// clear NSCD cache if using fcgid or fpm, #1570 - not needed for nss-extrausers
|
||||
if ((Settings::Get('system.mod_fcgid') == 1 || (int)Settings::Get('phpfpm.enabled') == 1) && Settings::Get('system.nssextrausers') == 0) {
|
||||
$false_val = false;
|
||||
FileDir::safe_exec('nscd -i passwd 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
FileDir::safe_exec('nscd -i group 1> /dev/null', $false_val, [
|
||||
'>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function shutdown()
|
||||
{
|
||||
// check for cron.d-generation task and create it if necessary
|
||||
CronConfig::checkCrondConfigurationFile();
|
||||
|
||||
if (Settings::Get('logger.log_cron') == '1') {
|
||||
FroxlorLogger::getInstanceOf()->setCronLog(0);
|
||||
fwrite(self::$debugHandler, 'Logging for cron has been shutdown' . "\n");
|
||||
}
|
||||
|
||||
fclose(self::$debugHandler);
|
||||
|
||||
if (Settings::Get('system.debug_cron') != '1') {
|
||||
unlink(self::getLockfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,30 +258,28 @@ class FroxlorLogger
|
||||
/**
|
||||
* Set whether to log cron-runs
|
||||
*
|
||||
* @param bool $_cronlog
|
||||
* @param int $cronlog
|
||||
*
|
||||
* @return boolean
|
||||
* @return int
|
||||
*/
|
||||
public function setCronLog($_cronlog = 0)
|
||||
public function setCronLog(int $cronlog = 0)
|
||||
{
|
||||
$_cronlog = (int)$_cronlog;
|
||||
|
||||
if ($_cronlog < 0 || $_cronlog > 2) {
|
||||
$_cronlog = 0;
|
||||
if ($cronlog < 0 || $cronlog > 2) {
|
||||
$cronlog = 0;
|
||||
}
|
||||
Settings::Set('logger.log_cron', $_cronlog);
|
||||
return $_cronlog;
|
||||
Settings::Set('logger.log_cron', $cronlog);
|
||||
return $cronlog;
|
||||
}
|
||||
|
||||
/**
|
||||
* setter for crondebug-flag
|
||||
*
|
||||
* @param bool $_flag
|
||||
* @param bool $flag
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCronDebugFlag($_flag = false)
|
||||
public function setCronDebugFlag(bool $flag = false)
|
||||
{
|
||||
self::$crondebug_flag = (bool)$_flag;
|
||||
self::$crondebug_flag = $flag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ class Linker
|
||||
}
|
||||
|
||||
// Encode parameters and add them to the link
|
||||
$link .= urlencode($key) . (!empty($value) ? '=' . urlencode($value) : '');
|
||||
$link .= urlencode($key) . ($value !== "" ? '=' . urlencode($value) : '');
|
||||
}
|
||||
|
||||
// Reset our class for further use
|
||||
|
||||
@@ -4646,7 +4646,7 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- PHP-FPM -->
|
||||
<daemon name="php-fpm"
|
||||
@@ -4679,12 +4679,12 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>bin/froxlor-cli froxlor:cron --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
|
||||
@@ -4857,7 +4857,7 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- PHP-FPM -->
|
||||
<daemon name="php-fpm"
|
||||
@@ -4890,12 +4890,12 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>bin/froxlor-cli froxlor:cron --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
|
||||
@@ -4848,7 +4848,7 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- PHP-FPM -->
|
||||
<daemon name="php-fpm"
|
||||
@@ -4881,12 +4881,12 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>bin/froxlor-cli froxlor:cron --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
|
||||
@@ -4071,7 +4071,7 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- PHP-FPM -->
|
||||
<daemon name="php-fpm"
|
||||
@@ -4104,12 +4104,12 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>bin/froxlor-cli froxlor:cron --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
|
||||
@@ -3859,7 +3859,7 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- PHP-FPM -->
|
||||
<daemon name="php-fpm"
|
||||
@@ -3903,12 +3903,12 @@ aliases: files
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>bin/froxlor-cli froxlor:cron --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
|
||||
16
lib/init.php
16
lib/init.php
@@ -62,6 +62,7 @@ use Froxlor\UI\Linker;
|
||||
use Froxlor\UI\Panel\UI;
|
||||
use Froxlor\UI\Request;
|
||||
use Froxlor\UI\Response;
|
||||
use Froxlor\Install\Update;
|
||||
|
||||
// include MySQL-tabledefinitions
|
||||
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
@@ -153,13 +154,14 @@ UI::setLinker($linker);
|
||||
/**
|
||||
* Global Theme-variable
|
||||
*/
|
||||
$theme = (Settings::Get('panel.default_theme') !== null) ? Settings::Get('panel.default_theme') : $_deftheme;
|
||||
|
||||
/**
|
||||
* Overwrite with customer/admin theme if defined
|
||||
*/
|
||||
if (CurrentUser::hasSession() && CurrentUser::getField('theme') != $theme) {
|
||||
$theme = CurrentUser::getField('theme');
|
||||
if (Update::versionInUpdate(Settings::Get('panel.version'), '0.11.0-dev1')) {
|
||||
$theme = $_deftheme;
|
||||
} else {
|
||||
$theme = (Settings::Get('panel.default_theme') !== null) ? Settings::Get('panel.default_theme') : $_deftheme;
|
||||
// Overwrite with customer/admin theme if defined
|
||||
if (CurrentUser::hasSession() && CurrentUser::getField('theme') != $theme) {
|
||||
$theme = CurrentUser::getField('theme');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a different variant of the theme is used
|
||||
|
||||
@@ -1559,12 +1559,6 @@ Vielen Dank, Ihr Administrator',
|
||||
'title' => 'Erlaube Verschieben von Domains unter Kunden',
|
||||
'description' => 'Wenn diese Option aktiviert ist, kann unter Domaineinstellungen die Domain einem anderen Kunden zugewiesen werden.<br /><b>Achtung:</b> Der Dokumenten-Pfad der Domain wird auf den Heimatpfad (+ Domain-Ordner, sofern aktiviert) des neuen Kunden gesetzt.',
|
||||
],
|
||||
'cron' => [
|
||||
'debug' => [
|
||||
'title' => 'Debuggen des Cronscripts',
|
||||
'description' => 'Wenn aktiviert, wird die Lockdatei nach dem Cronlauf zum Debuggen nicht gelöscht<br /><b>Achtung:</b> Eine alte Lockdatei kann weitere Cronjobs behindern und dafür sorgen, dass diese nicht vollständig ausgeführt werden.',
|
||||
],
|
||||
],
|
||||
'specialsettingsforsubdomains' => [
|
||||
'description' => 'Wenn ja, werden die individuellen Einstellungen für alle Subdomains übernommen.<br />Wenn nein, werden Subdomain-Specialsettings entfernt.',
|
||||
],
|
||||
|
||||
@@ -1935,12 +1935,6 @@ Yours sincerely, your administrator',
|
||||
'title' => 'Allow moving domains between customers',
|
||||
'description' => 'If activated you can change the customer of a domain at domainsettings.<br /><b>Attention:</b> Froxlor changes the documentroot to the new customer\'s default homedir (+ domain-folder if activated)',
|
||||
],
|
||||
'cron' => [
|
||||
'debug' => [
|
||||
'title' => 'Cronscript debugging',
|
||||
'description' => 'Activate to keep the lockfile after a cron-run for debugging.<br /><b>Attention:</b>Keeping the lockfile can cause the next scheduled cron not to run properly.',
|
||||
],
|
||||
],
|
||||
'specialsettingsforsubdomains' => [
|
||||
'description' => 'If yes these custom vHost-settings will be added to all subdomains; if no subdomain-specialsettings are being removed.',
|
||||
],
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can also view it online at
|
||||
* https://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright the authors
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
// validate correct php version
|
||||
if (version_compare("7.4.0", PHP_VERSION, ">=")) {
|
||||
die('Froxlor requires at least php-7.4. Please validate that your php-cli version and the cron execution command are correct.');
|
||||
}
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
\Froxlor\Cron\MasterCron::setArguments($argv);
|
||||
\Froxlor\Cron\MasterCron::run();
|
||||
Reference in New Issue
Block a user