Passed
Push — master ( ed5661...51c9fd )
by Robin
09:54 queued 11s
created
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Artem Sidorenko <[email protected]>
6
 * @author Bernhard Posselt <[email protected]>
7
 * @author Christopher Schäpers <[email protected]>
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Damjan Georgievski <[email protected]>
10
 * @author Daniel Kesselberg <[email protected]>
11
 * @author Jakob Sack <[email protected]>
12
 * @author Joas Schilling <[email protected]>
13
 * @author Jörn Friedrich Dreyer <[email protected]>
14
 * @author Ko- <[email protected]>
15
 * @author Michael Kuhn <[email protected]>
16
 * @author Morris Jobke <[email protected]>
17
 * @author Oliver Kohl D.Sc. <[email protected]>
18
 * @author Robin Appelman <[email protected]>
19
 * @author Roeland Jago Douma <[email protected]>
20
 * @author Steffen Lindner <[email protected]>
21
 * @author Thomas Müller <[email protected]>
22
 * @author Vincent Petry <[email protected]>
23
 *
24
 * @license AGPL-3.0
25
 *
26
 * This code is free software: you can redistribute it and/or modify
27
 * it under the terms of the GNU Affero General Public License, version 3,
28
 * as published by the Free Software Foundation.
29
 *
30
 * This program is distributed in the hope that it will be useful,
31
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33
 * GNU Affero General Public License for more details.
34
 *
35
 * You should have received a copy of the GNU Affero General Public License, version 3,
36
 * along with this program. If not, see <http://www.gnu.org/licenses/>
37
 *
38
 */
39
40
require_once __DIR__ . '/lib/versioncheck.php';
41
42
try {
43
	require_once __DIR__ . '/lib/base.php';
44
45
	if (\OCP\Util::needUpgrade()) {
46
		\OC::$server->getLogger()->debug('Update required, skipping cron', ['app' => 'cron']);
47
		exit;
48
	}
49
	if ((bool) \OC::$server->getSystemConfig()->getValue('maintenance', false)) {
50
		\OC::$server->getLogger()->debug('We are in maintenance mode, skipping cron', ['app' => 'cron']);
51
		exit;
52
	}
53
54
	// load all apps to get all api routes properly setup
55
	OC_App::loadApps();
56
57
	\OC::$server->getSession()->close();
58
59
	// initialize a dummy memory session
60
	$session = new \OC\Session\Memory('');
61
	$cryptoWrapper = \OC::$server->getSessionCryptoWrapper();
62
	$session = $cryptoWrapper->wrapSession($session);
63
	\OC::$server->setSession($session);
64
65
	$logger = \OC::$server->getLogger();
66
	$config = \OC::$server->getConfig();
67
68
	// Don't do anything if Nextcloud has not been installed
69
	if (!$config->getSystemValue('installed', false)) {
70
		exit(0);
71
	}
72
73
	\OC::$server->getTempManager()->cleanOld();
74
75
	// Exit if background jobs are disabled!
76
	$appMode = $config->getAppValue('core', 'backgroundjobs_mode', 'ajax');
77
	if ($appMode === 'none') {
78
		if (OC::$CLI) {
79
			echo 'Background Jobs are disabled!' . PHP_EOL;
80
		} else {
81
			OC_JSON::error(['data' => ['message' => 'Background jobs disabled!']]);
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::error() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

81
			/** @scrutinizer ignore-deprecated */ OC_JSON::error(['data' => ['message' => 'Background jobs disabled!']]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
82
		}
83
		exit(1);
84
	}
85
86
	if (OC::$CLI) {
87
		// set to run indefinitely if needed
88
		if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
89
			@set_time_limit(0);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_time_limit(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

89
			/** @scrutinizer ignore-unhandled */ @set_time_limit(0);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
90
		}
91
92
		// the cron job must be executed with the right user
93
		if (!function_exists('posix_getuid')) {
94
			echo "The posix extensions are required - see http://php.net/manual/en/book.posix.php" . PHP_EOL;
95
			exit(1);
96
		}
97
98
		$user = posix_getpwuid(posix_getuid());
99
		$configUser = posix_getpwuid(fileowner(OC::$configDir . 'config.php'));
100
		if ($user['name'] !== $configUser['name']) {
101
			echo "Console has to be executed with the user that owns the file config/config.php" . PHP_EOL;
102
			echo "Current user: " . $user['name'] . PHP_EOL;
103
			echo "Owner of config.php: " . $configUser['name'] . PHP_EOL;
104
			exit(1);
105
		}
106
107
		// We call Nextcloud from the CLI (aka cron)
108
		if ($appMode !== 'cron') {
109
			$config->setAppValue('core', 'backgroundjobs_mode', 'cron');
110
		}
111
112
		// Work
113
		$jobList = \OC::$server->getJobList();
114
115
		// We only ask for jobs for 14 minutes, because after 5 minutes the next
116
		// system cron task should spawn and we want to have at most three
117
		// cron jobs running in parallel.
118
		$endTime = time() + 14 * 60;
119
120
		$executedJobs = [];
121
		while ($job = $jobList->getNext()) {
122
			if (isset($executedJobs[$job->getId()])) {
123
				$jobList->unlockJob($job);
124
				break;
125
			}
126
127
			$job->execute($jobList, $logger);
128
			// clean up after unclean jobs
129
			\OC_Util::tearDownFS();
130
131
			$jobList->setLastJob($job);
132
			$executedJobs[$job->getId()] = true;
133
			unset($job);
134
135
			if (time() > $endTime) {
136
				break;
137
			}
138
		}
139
	} else {
140
		// We call cron.php from some website
141
		if ($appMode === 'cron') {
142
			// Cron is cron :-P
143
			OC_JSON::error(['data' => ['message' => 'Backgroundjobs are using system cron!']]);
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::error() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

143
			/** @scrutinizer ignore-deprecated */ OC_JSON::error(['data' => ['message' => 'Backgroundjobs are using system cron!']]);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
144
		} else {
145
			// Work and success :-)
146
			$jobList = \OC::$server->getJobList();
147
			$job = $jobList->getNext();
148
			if ($job != null) {
149
				$job->execute($jobList, $logger);
150
				$jobList->setLastJob($job);
151
			}
152
			OC_JSON::success();
0 ignored issues
show
Deprecated Code introduced by
The function OC_JSON::success() has been deprecated: Use a AppFramework JSONResponse instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

152
			/** @scrutinizer ignore-deprecated */ OC_JSON::success();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
153
		}
154
	}
155
156
	// Log the successful cron execution
157
	$config->setAppValue('core', 'lastcron', time());
158
	exit();
159
} catch (Exception $ex) {
160
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
161
} catch (Error $ex) {
162
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
163
}
164