Skip to content

Commit

Permalink
Add repair step for updater issues
Browse files Browse the repository at this point in the history
The updater as shipped with ownCloud =< 9.0.1 has several bugs leading to a not properly executed update. For example the third-party changes are not copied.

This pull request:

1. Ships the third-party files changed since ownCloud 9.0.1 in the resources folder. On update the files are replaced. (owncloud/updater#316)
2. Adds updater/* and _oc_upgrade/* as an exemption to the code integrity checker since the updater is updating in the wrong order. (owncloud/updater#318)
  • Loading branch information
LukasReschke committed Apr 20, 2016
1 parent bd19bbb commit 2d37341
Show file tree
Hide file tree
Showing 19 changed files with 13,233 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lib/private/integritycheck/checker.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,19 @@ private function verify($signaturePath, $basePath, $certificateCN) {
throw new InvalidSignatureException('Signature could not get verified.');
}

// Fixes for the updater as shipped with ownCloud 9.0.x: The updater is
// replaced after the code integrity check is performed.
//
// Due to this reason we exclude the whole updater/ folder from the code
// integrity check.
if($basePath === $this->environmentHelper->getServerRoot()) {
foreach($expectedHashes as $fileName => $hash) {
if(strpos($fileName, 'updater/') === 0) {
unset($expectedHashes[$fileName]);
}
}
}

// Compare the list of files which are not identical
$currentInstanceHashes = $this->generateHashes($this->getFolderIterator($basePath), $basePath);
$differencesA = array_diff($expectedHashes, $currentInstanceHashes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public function __construct(\RecursiveIterator $iterator, $root = '') {
rtrim($root . '/apps', '/'),
rtrim($root . '/assets', '/'),
rtrim($root . '/lost+found', '/'),
// Ignore folders generated by updater since the updater is replaced
// after the integrity check is run.
// See https://github.com/owncloud/updater/issues/318#issuecomment-212497846
rtrim($root . '/updater', '/'),
rtrim($root . '/_oc_upgrade', '/'),
];
$customDataDir = \OC::$server->getConfig()->getSystemValue('datadirectory', '');
if($customDataDir !== '') {
Expand Down
2 changes: 2 additions & 0 deletions lib/private/repair.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OC\Hooks\BasicEmitter;
use OC\Hooks\Emitter;
use OC\Repair\AssetCache;
use OC\Repair\BrokenUpdaterRepair;
use OC\Repair\CleanTags;
use OC\Repair\Collation;
use OC\Repair\DropOldJobs;
Expand Down Expand Up @@ -114,6 +115,7 @@ public static function getRepairSteps() {
new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()),
new UpdateOutdatedOcsIds(\OC::$server->getConfig()),
new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()),
new BrokenUpdaterRepair(),
];
}

Expand Down
109 changes: 109 additions & 0 deletions lib/private/repair/brokenupdaterrepair.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* @author Lukas Reschke <lukas@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

namespace OC\Repair;

use OC\Hooks\BasicEmitter;

/**
* Class BrokenUpdaterRepair fixes some issues caused by bugs in the ownCloud
* updater below version 9.0.2.
*
* FIXME: This file should be removed after the 9.0.2 release. The update server
* is instructed to deliver 9.0.2 for 9.0.0 and 9.0.1.
*
* @package OC\Repair
*/
class BrokenUpdaterRepair extends BasicEmitter implements \OC\RepairStep {

public function getName() {
return 'Manually copies the third-party folder changes since 9.0.0 due ' .
'to a bug in the updater.';
}

/**
* Manually copy the third-party files that have changed since 9.0.0 because
* the old updater does not copy over third-party changes.
*
* @return bool True if action performed, false otherwise
*/
private function manuallyCopyThirdPartyFiles() {
$resourceDir = __DIR__ . '/../../../resources/updater-fixes/';
$thirdPartyDir = __DIR__ . '/../../../3rdparty/';

$filesToCopy = [
// Composer updates
'composer.json',
'composer.lock',
'composer/autoload_classmap.php',
'composer/installed.json',
'composer/LICENSE',
// Icewind stream library
'icewind/streams/src/DirectoryFilter.php',
'icewind/streams/src/DirectoryWrapper.php',
'icewind/streams/src/RetryWrapper.php',
'icewind/streams/src/SeekableWrapper.php',
// Sabre update
'sabre/dav/CHANGELOG.md',
'sabre/dav/composer.json',
'sabre/dav/lib/CalDAV/Plugin.php',
'sabre/dav/lib/CardDAV/Backend/PDO.php',
'sabre/dav/lib/DAV/CorePlugin.php',
'sabre/dav/lib/DAV/Version.php',
];

// First check whether the files have been copied the first time already
// if so there is no need to run the move routine.
if(file_exists($thirdPartyDir . '/icewind/streams/src/RetryWrapper.php')) {
$this->emit('\OC\Repair', 'info', ['Third-party files seem already to have been copied. No repair necessary.']);
return false;
}

foreach($filesToCopy as $file) {
$state = copy($resourceDir . '/' . $file, $thirdPartyDir . '/' . $file);
if($state === true) {
$this->emit('\OC\Repair', 'info', ['Successfully replaced '.$file.' with new version.']);
} else {
$this->emit('\OC\Repair', 'warning', ['Could not replace '.$file.' with new version.']);
}
}
return true;
}

/**
* Rerun the integrity check after the update since the repair step has
* repaired some invalid copied files.
*/
private function recheckIntegrity() {
\OC::$server->getIntegrityCodeChecker()->runInstanceVerification();
}

public function run() {
if($this->manuallyCopyThirdPartyFiles()) {
$this->emit('\OC\Repair', 'info', ['Start integrity recheck.']);
$this->recheckIntegrity();
$this->emit('\OC\Repair', 'info', ['Finished integrity recheck.']);
} else {
$this->emit('\OC\Repair', 'info', ['Rechecking code integrity not necessary.']);
}
}
}

44 changes: 44 additions & 0 deletions resources/updater-fixes/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "owncloud/3rdparty",
"description": "All 3rdparty components",
"license": "MIT",
"config": {
"vendor-dir": ".",
"optimize-autoloader": true,
"classmap-authoritative": true
},
"require": {
"doctrine/dbal": "2.5.2",
"mcnetic/zipstreamer": "^1.0",
"phpseclib/phpseclib": "2.0.0",
"rackspace/php-opencloud": "v1.9.2",
"james-heinrich/getid3": "dev-master",
"jeremeamia/superclosure": "2.1.0",
"ircmaxell/random-lib": "~1.1",
"bantu/ini-get-wrapper": "v1.0.1",
"natxet/CssMin": "dev-master",
"punic/punic": "1.6.3",
"pear/archive_tar": "1.4.1",
"patchwork/utf8": "1.2.6",
"symfony/console": "2.8.1",
"symfony/event-dispatcher": "2.8.1",
"symfony/routing": "2.8.1",
"symfony/process": "2.8.1",
"pimple/pimple": "3.0.2",
"ircmaxell/password-compat": "1.0.*",
"nikic/php-parser": "1.4.1",
"icewind/Streams": "0.4.0",
"swiftmailer/swiftmailer": "@stable",
"guzzlehttp/guzzle": "5.3.0",
"league/flysystem": "1.0.16",
"pear/pear-core-minimal": "v1.10.1",
"interfasys/lognormalizer": "^v1.0",
"deepdiver1975/TarStreamer": "v0.1.0",
"patchwork/jsqueeze": "^2.0",
"kriswallsmith/assetic": "1.3.2",
"sabre/dav": "3.0.9",
"symfony/polyfill-php70": "^1.0",
"symfony/polyfill-php55": "^1.0",
"symfony/polyfill-php56": "^1.0"
}
}
Loading

0 comments on commit 2d37341

Please sign in to comment.