split upgrade logic from ajax file

This commit is contained in:
Robin Appelman 2013-07-06 17:00:00 +02:00
parent c8ad3df1fa
commit 58f473d734
3 changed files with 160 additions and 146 deletions

View File

@ -4,113 +4,34 @@ $RUNTIME_NOAPPS = true;
require_once '../../lib/base.php';
if (OC::checkUpgrade(false)) {
\OC_DB::enableCaching(false);
OC_Config::setValue('maintenance', true);
$installedVersion = OC_Config::getValue('version', '0.0.0');
$currentVersion = implode('.', OC_Util::getVersion());
OC_Log::write('core', 'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, OC_Log::WARN);
$updateEventSource = new OC_EventSource();
$watcher = new UpdateWatcher($updateEventSource);
OC_Hook::connect('update', 'success', $watcher, 'success');
OC_Hook::connect('update', 'error', $watcher, 'error');
OC_Hook::connect('update', 'failure', $watcher, 'failure');
$watcher->success('Turned on maintenance mode');
try {
$result = OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml');
$watcher->success('Updated database');
// do a file cache upgrade for users with files
// this can take loooooooooooooooooooooooong
__doFileCacheUpgrade($watcher);
} catch (Exception $exception) {
$watcher->failure($exception->getMessage());
}
OC_Config::setValue('version', implode('.', OC_Util::getVersion()));
OC_App::checkAppsRequirements();
// load all apps to also upgrade enabled apps
OC_App::loadApps();
$eventSource = new OC_EventSource();
$updater = new \OC\Updater(\OC_Log::$object);
$updater->listen('\OC\Updater', 'maintenanceStart', function () use ($eventSource) {
$eventSource->send('success', 'Turned on maintenance mode');
});
$updater->listen('\OC\Updater', 'maintenanceEnd', function () use ($eventSource) {
$eventSource->send('success', 'Turned off maintenance mode');
});
$updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource) {
$eventSource->send('success', 'Updated database');
});
$updater->listen('\OC\Updater', 'filecacheStart', function () use ($eventSource) {
$eventSource->send('success', 'Updating filecache, this may take really long...');
});
$updater->listen('\OC\Updater', 'filecacheDone', function () use ($eventSource) {
$eventSource->send('success', 'Updated filecache');
});
$updater->listen('\OC\Updater', 'filecacheProgress', function ($out) use ($eventSource) {
$eventSource->send('success', '... ' . $out . '% done ...');
});
$updater->listen('\OC\Updater', 'failure', function ($message) use ($eventSource) {
$eventSource->send('failure', $message);
$eventSource->close();
OC_Config::setValue('maintenance', false);
$watcher->success('Turned off maintenance mode');
$watcher->done();
}
/**
* The FileCache Upgrade routine
*
* @param UpdateWatcher $watcher
*/
function __doFileCacheUpgrade($watcher) {
try {
$query = \OC_DB::prepare('
SELECT DISTINCT `user`
FROM `*PREFIX*fscache`
');
$result = $query->execute();
} catch (\Exception $e) {
return;
}
$users = $result->fetchAll();
if(count($users) == 0) {
return;
}
$step = 100 / count($users);
$percentCompleted = 0;
$lastPercentCompletedOutput = 0;
$startInfoShown = false;
foreach($users as $userRow) {
$user = $userRow['user'];
\OC\Files\Filesystem::initMountPoints($user);
\OC\Files\Cache\Upgrade::doSilentUpgrade($user);
if(!$startInfoShown) {
//We show it only now, because otherwise Info about upgraded apps
//will appear between this and progress info
$watcher->success('Updating filecache, this may take really long...');
$startInfoShown = true;
}
$percentCompleted += $step;
$out = floor($percentCompleted);
if($out != $lastPercentCompletedOutput) {
$watcher->success('... '. $out.'% done ...');
$lastPercentCompletedOutput = $out;
}
}
$watcher->success('Updated filecache');
}
class UpdateWatcher {
/**
* @var \OC_EventSource $eventSource;
*/
private $eventSource;
public function __construct($eventSource) {
$this->eventSource = $eventSource;
}
public function success($message) {
OC_Util::obEnd();
$this->eventSource->send('success', $message);
ob_start();
}
public function error($message) {
OC_Util::obEnd();
$this->eventSource->send('error', $message);
ob_start();
}
public function failure($message) {
OC_Util::obEnd();
$this->eventSource->send('failure', $message);
$this->eventSource->close();
OC_Config::setValue('maintenance', false);
die();
}
public function done() {
OC_Util::obEnd();
$this->eventSource->send('done', '');
$this->eventSource->close();
}
});
$updater->upgrade();
$eventSource->send('done', '');
$eventSource->close();
}

14
lib/legacy/updater.php Normal file
View File

@ -0,0 +1,14 @@
<?php
/**
* Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
class OC_Updater {
public static function check() {
$updater = new \OC\Updater();
return $updater->check();
}
}

View File

@ -1,56 +1,67 @@
<?php
/**
* ownCloud
*
* @author Frank Karlitschek
* @copyright 2012 Frank Karlitschek frank@owncloud.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (c) 2013 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;
use OC\Hooks\BasicEmitter;
/**
* Class that handels autoupdating of ownCloud
*
* Hooks provided in scope \OC\Updater
* - maintenanceStart()
* - maintenanceEnd()
* - dbUpgrade()
* - filecacheStart()
* - filecacheProgress(int $percentage)
* - filecacheDone()
* - failure(string $message)
*/
class OC_Updater{
class Updater extends BasicEmitter {
/**
* @var \OC\Log $log
*/
private $log;
/**
* @param \OC\Log $log
*/
public function __construct($log = null) {
$this->log = $log;
}
/**
* Check if a new version is available
* @return array | bool
*/
public static function check() {
public function check() {
// Look up the cache - it is invalidated all 30 minutes
if((OC_Appconfig::getValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode(OC_Appconfig::getValue('core', 'lastupdateResult'), true);
if ((\OC_Appconfig::getValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode(\OC_Appconfig::getValue('core', 'lastupdateResult'), true);
}
OC_Appconfig::setValue('core', 'lastupdatedat', time());
\OC_Appconfig::setValue('core', 'lastupdatedat', time());
if(OC_Appconfig::getValue('core', 'installedat', '')=='') {
OC_Appconfig::setValue('core', 'installedat', microtime(true));
if (\OC_Appconfig::getValue('core', 'installedat', '') == '') {
\OC_Appconfig::setValue('core', 'installedat', microtime(true));
}
$updaterurl='http://apps.owncloud.com/updater.php';
$version=OC_Util::getVersion();
$version['installed']=OC_Appconfig::getValue('core', 'installedat');
$version['updated']=OC_Appconfig::getValue('core', 'lastupdatedat');
$version['updatechannel']='stable';
$version['edition']=OC_Util::getEditionString();
$versionstring=implode('x', $version);
$updaterurl = 'http://apps.owncloud.com/updater.php';
$version = \OC_Util::getVersion();
$version['installed'] = \OC_Appconfig::getValue('core', 'installedat');
$version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat');
$version['updatechannel'] = 'stable';
$version['edition'] = \OC_Util::getEditionString();
$versionstring = implode('x', $version);
//fetch xml data from updater
$url=$updaterurl.'?version='.$versionstring;
$url = $updaterurl . '?version=' . $versionstring;
// set a sensible timeout of 10 sec to stay responsive even if the update server is down.
$ctx = stream_context_create(
@ -60,21 +71,89 @@ class OC_Updater{
)
)
);
$xml=@file_get_contents($url, 0, $ctx);
if($xml==false) {
$xml = @file_get_contents($url, 0, $ctx);
if ($xml == false) {
return array();
}
$data=@simplexml_load_string($xml);
$data = @simplexml_load_string($xml);
$tmp=array();
$tmp = array();
$tmp['version'] = $data->version;
$tmp['versionstring'] = $data->versionstring;
$tmp['url'] = $data->url;
$tmp['web'] = $data->web;
// Cache the result
OC_Appconfig::setValue('core', 'lastupdateResult', json_encode($data));
\OC_Appconfig::setValue('core', 'lastupdateResult', json_encode($data));
return $tmp;
}
/**
* runs the update actions in maintenance mode, does not upgrade the source files
*/
public function upgrade() {
\OC_DB::enableCaching(false);
\OC_Config::setValue('maintenance', true);
$installedVersion = \OC_Config::getValue('version', '0.0.0');
$currentVersion = implode('.', \OC_Util::getVersion());
if ($this->log) {
$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core'));
}
$this->emit('\OC\Updater', 'maintenanceStart');
try {
\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
$this->emit('\OC\Updater', 'dbUpgrade');
// do a file cache upgrade for users with files
// this can take loooooooooooooooooooooooong
$this->upgradeFileCache();
} catch (\Exception $exception) {
$this->emit('\OC\Updater', 'failure', array($exception->getMessage()));
}
\OC_Config::setValue('version', implode('.', \OC_Util::getVersion()));
\OC_App::checkAppsRequirements();
// load all apps to also upgrade enabled apps
\OC_App::loadApps();
\OC_Config::setValue('maintenance', false);
$this->emit('\OC\Updater', 'maintenanceEnd');
}
private function upgradeFileCache() {
try {
$query = \OC_DB::prepare('
SELECT DISTINCT `user`
FROM `*PREFIX*fscache`
');
$result = $query->execute();
} catch (\Exception $e) {
return;
}
$users = $result->fetchAll();
if (count($users) == 0) {
return;
}
$step = 100 / count($users);
$percentCompleted = 0;
$lastPercentCompletedOutput = 0;
$startInfoShown = false;
foreach ($users as $userRow) {
$user = $userRow['user'];
\OC\Files\Filesystem::initMountPoints($user);
\OC\Files\Cache\Upgrade::doSilentUpgrade($user);
if (!$startInfoShown) {
//We show it only now, because otherwise Info about upgraded apps
//will appear between this and progress info
$this->emit('\OC\Updater', 'filecacheStart');
$startInfoShown = true;
}
$percentCompleted += $step;
$out = floor($percentCompleted);
if ($out != $lastPercentCompletedOutput) {
$this->emit('\OC\Updater', 'filecacheProgress', array($out));
$lastPercentCompletedOutput = $out;
}
}
$this->emit('\OC\Updater', 'filecacheDone');
}
}