Skip to content
Snippets Groups Projects
Commit af1c3dd4 authored by Robin Appelman's avatar Robin Appelman
Browse files

Merge pull request #3963 from owncloud/update-logic-split

Move the upgrade logic to \OC\Updater
parents 15907f6a a0d5ba11
No related branches found
No related tags found
No related merge requests found
...@@ -4,113 +4,34 @@ $RUNTIME_NOAPPS = true; ...@@ -4,113 +4,34 @@ $RUNTIME_NOAPPS = true;
require_once '../../lib/base.php'; require_once '../../lib/base.php';
if (OC::checkUpgrade(false)) { if (OC::checkUpgrade(false)) {
\OC_DB::enableCaching(false); $eventSource = new OC_EventSource();
OC_Config::setValue('maintenance', true); $updater = new \OC\Updater(\OC_Log::$object);
$installedVersion = OC_Config::getValue('version', '0.0.0'); $updater->listen('\OC\Updater', 'maintenanceStart', function () use ($eventSource) {
$currentVersion = implode('.', OC_Util::getVersion()); $eventSource->send('success', 'Turned on maintenance mode');
OC_Log::write('core', 'starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, OC_Log::WARN); });
$updateEventSource = new OC_EventSource(); $updater->listen('\OC\Updater', 'maintenanceEnd', function () use ($eventSource) {
$watcher = new UpdateWatcher($updateEventSource); $eventSource->send('success', 'Turned off maintenance mode');
OC_Hook::connect('update', 'success', $watcher, 'success'); });
OC_Hook::connect('update', 'error', $watcher, 'error'); $updater->listen('\OC\Updater', 'dbUpgrade', function () use ($eventSource) {
OC_Hook::connect('update', 'failure', $watcher, 'failure'); $eventSource->send('success', 'Updated database');
$watcher->success('Turned on maintenance mode'); });
try { $updater->listen('\OC\Updater', 'filecacheStart', function () use ($eventSource) {
$result = OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml'); $eventSource->send('success', 'Updating filecache, this may take really long...');
$watcher->success('Updated database'); });
$updater->listen('\OC\Updater', 'filecacheDone', function () use ($eventSource) {
// do a file cache upgrade for users with files $eventSource->send('success', 'Updated filecache');
// this can take loooooooooooooooooooooooong });
__doFileCacheUpgrade($watcher); $updater->listen('\OC\Updater', 'filecacheProgress', function ($out) use ($eventSource) {
} catch (Exception $exception) { $eventSource->send('success', '... ' . $out . '% done ...');
$watcher->failure($exception->getMessage()); });
} $updater->listen('\OC\Updater', 'failure', function ($message) use ($eventSource) {
OC_Config::setValue('version', implode('.', OC_Util::getVersion())); $eventSource->send('failure', $message);
OC_App::checkAppsRequirements(); $eventSource->close();
// load all apps to also upgrade enabled apps
OC_App::loadApps();
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); OC_Config::setValue('maintenance', false);
die(); });
}
public function done() { $updater->upgrade();
OC_Util::obEnd();
$this->eventSource->send('done', '');
$this->eventSource->close();
}
} $eventSource->send('done', '');
\ No newline at end of file $eventSource->close();
}
<?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('http://apps.owncloud.com/updater.php');
}
}
<?php <?php
/** /**
* ownCloud * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
* * This file is licensed under the Affero General Public License version 3 or
* @author Frank Karlitschek * later.
* @copyright 2012 Frank Karlitschek frank@owncloud.org * See the COPYING-README file.
*
* 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/>.
*
*/ */
namespace OC;
use OC\Hooks\BasicEmitter;
/** /**
* Class that handels autoupdating of ownCloud * Class that handles 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 * Check if a new version is available
* @param string $updateUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php'
* @return array | bool
*/ */
public static function check() { public function check($updaterUrl) {
// Look up the cache - it is invalidated all 30 minutes // Look up the cache - it is invalidated all 30 minutes
if((OC_Appconfig::getValue('core', 'lastupdatedat') + 1800) > time()) { if ((\OC_Appconfig::getValue('core', 'lastupdatedat') + 1800) > time()) {
return json_decode(OC_Appconfig::getValue('core', 'lastupdateResult'), true); 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', '')=='') { if (\OC_Appconfig::getValue('core', 'installedat', '') == '') {
OC_Appconfig::setValue('core', 'installedat', microtime(true)); \OC_Appconfig::setValue('core', 'installedat', microtime(true));
} }
$updaterurl='http://apps.owncloud.com/updater.php'; $version = \OC_Util::getVersion();
$version=OC_Util::getVersion(); $version['installed'] = \OC_Appconfig::getValue('core', 'installedat');
$version['installed']=OC_Appconfig::getValue('core', 'installedat'); $version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat');
$version['updated']=OC_Appconfig::getValue('core', 'lastupdatedat'); $version['updatechannel'] = 'stable';
$version['updatechannel']='stable'; $version['edition'] = \OC_Util::getEditionString();
$version['edition']=OC_Util::getEditionString(); $versionString = implode('x', $version);
$versionstring=implode('x', $version);
//fetch xml data from updater //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. // set a sensible timeout of 10 sec to stay responsive even if the update server is down.
$ctx = stream_context_create( $ctx = stream_context_create(
...@@ -60,21 +71,89 @@ class OC_Updater{ ...@@ -60,21 +71,89 @@ class OC_Updater{
) )
) )
); );
$xml=@file_get_contents($url, 0, $ctx); $xml = @file_get_contents($url, 0, $ctx);
if($xml==false) { if ($xml == false) {
return array(); return array();
} }
$data=@simplexml_load_string($xml); $data = @simplexml_load_string($xml);
$tmp=array(); $tmp = array();
$tmp['version'] = $data->version; $tmp['version'] = $data->version;
$tmp['versionstring'] = $data->versionstring; $tmp['versionstring'] = $data->versionstring;
$tmp['url'] = $data->url; $tmp['url'] = $data->url;
$tmp['web'] = $data->web; $tmp['web'] = $data->web;
// Cache the result // Cache the result
OC_Appconfig::setValue('core', 'lastupdateResult', json_encode($data)); \OC_Appconfig::setValue('core', 'lastupdateResult', json_encode($data));
return $tmp; return $tmp;
} }
}
\ No newline at end of file /**
* 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');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment