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

80
			/** @scrutinizer ignore-deprecated */ OC_JSON::error(array('data' => array('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...
81
		}
82
		exit(1);
83
	}
84
85
	if (OC::$CLI) {
86
		// set to run indefinitely if needed
87
		if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
88
			@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

88
			/** @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...
89
		}
90
91
		// the cron job must be executed with the right user
92
		if (!function_exists('posix_getuid')) {
93
			echo "The posix extensions are required - see http://php.net/manual/en/book.posix.php" . PHP_EOL;
94
			exit(1);
95
		}
96
97
		$user = posix_getpwuid(posix_getuid());
98
		$configUser = posix_getpwuid(fileowner(OC::$configDir . 'config.php'));
99
		if ($user['name'] !== $configUser['name']) {
100
			echo "Console has to be executed with the user that owns the file config/config.php" . PHP_EOL;
101
			echo "Current user: " . $user['name'] . PHP_EOL;
102
			echo "Owner of config.php: " . $configUser['name'] . PHP_EOL;
103
			exit(1);
104
		}
105
106
		// We call Nextcloud from the CLI (aka cron)
107
		if ($appMode !== 'cron') {
108
			$config->setAppValue('core', 'backgroundjobs_mode', 'cron');
109
		}
110
111
		// Work
112
		$jobList = \OC::$server->getJobList();
113
114
		// We only ask for jobs for 14 minutes, because after 5 minutes the next
115
		// system cron task should spawn and we want to have at most three
116
		// cron jobs running in parallel.
117
		$endTime = time() + 14 * 60;
118
119
		$executedJobs = [];
120
		while ($job = $jobList->getNext()) {
121
			if (isset($executedJobs[$job->getId()])) {
122
				$jobList->unlockJob($job);
123
				break;
124
			}
125
126
			$job->execute($jobList, $logger);
127
			// clean up after unclean jobs
128
			\OC_Util::tearDownFS();
129
130
			$jobList->setLastJob($job);
131
			$executedJobs[$job->getId()] = true;
132
			unset($job);
133
134
			if (time() > $endTime) {
135
				break;
136
			}
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(array('data' => array('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(array('data' => array('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
160
} catch (Exception $ex) {
161
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
162
} catch (Error $ex) {
163
	\OC::$server->getLogger()->logException($ex, ['app' => 'cron']);
164
}
165