mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #56779 from nextcloud/jtr/needUpgrade-refactor
feat: improve needUpgrade() output and refactor for clarity
This commit is contained in:
commit
ebab99ec9a
1 changed files with 76 additions and 43 deletions
|
|
@ -753,52 +753,85 @@ class OC_Util {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether the instance needs to perform an upgrade,
|
||||
* either when the core version is higher or any app requires
|
||||
* an upgrade.
|
||||
* Determine whether this Nextcloud Server instance requires an upgrade.
|
||||
*
|
||||
* @param \OC\SystemConfig $config
|
||||
* @return bool whether the core or any app needs an upgrade
|
||||
* @throws \OCP\HintException When the upgrade from the given version is not allowed
|
||||
* @deprecated 32.0.0 Use \OCP\Util::needUpgrade instead
|
||||
* Compares the version stored in config.php ("installed" version) with the
|
||||
* version reported by the running codebase ("code" version). Returns true
|
||||
* when the codebase is newer, or when any enabled app requires an upgrade.
|
||||
*
|
||||
* Notes:
|
||||
* - "installed" refers to the version recorded in config.php.
|
||||
* - "code" refers to the version of the running Nextcloud Server code (version.php).
|
||||
* - Blocks unsupported downgrades (code older than installed), but does NOT validate
|
||||
* whether an upgrade path is supported (e.g., skipping major versions like 28->30).
|
||||
* Callers are expected to check that on their own.
|
||||
*
|
||||
* @param \OC\SystemConfig $config System configuration (reads 'installed', 'version', 'debug').
|
||||
* @return bool True if a core or app upgrade is required, false otherwise.
|
||||
* @throws \OCP\HintException If a downgrade is detected and not allowed.
|
||||
* @deprecated 32.0.0 Use \OCP\Util::needUpgrade() instead.
|
||||
* @see \OCP\Util::needUpgrade
|
||||
*/
|
||||
public static function needUpgrade(\OC\SystemConfig $config) {
|
||||
if ($config->getValue('installed', false)) {
|
||||
$installedVersion = $config->getValue('version', '0.0.0');
|
||||
$currentVersion = implode('.', \OCP\Util::getVersion());
|
||||
$versionDiff = version_compare($currentVersion, $installedVersion);
|
||||
if ($versionDiff > 0) {
|
||||
return true;
|
||||
} elseif ($config->getValue('debug', false) && $versionDiff < 0) {
|
||||
// downgrade with debug
|
||||
$installedMajor = explode('.', $installedVersion);
|
||||
$installedMajor = $installedMajor[0] . '.' . $installedMajor[1];
|
||||
$currentMajor = explode('.', $currentVersion);
|
||||
$currentMajor = $currentMajor[0] . '.' . $currentMajor[1];
|
||||
if ($installedMajor === $currentMajor) {
|
||||
// Same major, allow downgrade for developers
|
||||
return true;
|
||||
} else {
|
||||
// downgrade attempt, throw exception
|
||||
throw new \OCP\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
|
||||
}
|
||||
} elseif ($versionDiff < 0) {
|
||||
// downgrade attempt, throw exception
|
||||
throw new \OCP\HintException('Downgrading is not supported and is likely to cause unpredictable issues (from ' . $installedVersion . ' to ' . $currentVersion . ')');
|
||||
}
|
||||
|
||||
// also check for upgrades for apps (independently from the user)
|
||||
$apps = \OC_App::getEnabledApps(false, true);
|
||||
$shouldUpgrade = false;
|
||||
foreach ($apps as $app) {
|
||||
if (\OC_App::shouldUpgrade($app)) {
|
||||
$shouldUpgrade = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $shouldUpgrade;
|
||||
} else {
|
||||
public static function needUpgrade(\OC\SystemConfig $config): bool {
|
||||
if (!$config->getValue('installed', false)) {
|
||||
// not installed (nothing to do)
|
||||
return false;
|
||||
}
|
||||
|
||||
$installedVersion = (string)$config->getValue('version', '0.0.0');
|
||||
$codeVersion = implode('.', \OCP\Util::getVersion());
|
||||
|
||||
// codebase newer: upgrade needed
|
||||
if (version_compare($codeVersion, $installedVersion, '>')) {
|
||||
// upgrade needed
|
||||
return true;
|
||||
}
|
||||
|
||||
// codebase older: downgrade attempt
|
||||
if (version_compare($codeVersion, $installedVersion, '<')) {
|
||||
// allow downgrade only in debug and when major.minor match
|
||||
if ($config->getValue('debug', false)) {
|
||||
$installedMajorMinor = self::getMajorMinor($installedVersion);
|
||||
$codeMajorMinor = self::getMajorMinor($codeVersion);
|
||||
if ($installedMajorMinor === $codeMajorMinor) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// disallow downgrade (not in debug mode or major.minor mismatch)
|
||||
/** @var \Psr\Log\LoggerInterface $logger */
|
||||
$logger = \OCP\Server::get(LoggerInterface::class);
|
||||
$logger->error(
|
||||
'Detected downgrade attempt from installed {installed} to code {code}',
|
||||
[ 'installed' => $installedVersion, 'code' => $codeVersion, 'app' => 'core', ]
|
||||
);
|
||||
throw new \OCP\HintException(sprintf(
|
||||
'Downgrading Nextcloud from %s to %s is not supported and may corrupt your instance (database and data directory). '
|
||||
. 'Restore a full backup (code, database, and data directory) taken before the change, '
|
||||
. 'or restore the previous codebase so that it matches the installed version (version %s).',
|
||||
$installedVersion, $codeVersion, $installedVersion
|
||||
));
|
||||
}
|
||||
|
||||
// versions are equal: check whether any enabled apps need upgrading
|
||||
$appManager = \OCP\Server::get(\OCP\App\IAppManager::class);
|
||||
$apps = $appManager->getEnabledApps();
|
||||
foreach ($apps as $app) {
|
||||
if ($appManager->isUpgradeRequired($app)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to return "major.minor" for a version string
|
||||
*/
|
||||
private static function getMajorMinor(string $version): string {
|
||||
$parts = explode('.', $version, 3);
|
||||
// we could sanity check/guard/fallback this more but there's only so much we can do...
|
||||
$major = $parts[0];
|
||||
$minor = $parts[1];
|
||||
return $major . '.' . $minor;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue