Passed
Push — master ( 54e3be...fad8dd )
by Blizzz
11:55 queued 10s
created

Updater::includePreUpdate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 * @copyright Copyright (c) 2016, Lukas Reschke <[email protected]>
5
 *
6
 * @author Arthur Schiwon <[email protected]>
7
 * @author Bjoern Schiessle <[email protected]>
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Frank Karlitschek <[email protected]>
10
 * @author Georg Ehrke <[email protected]>
11
 * @author Joas Schilling <[email protected]>
12
 * @author Lukas Reschke <[email protected]>
13
 * @author Morris Jobke <[email protected]>
14
 * @author Robin Appelman <[email protected]>
15
 * @author Roeland Jago Douma <[email protected]>
16
 * @author Steffen Lindner <[email protected]>
17
 * @author Thomas Müller <[email protected]>
18
 * @author Victor Dubiniuk <[email protected]>
19
 * @author Vincent Petry <[email protected]>
20
 *
21
 * @license AGPL-3.0
22
 *
23
 * This code is free software: you can redistribute it and/or modify
24
 * it under the terms of the GNU Affero General Public License, version 3,
25
 * as published by the Free Software Foundation.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
 * GNU Affero General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU Affero General Public License, version 3,
33
 * along with this program. If not, see <http://www.gnu.org/licenses/>
34
 *
35
 */
36
37
namespace OC;
38
39
use OC\DB\MigrationService;
40
use OC\Hooks\BasicEmitter;
41
use OC\IntegrityCheck\Checker;
42
use OC_App;
43
use OCP\IConfig;
44
use OCP\ILogger;
45
use OCP\Util;
46
use Symfony\Component\EventDispatcher\GenericEvent;
47
48
/**
49
 * Class that handles autoupdating of ownCloud
50
 *
51
 * Hooks provided in scope \OC\Updater
52
 *  - maintenanceStart()
53
 *  - maintenanceEnd()
54
 *  - dbUpgrade()
55
 *  - failure(string $message)
56
 */
57
class Updater extends BasicEmitter {
0 ignored issues
show
Deprecated Code introduced by
The class OC\Hooks\BasicEmitter has been deprecated: 18.0.0 use \OCP\EventDispatcher\IEventDispatcher ( Ignorable by Annotation )

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

57
class Updater extends /** @scrutinizer ignore-deprecated */ BasicEmitter {
Loading history...
58
59
	/** @var ILogger $log */
60
	private $log;
61
62
	/** @var IConfig */
63
	private $config;
64
65
	/** @var Checker */
66
	private $checker;
67
68
	/** @var Installer */
69
	private $installer;
70
71
	private $logLevelNames = [
72
		0 => 'Debug',
73
		1 => 'Info',
74
		2 => 'Warning',
75
		3 => 'Error',
76
		4 => 'Fatal',
77
	];
78
79
	/**
80
	 * @param IConfig $config
81
	 * @param Checker $checker
82
	 * @param ILogger $log
83
	 * @param Installer $installer
84
	 */
85
	public function __construct(IConfig $config,
86
								Checker $checker,
87
								ILogger $log = null,
88
								Installer $installer) {
89
		$this->log = $log;
90
		$this->config = $config;
91
		$this->checker = $checker;
92
		$this->installer = $installer;
93
	}
94
95
	/**
96
	 * runs the update actions in maintenance mode, does not upgrade the source files
97
	 * except the main .htaccess file
98
	 *
99
	 * @return bool true if the operation succeeded, false otherwise
100
	 */
101
	public function upgrade() {
102
		$this->emitRepairEvents();
103
		$this->logAllEvents();
104
105
		$logLevel = $this->config->getSystemValue('loglevel', ILogger::WARN);
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\ILogger::WARN has been deprecated: 20.0.0 ( Ignorable by Annotation )

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

105
		$logLevel = $this->config->getSystemValue('loglevel', /** @scrutinizer ignore-deprecated */ ILogger::WARN);

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

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

Loading history...
106
		$this->emit('\OC\Updater', 'setDebugLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
107
		$this->config->setSystemValue('loglevel', ILogger::DEBUG);
0 ignored issues
show
Deprecated Code introduced by
The constant OCP\ILogger::DEBUG has been deprecated: 20.0.0 ( Ignorable by Annotation )

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

107
		$this->config->setSystemValue('loglevel', /** @scrutinizer ignore-deprecated */ ILogger::DEBUG);

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

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

Loading history...
108
109
		$wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
110
111
		if (!$wasMaintenanceModeEnabled) {
112
			$this->config->setSystemValue('maintenance', true);
113
			$this->emit('\OC\Updater', 'maintenanceEnabled');
114
		}
115
116
		// Clear CAN_INSTALL file if not on git
117
		if (\OC_Util::getChannel() !== 'git' && is_file(\OC::$configDir.'/CAN_INSTALL')) {
118
			if (!unlink(\OC::$configDir . '/CAN_INSTALL')) {
119
				$this->log->error('Could not cleanup CAN_INSTALL from your config folder. Please remove this file manually.');
120
			}
121
		}
122
123
		$installedVersion = $this->config->getSystemValue('version', '0.0.0');
124
		$currentVersion = implode('.', \OCP\Util::getVersion());
125
126
		$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, ['app' => 'core']);
127
128
		$success = true;
129
		try {
130
			$this->doUpgrade($currentVersion, $installedVersion);
131
		} catch (HintException $exception) {
132
			$this->log->logException($exception, ['app' => 'core']);
133
			$this->emit('\OC\Updater', 'failure', [$exception->getMessage() . ': ' .$exception->getHint()]);
134
			$success = false;
135
		} catch (\Exception $exception) {
136
			$this->log->logException($exception, ['app' => 'core']);
137
			$this->emit('\OC\Updater', 'failure', [get_class($exception) . ': ' .$exception->getMessage()]);
138
			$success = false;
139
		}
140
141
		$this->emit('\OC\Updater', 'updateEnd', [$success]);
142
143
		if (!$wasMaintenanceModeEnabled && $success) {
144
			$this->config->setSystemValue('maintenance', false);
145
			$this->emit('\OC\Updater', 'maintenanceDisabled');
146
		} else {
147
			$this->emit('\OC\Updater', 'maintenanceActive');
148
		}
149
150
		$this->emit('\OC\Updater', 'resetLogLevel', [ $logLevel, $this->logLevelNames[$logLevel] ]);
151
		$this->config->setSystemValue('loglevel', $logLevel);
152
		$this->config->setSystemValue('installed', true);
153
154
		return $success;
155
	}
156
157
	/**
158
	 * Return version from which this version is allowed to upgrade from
159
	 *
160
	 * @return array allowed previous versions per vendor
161
	 */
162
	private function getAllowedPreviousVersions() {
163
		// this should really be a JSON file
164
		require \OC::$SERVERROOT . '/version.php';
165
		/** @var array $OC_VersionCanBeUpgradedFrom */
166
		return $OC_VersionCanBeUpgradedFrom;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $OC_VersionCanBeUpgradedFrom seems to be never defined.
Loading history...
167
	}
168
169
	/**
170
	 * Return vendor from which this version was published
171
	 *
172
	 * @return string Get the vendor
173
	 */
174
	private function getVendor() {
175
		// this should really be a JSON file
176
		require \OC::$SERVERROOT . '/version.php';
177
		/** @var string $vendor */
178
		return (string) $vendor;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $vendor seems to be never defined.
Loading history...
179
	}
180
181
	/**
182
	 * Whether an upgrade to a specified version is possible
183
	 * @param string $oldVersion
184
	 * @param string $newVersion
185
	 * @param array $allowedPreviousVersions
186
	 * @return bool
187
	 */
188
	public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) {
189
		$version = explode('.', $oldVersion);
190
		$majorMinor = $version[0] . '.' . $version[1];
191
192
		$currentVendor = $this->config->getAppValue('core', 'vendor', '');
193
194
		// Vendor was not set correctly on install, so we have to white-list known versions
195
		if ($currentVendor === '' && isset($allowedPreviousVersions['owncloud'][$oldVersion])) {
196
			$currentVendor = 'owncloud';
197
		}
198
199
		if ($currentVendor === 'nextcloud') {
200
			return isset($allowedPreviousVersions[$currentVendor][$majorMinor])
201
				&& (version_compare($oldVersion, $newVersion, '<=') ||
202
					$this->config->getSystemValue('debug', false));
203
		}
204
205
		// Check if the instance can be migrated
206
		return isset($allowedPreviousVersions[$currentVendor][$majorMinor]) ||
207
			isset($allowedPreviousVersions[$currentVendor][$oldVersion]);
208
	}
209
210
	/**
211
	 * runs the update actions in maintenance mode, does not upgrade the source files
212
	 * except the main .htaccess file
213
	 *
214
	 * @param string $currentVersion current version to upgrade to
215
	 * @param string $installedVersion previous version from which to upgrade from
216
	 *
217
	 * @throws \Exception
218
	 */
219
	private function doUpgrade($currentVersion, $installedVersion) {
220
		// Stop update if the update is over several major versions
221
		$allowedPreviousVersions = $this->getAllowedPreviousVersions();
222
		if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) {
223
			throw new \Exception('Updates between multiple major versions and downgrades are unsupported.');
224
		}
225
226
		// Update .htaccess files
227
		try {
228
			Setup::updateHtaccess();
229
			Setup::protectDataDirectory();
230
		} catch (\Exception $e) {
231
			throw new \Exception($e->getMessage());
232
		}
233
234
		// create empty file in data dir, so we can later find
235
		// out that this is indeed an ownCloud data directory
236
		// (in case it didn't exist before)
237
		file_put_contents($this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
238
239
		// pre-upgrade repairs
240
		$repair = new Repair(Repair::getBeforeUpgradeRepairSteps(), \OC::$server->getEventDispatcher());
241
		$repair->run();
242
243
		$this->doCoreUpgrade();
244
245
		try {
246
			// TODO: replace with the new repair step mechanism https://github.com/owncloud/core/pull/24378
247
			Setup::installBackgroundJobs();
248
		} catch (\Exception $e) {
249
			throw new \Exception($e->getMessage());
250
		}
251
252
		// update all shipped apps
253
		$this->checkAppsRequirements();
254
		$this->doAppUpgrade();
255
256
		// Update the appfetchers version so it downloads the correct list from the appstore
257
		\OC::$server->getAppFetcher()->setVersion($currentVersion);
258
259
		// upgrade appstore apps
260
		$this->upgradeAppStoreApps(\OC::$server->getAppManager()->getInstalledApps());
261
		$autoDisabledApps = \OC::$server->getAppManager()->getAutoDisabledApps();
262
		$this->upgradeAppStoreApps($autoDisabledApps, true);
263
264
		// install new shipped apps on upgrade
265
		OC_App::loadApps(['authentication']);
266
		$errors = Installer::installShippedApps(true);
267
		foreach ($errors as $appId => $exception) {
268
			/** @var \Exception $exception */
269
			$this->log->logException($exception, ['app' => $appId]);
270
			$this->emit('\OC\Updater', 'failure', [$appId . ': ' . $exception->getMessage()]);
271
		}
272
273
		// post-upgrade repairs
274
		$repair = new Repair(Repair::getRepairSteps(), \OC::$server->getEventDispatcher());
275
		$repair->run();
276
277
		//Invalidate update feed
278
		$this->config->setAppValue('core', 'lastupdatedat', 0);
279
280
		// Check for code integrity if not disabled
281
		if (\OC::$server->getIntegrityCodeChecker()->isCodeCheckEnforced()) {
282
			$this->emit('\OC\Updater', 'startCheckCodeIntegrity');
283
			$this->checker->runInstanceVerification();
284
			$this->emit('\OC\Updater', 'finishedCheckCodeIntegrity');
285
		}
286
287
		// only set the final version if everything went well
288
		$this->config->setSystemValue('version', implode('.', Util::getVersion()));
289
		$this->config->setAppValue('core', 'vendor', $this->getVendor());
290
	}
291
292
	protected function doCoreUpgrade() {
293
		$this->emit('\OC\Updater', 'dbUpgradeBefore');
294
295
		// execute core migrations
296
		$ms = new MigrationService('core', \OC::$server->getDatabaseConnection());
297
		$ms->migrate();
298
299
		$this->emit('\OC\Updater', 'dbUpgrade');
300
	}
301
302
	/**
303
	 * upgrades all apps within a major ownCloud upgrade. Also loads "priority"
304
	 * (types authentication, filesystem, logging, in that order) afterwards.
305
	 *
306
	 * @throws NeedsUpdateException
307
	 */
308
	protected function doAppUpgrade() {
309
		$apps = \OC_App::getEnabledApps();
310
		$priorityTypes = ['authentication', 'filesystem', 'logging'];
311
		$pseudoOtherType = 'other';
312
		$stacks = [$pseudoOtherType => []];
313
314
		foreach ($apps as $appId) {
315
			$priorityType = false;
316
			foreach ($priorityTypes as $type) {
317
				if (!isset($stacks[$type])) {
318
					$stacks[$type] = [];
319
				}
320
				if (\OC_App::isType($appId, [$type])) {
321
					$stacks[$type][] = $appId;
322
					$priorityType = true;
323
					break;
324
				}
325
			}
326
			if (!$priorityType) {
327
				$stacks[$pseudoOtherType][] = $appId;
328
			}
329
		}
330
		foreach ($stacks as $type => $stack) {
331
			foreach ($stack as $appId) {
332
				if (\OC_App::shouldUpgrade($appId)) {
333
					$this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OC_App::getAppVersion($appId)]);
334
					\OC_App::updateApp($appId);
335
					$this->emit('\OC\Updater', 'appUpgrade', [$appId, \OC_App::getAppVersion($appId)]);
336
				}
337
				if ($type !== $pseudoOtherType) {
338
					// load authentication, filesystem and logging apps after
339
					// upgrading them. Other apps my need to rely on modifying
340
					// user and/or filesystem aspects.
341
					\OC_App::loadApp($appId);
342
				}
343
			}
344
		}
345
	}
346
347
	/**
348
	 * check if the current enabled apps are compatible with the current
349
	 * ownCloud version. disable them if not.
350
	 * This is important if you upgrade ownCloud and have non ported 3rd
351
	 * party apps installed.
352
	 *
353
	 * @return array
354
	 * @throws \Exception
355
	 */
356
	private function checkAppsRequirements() {
357
		$isCoreUpgrade = $this->isCodeUpgrade();
358
		$apps = OC_App::getEnabledApps();
359
		$version = implode('.', Util::getVersion());
360
		$disabledApps = [];
361
		$appManager = \OC::$server->getAppManager();
362
		foreach ($apps as $app) {
363
			// check if the app is compatible with this version of ownCloud
364
			$info = OC_App::getAppInfo($app);
365
			if ($info === null || !OC_App::isAppCompatible($version, $info)) {
366
				if ($appManager->isShipped($app)) {
367
					throw new \UnexpectedValueException('The files of the app "' . $app . '" were not correctly replaced before running the update');
368
				}
369
				\OC::$server->getAppManager()->disableApp($app, true);
370
				$this->emit('\OC\Updater', 'incompatibleAppDisabled', [$app]);
371
			}
372
			// no need to disable any app in case this is a non-core upgrade
373
			if (!$isCoreUpgrade) {
374
				continue;
375
			}
376
			// shipped apps will remain enabled
377
			if ($appManager->isShipped($app)) {
378
				continue;
379
			}
380
			// authentication and session apps will remain enabled as well
381
			if (OC_App::isType($app, ['session', 'authentication'])) {
382
				continue;
383
			}
384
		}
385
		return $disabledApps;
386
	}
387
388
	/**
389
	 * @return bool
390
	 */
391
	private function isCodeUpgrade() {
392
		$installedVersion = $this->config->getSystemValue('version', '0.0.0');
393
		$currentVersion = implode('.', Util::getVersion());
394
		if (version_compare($currentVersion, $installedVersion, '>')) {
395
			return true;
396
		}
397
		return false;
398
	}
399
400
	/**
401
	 * @param array $disabledApps
402
	 * @param bool $reenable
403
	 * @throws \Exception
404
	 */
405
	private function upgradeAppStoreApps(array $disabledApps, $reenable = false) {
406
		foreach ($disabledApps as $app) {
407
			try {
408
				$this->emit('\OC\Updater', 'checkAppStoreAppBefore', [$app]);
409
				if ($this->installer->isUpdateAvailable($app)) {
410
					$this->emit('\OC\Updater', 'upgradeAppStoreApp', [$app]);
411
					$this->installer->updateAppstoreApp($app);
412
				}
413
				$this->emit('\OC\Updater', 'checkAppStoreApp', [$app]);
414
415
				if ($reenable) {
416
					$ocApp = new \OC_App();
417
					$ocApp->enable($app);
418
				}
419
			} catch (\Exception $ex) {
420
				$this->log->logException($ex, ['app' => 'core']);
421
			}
422
		}
423
	}
424
425
	/**
426
	 * Forward messages emitted by the repair routine
427
	 */
428
	private function emitRepairEvents() {
429
		$dispatcher = \OC::$server->getEventDispatcher();
430
		$dispatcher->addListener('\OC\Repair::warning', function ($event) {
431
			if ($event instanceof GenericEvent) {
432
				$this->emit('\OC\Updater', 'repairWarning', $event->getArguments());
433
			}
434
		});
435
		$dispatcher->addListener('\OC\Repair::error', function ($event) {
436
			if ($event instanceof GenericEvent) {
437
				$this->emit('\OC\Updater', 'repairError', $event->getArguments());
438
			}
439
		});
440
		$dispatcher->addListener('\OC\Repair::info', function ($event) {
441
			if ($event instanceof GenericEvent) {
442
				$this->emit('\OC\Updater', 'repairInfo', $event->getArguments());
443
			}
444
		});
445
		$dispatcher->addListener('\OC\Repair::step', function ($event) {
446
			if ($event instanceof GenericEvent) {
447
				$this->emit('\OC\Updater', 'repairStep', $event->getArguments());
448
			}
449
		});
450
	}
451
452
	private function logAllEvents() {
453
		$log = $this->log;
454
455
		$dispatcher = \OC::$server->getEventDispatcher();
456
		$dispatcher->addListener('\OC\DB\Migrator::executeSql', function ($event) use ($log) {
457
			if (!$event instanceof GenericEvent) {
458
				return;
459
			}
460
			$log->info('\OC\DB\Migrator::executeSql: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
461
		});
462
		$dispatcher->addListener('\OC\DB\Migrator::checkTable', function ($event) use ($log) {
463
			if (!$event instanceof GenericEvent) {
464
				return;
465
			}
466
			$log->info('\OC\DB\Migrator::checkTable: ' . $event->getSubject() . ' (' . $event->getArgument(0) . ' of ' . $event->getArgument(1) . ')', ['app' => 'updater']);
467
		});
468
469
		$repairListener = function ($event) use ($log) {
470
			if (!$event instanceof GenericEvent) {
471
				return;
472
			}
473
			switch ($event->getSubject()) {
474
				case '\OC\Repair::startProgress':
475
					$log->info('\OC\Repair::startProgress: Starting ... ' . $event->getArgument(1) .  ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
476
					break;
477
				case '\OC\Repair::advance':
478
					$desc = $event->getArgument(1);
479
					if (empty($desc)) {
480
						$desc = '';
481
					}
482
					$log->info('\OC\Repair::advance: ' . $desc . ' (' . $event->getArgument(0) . ')', ['app' => 'updater']);
483
484
					break;
485
				case '\OC\Repair::finishProgress':
486
					$log->info('\OC\Repair::finishProgress', ['app' => 'updater']);
487
					break;
488
				case '\OC\Repair::step':
489
					$log->info('\OC\Repair::step: Repair step: ' . $event->getArgument(0), ['app' => 'updater']);
490
					break;
491
				case '\OC\Repair::info':
492
					$log->info('\OC\Repair::info: Repair info: ' . $event->getArgument(0), ['app' => 'updater']);
493
					break;
494
				case '\OC\Repair::warning':
495
					$log->warning('\OC\Repair::warning: Repair warning: ' . $event->getArgument(0), ['app' => 'updater']);
496
					break;
497
				case '\OC\Repair::error':
498
					$log->error('\OC\Repair::error: Repair error: ' . $event->getArgument(0), ['app' => 'updater']);
499
					break;
500
			}
501
		};
502
503
		$dispatcher->addListener('\OC\Repair::startProgress', $repairListener);
504
		$dispatcher->addListener('\OC\Repair::advance', $repairListener);
505
		$dispatcher->addListener('\OC\Repair::finishProgress', $repairListener);
506
		$dispatcher->addListener('\OC\Repair::step', $repairListener);
507
		$dispatcher->addListener('\OC\Repair::info', $repairListener);
508
		$dispatcher->addListener('\OC\Repair::warning', $repairListener);
509
		$dispatcher->addListener('\OC\Repair::error', $repairListener);
510
511
512
		$this->listen('\OC\Updater', 'maintenanceEnabled', function () use ($log) {
513
			$log->info('\OC\Updater::maintenanceEnabled: Turned on maintenance mode', ['app' => 'updater']);
514
		});
515
		$this->listen('\OC\Updater', 'maintenanceDisabled', function () use ($log) {
516
			$log->info('\OC\Updater::maintenanceDisabled: Turned off maintenance mode', ['app' => 'updater']);
517
		});
518
		$this->listen('\OC\Updater', 'maintenanceActive', function () use ($log) {
519
			$log->info('\OC\Updater::maintenanceActive: Maintenance mode is kept active', ['app' => 'updater']);
520
		});
521
		$this->listen('\OC\Updater', 'updateEnd', function ($success) use ($log) {
522
			if ($success) {
523
				$log->info('\OC\Updater::updateEnd: Update successful', ['app' => 'updater']);
524
			} else {
525
				$log->error('\OC\Updater::updateEnd: Update failed', ['app' => 'updater']);
526
			}
527
		});
528
		$this->listen('\OC\Updater', 'dbUpgradeBefore', function () use ($log) {
529
			$log->info('\OC\Updater::dbUpgradeBefore: Updating database schema', ['app' => 'updater']);
530
		});
531
		$this->listen('\OC\Updater', 'dbUpgrade', function () use ($log) {
532
			$log->info('\OC\Updater::dbUpgrade: Updated database', ['app' => 'updater']);
533
		});
534
		$this->listen('\OC\Updater', 'dbSimulateUpgradeBefore', function () use ($log) {
535
			$log->info('\OC\Updater::dbSimulateUpgradeBefore: Checking whether the database schema can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
536
		});
537
		$this->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($log) {
538
			$log->info('\OC\Updater::dbSimulateUpgrade: Checked database schema update', ['app' => 'updater']);
539
		});
540
		$this->listen('\OC\Updater', 'incompatibleAppDisabled', function ($app) use ($log) {
541
			$log->info('\OC\Updater::incompatibleAppDisabled: Disabled incompatible app: ' . $app, ['app' => 'updater']);
542
		});
543
		$this->listen('\OC\Updater', 'checkAppStoreAppBefore', function ($app) use ($log) {
544
			$log->info('\OC\Updater::checkAppStoreAppBefore: Checking for update of app "' . $app . '" in appstore', ['app' => 'updater']);
545
		});
546
		$this->listen('\OC\Updater', 'upgradeAppStoreApp', function ($app) use ($log) {
547
			$log->info('\OC\Updater::upgradeAppStoreApp: Update app "' . $app . '" from appstore', ['app' => 'updater']);
548
		});
549
		$this->listen('\OC\Updater', 'checkAppStoreApp', function ($app) use ($log) {
550
			$log->info('\OC\Updater::checkAppStoreApp: Checked for update of app "' . $app . '" in appstore', ['app' => 'updater']);
551
		});
552
		$this->listen('\OC\Updater', 'appUpgradeCheckBefore', function () use ($log) {
553
			$log->info('\OC\Updater::appUpgradeCheckBefore: Checking updates of apps', ['app' => 'updater']);
554
		});
555
		$this->listen('\OC\Updater', 'appSimulateUpdate', function ($app) use ($log) {
556
			$log->info('\OC\Updater::appSimulateUpdate: Checking whether the database schema for <' . $app . '> can be updated (this can take a long time depending on the database size)', ['app' => 'updater']);
557
		});
558
		$this->listen('\OC\Updater', 'appUpgradeCheck', function () use ($log) {
559
			$log->info('\OC\Updater::appUpgradeCheck: Checked database schema update for apps', ['app' => 'updater']);
560
		});
561
		$this->listen('\OC\Updater', 'appUpgradeStarted', function ($app) use ($log) {
562
			$log->info('\OC\Updater::appUpgradeStarted: Updating <' . $app . '> ...', ['app' => 'updater']);
563
		});
564
		$this->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($log) {
565
			$log->info('\OC\Updater::appUpgrade: Updated <' . $app . '> to ' . $version, ['app' => 'updater']);
566
		});
567
		$this->listen('\OC\Updater', 'failure', function ($message) use ($log) {
568
			$log->error('\OC\Updater::failure: ' . $message, ['app' => 'updater']);
569
		});
570
		$this->listen('\OC\Updater', 'setDebugLogLevel', function () use ($log) {
571
			$log->info('\OC\Updater::setDebugLogLevel: Set log level to debug', ['app' => 'updater']);
572
		});
573
		$this->listen('\OC\Updater', 'resetLogLevel', function ($logLevel, $logLevelName) use ($log) {
574
			$log->info('\OC\Updater::resetLogLevel: Reset log level to ' . $logLevelName . '(' . $logLevel . ')', ['app' => 'updater']);
575
		});
576
		$this->listen('\OC\Updater', 'startCheckCodeIntegrity', function () use ($log) {
577
			$log->info('\OC\Updater::startCheckCodeIntegrity: Starting code integrity check...', ['app' => 'updater']);
578
		});
579
		$this->listen('\OC\Updater', 'finishedCheckCodeIntegrity', function () use ($log) {
580
			$log->info('\OC\Updater::finishedCheckCodeIntegrity: Finished code integrity check', ['app' => 'updater']);
581
		});
582
	}
583
}
584