diff options
-rw-r--r-- | core/ajax/update.php | 6 | ||||
-rwxr-xr-x | index.php | 6 | ||||
-rw-r--r-- | lib/private/app.php | 51 | ||||
-rw-r--r-- | lib/private/needsupdateexception.php | 12 | ||||
-rw-r--r-- | lib/private/serviceunavailableexception.php | 12 | ||||
-rw-r--r-- | lib/private/updater.php | 77 | ||||
-rwxr-xr-x | lib/private/util.php | 13 | ||||
-rw-r--r-- | public.php | 5 | ||||
-rw-r--r-- | remote.php | 4 | ||||
-rw-r--r-- | settings/ajax/updateapp.php | 3 |
10 files changed, 132 insertions, 57 deletions
diff --git a/core/ajax/update.php b/core/ajax/update.php index 698614c975f..627ada080c8 100644 --- a/core/ajax/update.php +++ b/core/ajax/update.php @@ -18,6 +18,12 @@ if (OC::checkUpgrade(false)) { $updater->listen('\OC\Updater', 'dbSimulateUpgrade', function () use ($eventSource, $l) { $eventSource->send('success', (string)$l->t('Checked database schema update')); }); + $updater->listen('\OC\Updater', 'appUpgradeCheck', function () use ($eventSource, $l) { + $eventSource->send('success', (string)$l->t('Checked database schema update for apps')); + }); + $updater->listen('\OC\Updater', 'appUpgrade', function ($app, $version) use ($eventSource, $l) { + $eventSource->send('success', (string)$l->t('Updated "%s" to %s', array($app, $version))); + }); $updater->listen('\OC\Updater', 'disabledApps', function ($appList) use ($eventSource, $l) { $list = array(); foreach ($appList as $appId) { diff --git a/index.php b/index.php index bd94d0e908d..061391892fe 100755 --- a/index.php +++ b/index.php @@ -27,6 +27,12 @@ try { OC::handleRequest(); +} catch(\OC\ServiceUnavailableException $ex) { + \OCP\Util::logException('index', $ex); + + //show the user a detailed error page + OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + OC_Template::printExceptionErrorPage($ex); } catch (Exception $ex) { \OCP\Util::logException('index', $ex); diff --git a/lib/private/app.php b/lib/private/app.php index 2887961754c..70f8980d2c1 100644 --- a/lib/private/app.php +++ b/lib/private/app.php @@ -62,6 +62,9 @@ class OC_App { * if $types is set, only apps of those types will be loaded */ public static function loadApps($types = null) { + if (OC_Config::getValue('maintenance', false)) { + return false; + } // Load the enabled apps here $apps = self::getEnabledApps(); // prevent app.php from printing output @@ -81,10 +84,14 @@ class OC_App { * load a single app * * @param string $app + * @param bool $checkUpgrade whether an upgrade check should be done + * @throws \OC\NeedsUpdateException */ - public static function loadApp($app) { + public static function loadApp($app, $checkUpgrade = true) { if (is_file(self::getAppPath($app) . '/appinfo/app.php')) { - self::checkUpgrade($app); + if ($checkUpgrade and self::shouldUpgrade($app)) { + throw new \OC\NeedsUpdateException(); + } require_once $app . '/appinfo/app.php'; } } @@ -957,39 +964,6 @@ class OC_App { } /** - * check if the app needs updating and update when needed - * - * @param string $app - */ - public static function checkUpgrade($app) { - if (in_array($app, self::$checkedApps)) { - return; - } - self::$checkedApps[] = $app; - if (!self::shouldUpgrade($app)) { - return; - } - $versions = self::getAppVersions(); - $installedVersion = $versions[$app]; - $currentVersion = OC_App::getAppVersion($app); - OC_Log::write( - $app, - 'starting app upgrade from ' . $installedVersion . ' to ' . $currentVersion, - OC_Log::DEBUG - ); - $info = self::getAppInfo($app); - try { - OC_App::updateApp($app); - OC_Hook::emit('update', 'success', 'Updated ' . $info['name'] . ' app'); - } catch (Exception $e) { - OC_Hook::emit('update', 'failure', 'Failed to update ' . $info['name'] . ' app: ' . $e->getMessage()); - $l = OC_L10N::get('lib'); - throw new RuntimeException($l->t('Failed to upgrade "%s".', array($app)), 0, $e); - } - OC_Appconfig::setValue($app, 'installed_version', OC_App::getAppVersion($app)); - } - - /** * check if the current enabled apps are compatible with the current * ownCloud version. disable them if not. * This is important if you upgrade ownCloud and have non ported 3rd @@ -1167,7 +1141,7 @@ class OC_App { */ public static function updateApp($appId) { if (file_exists(self::getAppPath($appId) . '/appinfo/preupdate.php')) { - self::loadApp($appId); + self::loadApp($appId, false); include self::getAppPath($appId) . '/appinfo/preupdate.php'; } if (file_exists(self::getAppPath($appId) . '/appinfo/database.xml')) { @@ -1177,7 +1151,7 @@ class OC_App { return false; } if (file_exists(self::getAppPath($appId) . '/appinfo/update.php')) { - self::loadApp($appId); + self::loadApp($appId, false); include self::getAppPath($appId) . '/appinfo/update.php'; } @@ -1195,6 +1169,9 @@ class OC_App { self::setAppTypes($appId); + $version = \OC_App::getAppVersion($appId); + \OC_Appconfig::setValue($appId, 'installed_version', $version); + return true; } diff --git a/lib/private/needsupdateexception.php b/lib/private/needsupdateexception.php new file mode 100644 index 00000000000..bab928dc30f --- /dev/null +++ b/lib/private/needsupdateexception.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +class NeedsUpdateException extends ServiceUnavailableException { +} diff --git a/lib/private/serviceunavailableexception.php b/lib/private/serviceunavailableexception.php new file mode 100644 index 00000000000..15e4cd5c2fd --- /dev/null +++ b/lib/private/serviceunavailableexception.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC; + +class ServiceUnavailableException extends \Exception { +} diff --git a/lib/private/updater.php b/lib/private/updater.php index 7acd6446ec4..1d52f9be374 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -7,6 +7,7 @@ */ namespace OC; + use OC\Hooks\BasicEmitter; /** @@ -61,6 +62,7 @@ class Updater extends BasicEmitter { /** * Check if a new version is available + * * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' * @return array|bool */ @@ -161,7 +163,7 @@ class Updater extends BasicEmitter { // create empty file in data dir, so we can later find // out that this is indeed an ownCloud data directory // (in case it didn't exist before) - file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT.'/data').'/.ocdata', ''); + file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', ''); /* * START CONFIG CHANGES FOR OLDER VERSIONS @@ -182,22 +184,11 @@ class Updater extends BasicEmitter { // simulate DB upgrade if ($this->simulateStepEnabled) { - // simulate core DB upgrade - \OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); + $this->checkCoreUpgrade(); // simulate apps DB upgrade - $version = \OC_Util::getVersion(); - $apps = \OC_App::getEnabledApps(); - foreach ($apps as $appId) { - $info = \OC_App::getAppInfo($appId); - if (\OC_App::isAppCompatible($version, $info) && \OC_App::shouldUpgrade($appId)) { - if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) { - \OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml'); - } - } - } + $this->checkAppUpgrade($currentVersion); - $this->emit('\OC\Updater', 'dbSimulateUpgrade'); } // upgrade from OC6 to OC7 @@ -208,16 +199,14 @@ class Updater extends BasicEmitter { } if ($this->updateStepEnabled) { - // do the real upgrade - \OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); - $this->emit('\OC\Updater', 'dbUpgrade'); + $this->doCoreUpgrade(); $disabledApps = \OC_App::checkAppsRequirements(); if (!empty($disabledApps)) { $this->emit('\OC\Updater', 'disabledApps', array($disabledApps)); } - // load all apps to also upgrade enabled apps - \OC_App::loadApps(); + + $this->doAppUpgrade(); // post-upgrade repairs $repair = new \OC\Repair(\OC\Repair::getRepairSteps()); @@ -230,5 +219,55 @@ class Updater extends BasicEmitter { \OC_Config::setValue('version', implode('.', \OC_Util::getVersion())); } } + + protected function checkCoreUpgrade() { + // simulate core DB upgrade + \OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); + + $this->emit('\OC\Updater', 'dbSimulateUpgrade'); + } + + protected function doCoreUpgrade() { + // do the real upgrade + \OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml'); + + $this->emit('\OC\Updater', 'dbUpgrade'); + } + + /** + * @param string $version the oc version to check app compatibilty with + */ + protected function checkAppUpgrade($version) { + $apps = \OC_App::getEnabledApps(); + + + foreach ($apps as $appId) { + if ($version) { + $info = \OC_App::getAppInfo($appId); + $compatible = \OC_App::isAppCompatible($version, $info); + } else { + $compatible = true; + } + + if ($compatible && \OC_App::shouldUpgrade($appId)) { + if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) { + \OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml'); + } + } + } + + $this->emit('\OC\Updater', 'appUpgradeCheck'); + } + + protected function doAppUpgrade() { + $apps = \OC_App::getEnabledApps(); + + foreach ($apps as $appId) { + if (\OC_App::shouldUpgrade($appId)) { + \OC_App::updateApp($appId); + $this->emit('\OC\Updater', 'appUpgrade', array($appId, \OC_App::getAppVersion($appId))); + } + } + } } diff --git a/lib/private/util.php b/lib/private/util.php index 1485377828d..4959cb5a786 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -1465,7 +1465,18 @@ class OC_Util { if (OC_Config::getValue('installed', false)) { $installedVersion = OC_Config::getValue('version', '0.0.0'); $currentVersion = implode('.', OC_Util::getVersion()); - return version_compare($currentVersion, $installedVersion, '>'); + if (version_compare($currentVersion, $installedVersion, '>')) { + return true; + } + + // also check for upgrades for apps + $apps = \OC_App::getEnabledApps(); + foreach ($apps as $app) { + if (\OC_App::shouldUpgrade($app)) { + return true; + } + } + return false; } else { return false; } diff --git a/public.php b/public.php index 2ac082dba57..0e04db66da7 100644 --- a/public.php +++ b/public.php @@ -45,6 +45,11 @@ try { require_once OC_App::getAppPath($app) . '/' . $parts[1]; +} catch (\OC\ServiceUnavailableException $ex) { + //show the user a detailed error page + OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + \OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL); + OC_Template::printExceptionErrorPage($ex); } catch (Exception $ex) { //show the user a detailed error page OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR); diff --git a/remote.php b/remote.php index a91742b0475..d854b1d65a6 100644 --- a/remote.php +++ b/remote.php @@ -51,6 +51,10 @@ try { $baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/'; require_once $file; +} catch (\OC\ServiceUnavailableException $ex) { + OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE); + \OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL); + OC_Template::printExceptionErrorPage($ex); } catch (Exception $ex) { OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR); \OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL); diff --git a/settings/ajax/updateapp.php b/settings/ajax/updateapp.php index 78f6775fe95..afaa9318fb2 100644 --- a/settings/ajax/updateapp.php +++ b/settings/ajax/updateapp.php @@ -33,7 +33,10 @@ if (!is_numeric($appId)) { $appId = OC_App::cleanAppId($appId); +\OC_Config::setValue('maintenance', true); $result = OC_Installer::updateAppByOCSId($appId, $isShipped); +\OC_Config::setValue('maintenance', false); + if($result !== false) { OC_JSON::success(array('data' => array('appid' => $appId))); } else { |