X Tutup
Skip to content

Commit e0bf50f

Browse files
Merge pull request #34932 from owncloud/stable10-tech-dept/json.php
[stable10] Have a real controller handling cron requests
2 parents 568e9d9 + 64b1887 commit e0bf50f

File tree

9 files changed

+457
-123
lines changed

9 files changed

+457
-123
lines changed

core/Application.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
use OC\AppFramework\Utility\TimeFactory;
3333
use OC\Core\Controller\AvatarController;
3434
use OC\Core\Controller\CloudController;
35+
use OC\Core\Controller\CronController;
3536
use OC\Core\Controller\LoginController;
3637
use OC\Core\Controller\LostController;
3738
use OC\Core\Controller\TokenController;
3839
use OC\Core\Controller\TwoFactorChallengeController;
3940
use OC\Core\Controller\UserController;
4041
use OC_Defaults;
4142
use OCP\AppFramework\App;
43+
use OCP\BackgroundJob\IJobList;
44+
use OCP\IConfig;
45+
use OCP\ILogger;
4246
use OCP\IServerContainer;
4347
use OCP\Util;
4448

@@ -138,6 +142,15 @@ public function __construct(array $urlParams= []) {
138142
$c->query('Request')
139143
);
140144
});
145+
$container->registerService('CronController', function (SimpleContainer $c) {
146+
return new CronController(
147+
$c->query('AppName'),
148+
$c->query('Request'),
149+
$c->query(IConfig::class),
150+
$c->query(ILogger::class),
151+
$c->query(IJobList::class)
152+
);
153+
});
141154

142155
/**
143156
* Core class wrappers

core/Command/System/Cron.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
/**
3+
* @author Thomas Müller <thomas.mueller@tmit.eu>
4+
*
5+
* @copyright Copyright (c) 2018, ownCloud GmbH
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
22+
namespace OC\Core\Command\System;
23+
24+
use OCP\BackgroundJob\IJobList;
25+
use OCP\IConfig;
26+
use OCP\ILogger;
27+
use OCP\ITempManager;
28+
use Symfony\Component\Console\Command\Command;
29+
use Symfony\Component\Console\Helper\ProgressBar;
30+
use Symfony\Component\Console\Input\InputInterface;
31+
use Symfony\Component\Console\Output\OutputInterface;
32+
33+
class Cron extends Command {
34+
35+
/** @var \OCP\BackgroundJob\IJobList */
36+
private $jobList;
37+
/** @var IConfig */
38+
private $config;
39+
/** @var ILogger */
40+
private $logger;
41+
/** @var ITempManager */
42+
private $tempManager;
43+
44+
/**
45+
* Cron constructor.
46+
*
47+
* @param IJobList $jobList
48+
* @param IConfig $config
49+
* @param ILogger $logger
50+
* @param ITempManager $tempManager
51+
*/
52+
public function __construct(IJobList $jobList,
53+
IConfig $config,
54+
ILogger $logger,
55+
ITempManager $tempManager) {
56+
$this->jobList = $jobList;
57+
$this->config = $config;
58+
$this->logger = $logger;
59+
$this->tempManager = $tempManager;
60+
parent::__construct();
61+
}
62+
63+
protected function configure() {
64+
$this
65+
->setName('system:cron')
66+
->setDescription('Execute background jobs as cron');
67+
}
68+
69+
/**
70+
* @param InputInterface $input
71+
* @param OutputInterface $output
72+
* @return int
73+
*/
74+
protected function execute(InputInterface $input, OutputInterface $output) {
75+
if (\OCP\Util::needUpgrade()) {
76+
$output->writeln('Update required, skipping cron');
77+
return 1;
78+
}
79+
if ($this->config->getSystemValue('maintenance', false)) {
80+
$output->writeln('We are in maintenance mode, skipping cron');
81+
return 1;
82+
}
83+
if ($this->config->getSystemValue('singleuser', false)) {
84+
$output->writeln('We are in admin only mode, skipping cron');
85+
return 1;
86+
}
87+
88+
// clean the temp folder
89+
$this->tempManager->cleanOld();
90+
91+
// Exit if background jobs are disabled!
92+
$appMode = $this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax');
93+
if ($appMode === 'none') {
94+
$output->writeln('Background Jobs are disabled!');
95+
return 1;
96+
}
97+
98+
// We call ownCloud from the CLI (aka cron)
99+
if ($appMode !== 'cron') {
100+
$this->config->setAppValue('core', 'backgroundjobs_mode', 'cron');
101+
}
102+
103+
$progress = new ProgressBar($output);
104+
105+
// We only ask for jobs for 14 minutes, because after 15 minutes the next
106+
// system cron task should spawn.
107+
$endTime = \time() + 14 * 60;
108+
109+
$executedJobs = [];
110+
while ($job = $this->jobList->getNext()) {
111+
if (isset($executedJobs[$job->getId()])) {
112+
$this->jobList->unlockJob($job);
113+
break;
114+
}
115+
$progress->advance();
116+
$jobName = \get_class($job);
117+
$progress->setMessage("Executing: {$job->getId()} - {$jobName}");
118+
119+
$job->execute($this->jobList, $this->logger);
120+
121+
// clean up after unclean jobs
122+
\OC_Util::tearDownFS();
123+
124+
$this->jobList->setLastJob($job);
125+
$executedJobs[$job->getId()] = true;
126+
unset($job);
127+
128+
if (\time() > $endTime) {
129+
break;
130+
}
131+
}
132+
133+
// Log the successful cron execution
134+
if ($this->config->getSystemValue('cron_log', true)) {
135+
$this->config->setAppValue('core', 'lastcron', \time());
136+
}
137+
$output->writeln('');
138+
139+
return 0;
140+
}
141+
}

core/Controller/CronController.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* @author Thomas Müller <thomas.mueller@tmit.eu>
4+
*
5+
* @copyright Copyright (c) 2018, ownCloud GmbH
6+
* @license AGPL-3.0
7+
*
8+
* This code is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU Affero General Public License, version 3,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU Affero General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License, version 3,
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>
19+
*
20+
*/
21+
22+
namespace OC\Core\Controller;
23+
24+
use OCP\AppFramework\Controller;
25+
use OCP\AppFramework\Http\JSONResponse;
26+
use OCP\BackgroundJob\IJobList;
27+
use OCP\IConfig;
28+
use OCP\IRequest;
29+
use OCP\ILogger;
30+
31+
class CronController extends Controller {
32+
33+
/** @var IConfig */
34+
private $config;
35+
/** @var ILogger */
36+
private $logger;
37+
/** @var IJobList */
38+
private $jobList;
39+
40+
/**
41+
* CronController constructor.
42+
*
43+
* @param string $appName
44+
* @param IRequest $request
45+
* @param IConfig $config
46+
* @param ILogger $logger
47+
* @param IJobList $jobList
48+
*/
49+
public function __construct($appName, IRequest $request,
50+
IConfig $config,
51+
ILogger $logger,
52+
IJobList $jobList) {
53+
parent::__construct($appName, $request);
54+
$this->config = $config;
55+
$this->logger = $logger;
56+
$this->jobList = $jobList;
57+
}
58+
59+
/**
60+
* @PublicPage
61+
* @NoCSRFRequired
62+
*
63+
* @return JSONResponse
64+
* @throws \Exception
65+
*/
66+
public function run(): JSONResponse {
67+
// Exit if background jobs are disabled!
68+
$appMode = $this->config->getAppValue('core', 'backgroundjobs_mode', 'ajax');
69+
if ($appMode === 'none') {
70+
return new JSONResponse(['data' => ['message' => 'Background jobs disabled!']]);
71+
}
72+
73+
// We call cron.php from some website
74+
if ($appMode === 'cron') {
75+
return new JSONResponse(['data' => ['message' => 'Background jobs are using system cron!']]);
76+
}
77+
78+
// Work and success :-)
79+
$job = $this->jobList->getNext();
80+
if ($job !== null) {
81+
$job->execute($this->jobList, $this->logger);
82+
$this->jobList->setLastJob($job);
83+
}
84+
85+
// Log the successful cron execution
86+
if ($this->config->getSystemValue('cron_log', true)) {
87+
$this->config->setAppValue('core', 'lastcron', \time());
88+
}
89+
90+
return new JSONResponse();
91+
}
92+
}

core/register_command.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
177177
$application->add(new OC\Core\Command\Security\RemoveCertificate(\OC::$server->getCertificateManager(null)));
178178
$application->add(new OC\Core\Command\Security\ListRoutes(\OC::$server->getRouter()));
179+
$application->add(new OC\Core\Command\System\Cron(\OC::$server->getJobList(), \OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getTempManager()));
179180
} else {
180181
$application->add(new OC\Core\Command\Maintenance\Install(\OC::$server->getConfig()));
181182
}

core/routes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
5252
['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
5353
['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
54+
['name' => 'Cron#run', 'url' => '/cron', 'verb' => 'GET'],
5455
],
5556
'ocs' => [
5657
['root' => '/cloud', 'name' => 'Cloud#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],

0 commit comments

Comments
 (0)
X Tutup