diff --git a/lib/private/Updater.php b/lib/private/Updater.php index a66d49941c..3f4e54cf80 100644 --- a/lib/private/Updater.php +++ b/lib/private/Updater.php @@ -157,9 +157,9 @@ class Updater extends BasicEmitter { /** * Return version from which this version is allowed to upgrade from * - * @return string allowed previous version + * @return array allowed previous versions per vendor */ - private function getAllowedPreviousVersion() { + private function getAllowedPreviousVersions() { // this should really be a JSON file require \OC::$SERVERROOT . '/version.php'; /** @var array $OC_VersionCanBeUpgradedFrom */ @@ -182,26 +182,22 @@ class Updater extends BasicEmitter { * Whether an upgrade to a specified version is possible * @param string $oldVersion * @param string $newVersion - * @param string $allowedPreviousVersion + * @param array $allowedPreviousVersions * @return bool */ - public function isUpgradePossible($oldVersion, $newVersion, $allowedPreviousVersion) { - $allowedUpgrade = (version_compare($allowedPreviousVersion, $oldVersion, '<=') - && (version_compare($oldVersion, $newVersion, '<=') || $this->config->getSystemValue('debug', false))); + public function isUpgradePossible($oldVersion, $newVersion, array $allowedPreviousVersions) { + $version = explode('.', $oldVersion); + $majorMinor = $version[0] . '.' . $version[1]; - if ($allowedUpgrade) { - return $allowedUpgrade; + $currentVendor = $this->config->getAppValue('core', 'vendor', ''); + if ($currentVendor === 'nextcloud') { + return isset($allowedPreviousVersions[$currentVendor][$majorMinor]) + && (version_compare($oldVersion, $newVersion, '<=') || + $this->config->getSystemValue('debug', false)); } - // Upgrade not allowed, someone switching vendor? - if ($this->getVendor() !== $this->config->getAppValue('core', 'vendor', '')) { - $oldVersion = explode('.', $oldVersion); - $newVersion = explode('.', $newVersion); - - return $oldVersion[0] === $newVersion[0] && $oldVersion[1] === $newVersion[1]; - } - - return false; + // Check if the instance can be migrated + return isset($allowedPreviousVersions[$currentVendor][$majorMinor]); } /** @@ -215,8 +211,8 @@ class Updater extends BasicEmitter { */ private function doUpgrade($currentVersion, $installedVersion) { // Stop update if the update is over several major versions - $allowedPreviousVersion = $this->getAllowedPreviousVersion(); - if (!self::isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersion)) { + $allowedPreviousVersions = $this->getAllowedPreviousVersions(); + if (!$this->isUpgradePossible($installedVersion, $currentVersion, $allowedPreviousVersions)) { throw new \Exception('Updates between multiple major versions and downgrades are unsupported.'); } diff --git a/tests/lib/UpdaterTest.php b/tests/lib/UpdaterTest.php index 80c7c28cd6..afa0635768 100644 --- a/tests/lib/UpdaterTest.php +++ b/tests/lib/UpdaterTest.php @@ -56,93 +56,32 @@ class UpdaterTest extends TestCase { ); } - /** - * @param string $baseUrl - * @return string - */ - private function buildUpdateUrl($baseUrl) { - return $baseUrl . '?version='.implode('x', \OCP\Util::getVersion()).'xinstalledatxlastupdatedatx'.\OC_Util::getChannel().'xx'; - } - /** * @return array */ public function versionCompatibilityTestData() { return [ - ['1', '2', '1', true], - ['2', '2', '2', true], - ['6.0.5.0', '6.0.6.0', '5.0', true], - ['5.0.6.0', '7.0.4.0', '6.0', false], - // allow upgrading within the same major release - ['8.0.0.0', '8.0.0.0', '8.0', true], - ['8.0.0.0', '8.0.0.4', '8.0', true], - ['8.0.0.0', '8.0.1.0', '8.0', true], - ['8.0.0.0', '8.0.2.0', '8.0', true], - // does not allow downgrading within the same major release - ['8.0.1.0', '8.0.0.0', '8.0', false], - ['8.0.2.0', '8.0.1.0', '8.0', false], - ['8.0.0.4', '8.0.0.0', '8.0', false], - // allows upgrading within the patch version - ['8.0.0.0', '8.0.0.1', '8.0', true], - ['8.0.0.0', '8.0.0.2', '8.0', true], - // does not allow downgrading within the same major release - ['8.0.0.1', '8.0.0.0', '8.0', false], - ['8.0.0.2', '8.0.0.0', '8.0', false], - // allow upgrading to the next major release - ['8.0.0.0', '8.1.0.0', '8.0', true], - ['8.0.0.0', '8.1.1.0', '8.0', true], - ['8.0.0.0', '8.1.1.5', '8.0', true], - ['8.0.0.2', '8.1.1.5', '8.0', true], - ['8.1.0.0', '8.2.0.0', '8.1', true], - ['8.1.0.2', '8.2.0.4', '8.1', true], - ['8.1.0.5', '8.2.0.1', '8.1', true], - ['8.1.0.0', '8.2.1.0', '8.1', true], - ['8.1.0.2', '8.2.1.5', '8.1', true], - ['8.1.0.5', '8.2.1.1', '8.1', true], - // does not allow downgrading to the previous major release - ['8.1.0.0', '8.0.0.0', '7.0', false], - ['8.1.1.0', '8.0.0.0', '7.0', false], - // does not allow skipping major releases - ['8.0.0.0', '8.2.0.0', '8.1', false], - ['8.0.0.0', '8.2.1.0', '8.1', false], - ['8.0.0.0', '9.0.1.0', '8.2', false], - ['8.0.0.0', '10.0.0.0', '9.3', false], - // allows updating to the next major release - ['8.2.0.0', '9.0.0.0', '8.2', true], - ['8.2.0.0', '9.0.0.0', '8.2', true], - ['8.2.0.0', '9.0.1.0', '8.2', true], - ['8.2.0.0', '9.0.1.1', '8.2', true], - ['8.2.0.2', '9.0.1.1', '8.2', true], - ['8.2.2.0', '9.0.1.0', '8.2', true], - ['8.2.2.2', '9.0.1.1', '8.2', true], - ['9.0.0.0', '9.1.0.0', '9.0', true], - ['9.0.0.0', '9.1.0.2', '9.0', true], - ['9.0.0.2', '9.1.0.1', '9.0', true], - ['9.1.0.0', '9.2.0.0', '9.1', true], - ['9.2.0.0', '9.3.0.0', '9.2', true], - ['9.3.0.0', '10.0.0.0', '9.3', true], - // does not allow updating to the next major release (first number) - ['9.0.0.0', '8.2.0.0', '8.1', false], - // other cases - ['8.0.0.0', '8.1.5.0', '8.0', true], - ['8.2.0.0', '9.0.0.0', '8.2', true], - ['8.2.0.0', '9.1.0.0', '9.0', false], - ['9.0.0.0', '8.1.0.0', '8.0', false], - ['9.0.0.0', '8.0.0.0', '7.0', false], - ['9.1.0.0', '8.0.0.0', '7.0', false], - ['8.2.0.0', '8.1.0.0', '8.0', false], + // Upgrade with invalid version + ['9.1.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], false], + ['10.0.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], false], + // Upgrad with valid version + ['11.0.1.13', '11.0.2.25', ['nextcloud' => ['11.0' => true]], true], + // Downgrade with valid version + ['11.0.2.25', '11.0.1.13', ['nextcloud' => ['11.0' => true]], false], + ['11.0.2.25', '11.0.1.13', ['nextcloud' => ['11.0' => true]], true, true], + // Downgrade with invalid version + ['11.0.2.25', '10.0.1.13', ['nextcloud' => ['10.0' => true]], false], + ['11.0.2.25', '10.0.1.13', ['nextcloud' => ['10.0' => true]], false, true], - // With debug enabled - ['8.0.0.0', '8.2.0.0', '8.1', false, true], - ['8.1.0.0', '8.2.0.0', '8.1', true, true], - ['8.2.0.1', '8.2.0.1', '8.1', true, true], - ['8.3.0.0', '8.2.0.0', '8.1', true, true], - - // Downgrade of maintenance - ['9.0.53.0', '9.0.4.0', '8.1', false, false, 'nextcloud'], - // with vendor switch - ['9.0.53.0', '9.0.4.0', '8.1', true, false, ''], - ['9.0.53.0', '9.0.4.0', '8.1', true, false, 'owncloud'], + // Migration with unknown vendor + ['9.1.1.13', '11.0.2.25', ['nextcloud' => ['9.1' => true]], false, false, 'owncloud'], + ['9.1.1.13', '11.0.2.25', ['nextcloud' => ['9.1' => true]], false, true, 'owncloud'], + // Migration with unsupported vendor version + ['9.1.1.13', '11.0.2.25', ['owncloud' => ['10.0' => true]], false, false, 'owncloud'], + ['9.1.1.13', '11.0.2.25', ['owncloud' => ['10.0' => true]], false, true, 'owncloud'], + // Migration with valid vendor version + ['9.1.1.13', '11.0.2.25', ['owncloud' => ['9.1' => true]], true, false, 'owncloud'], + ['9.1.1.13', '11.0.2.25', ['owncloud' => ['9.1' => true]], true, true, 'owncloud'], ]; } @@ -151,12 +90,12 @@ class UpdaterTest extends TestCase { * * @param string $oldVersion * @param string $newVersion - * @param string $allowedVersion + * @param array $allowedVersions * @param bool $result * @param bool $debug * @param string $vendor */ - public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersion, $result, $debug = false, $vendor = 'nextcloud') { + public function testIsUpgradePossible($oldVersion, $newVersion, $allowedVersions, $result, $debug = false, $vendor = 'nextcloud') { $this->config->expects($this->any()) ->method('getSystemValue') ->with('debug', false) @@ -166,7 +105,7 @@ class UpdaterTest extends TestCase { ->with('core', 'vendor', '') ->willReturn($vendor); - $this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersion)); + $this->assertSame($result, $this->updater->isUpgradePossible($oldVersion, $newVersion, $allowedVersions)); } public function testSetSkip3rdPartyAppsDisable() { diff --git a/version.php b/version.php index 90f4e65055..3d8abb5f2f 100644 --- a/version.php +++ b/version.php @@ -31,7 +31,15 @@ $OC_Version = array(12, 0, 0, 12); // The human readable string $OC_VersionString = '12.0 alpha'; -$OC_VersionCanBeUpgradedFrom = array(11); +$OC_VersionCanBeUpgradedFrom = [ + 'nextcloud' => [ + '11.0' => true, + '12.0' => true, + ], + 'owncloud' => [ + '10.0' => true, + ], +]; // default Nextcloud channel $OC_Channel = 'git';