Merge pull request #12622 from nupplaphil/bug/config

`node.config.php` bugfixings
This commit is contained in:
Hypolite Petovan 2023-01-07 08:45:53 -05:00 committed by GitHub
commit 308618b559
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 457 additions and 325 deletions

View file

@ -359,7 +359,7 @@ class App
$this->profiler->update($this->config);
Core\Hook::loadHooks();
$loader = (new Config())->createConfigFileLoader($this->getBasePath(), $_SERVER);
$loader = (new Config())->createConfigFileManager($this->getBasePath(), $_SERVER);
Core\Hook::callAll('load_config', $loader);
// Hooks are now working, reload the whole definitions with hook enabled
@ -659,7 +659,7 @@ class App
$this->baseURL->redirect('install');
} else {
$this->checkURL();
Core\Update::check($this->getBasePath(), false, $this->mode);
Core\Update::check($this->getBasePath(), false);
Core\Addon::loadAddons();
Core\Hook::loadHooks();
}

View file

@ -56,7 +56,7 @@ class Config
*
* @return Util\ConfigFileManager
*/
public function createConfigFileLoader(string $basePath, array $server = []): Util\ConfigFileManager
public function createConfigFileManager(string $basePath, array $server = []): Util\ConfigFileManager
{
if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
$configDir = $server[self::CONFIG_DIR_ENV];
@ -65,19 +65,18 @@ class Config
}
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, new Util\ConfigFileTransformer());
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, $server);
}
/**
* @param Util\ConfigFileManager $configFileManager The Config Cache manager (INI/config/.htconfig)
* @param array $server
*
* @return Cache
*/
public function createCache(Util\ConfigFileManager $configFileManager, array $server = []): Cache
public function createCache(Util\ConfigFileManager $configFileManager): Cache
{
$configCache = new Cache();
$configFileManager->setupCache($configCache, $server);
$configFileManager->setupCache($configCache);
return $configCache;
}

View file

@ -39,19 +39,14 @@ class Config implements IManageConfigValues
/** @var ConfigFileManager */
protected $configFileManager;
/** @var array */
protected $server;
/**
* @param ConfigFileManager $configFileManager The configuration file manager to save back configs
* @param Cache $configCache The configuration cache (based on the config-files)
* @param array $server The $_SERVER variable
*/
public function __construct(ConfigFileManager $configFileManager, Cache $configCache, array $server = [])
public function __construct(ConfigFileManager $configFileManager, Cache $configCache)
{
$this->configFileManager = $configFileManager;
$this->configCache = $configCache;
$this->server = $server;
}
/**
@ -87,7 +82,7 @@ class Config implements IManageConfigValues
$configCache = new Cache();
try {
$this->configFileManager->setupCache($configCache, $this->server);
$this->configFileManager->setupCache($configCache);
} catch (ConfigFileException $e) {
throw new ConfigPersistenceException('Cannot reload config', $e);
}
@ -121,7 +116,7 @@ class Config implements IManageConfigValues
/** {@inheritDoc} */
public function delete(string $cat, string $key): bool
{
if ($this->configCache->delete($cat, $key)) {
if ($this->configCache->delete($cat, $key, Cache::SOURCE_DATA)) {
$this->save();
return true;
} else {

View file

@ -35,37 +35,13 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
protected $config;
/** @var Cache */
protected $cache;
/** @var Cache */
protected $delCache;
/** @var bool field to check if something is to save */
protected $changedConfig = false;
public function __construct(IManageConfigValues $config)
{
$this->config = $config;
$this->cache = new Cache();
$this->delCache = new Cache();
}
/**
* Get a particular user's config variable given the category name
* ($cat) and a $key from the current transaction.
*
* Isn't part of the interface because of it's rare use case
*
* @param string $cat The category of the configuration value
* @param string $key The configuration key to query
*
* @return mixed Stored value or null if it does not exist
*
* @throws ConfigPersistenceException In case the persistence layer throws errors
*
*/
public function get(string $cat, string $key)
{
return !$this->delCache->get($cat, $key) ?
($this->cache->get($cat, $key) ?? $this->config->get($cat, $key)) :
null;
$this->config = $config;
$this->cache = clone $config->getCache();
}
/** {@inheritDoc} */
@ -81,8 +57,7 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
/** {@inheritDoc} */
public function delete(string $cat, string $key): ISetConfigValuesTransactionally
{
$this->cache->delete($cat, $key);
$this->delCache->set($cat, $key, 'deleted');
$this->cache->delete($cat, $key, Cache::SOURCE_DATA);
$this->changedConfig = true;
return $this;
@ -97,13 +72,8 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
}
try {
$newCache = $this->config->getCache()->merge($this->cache);
$newCache = $newCache->diff($this->delCache);
$this->config->load($newCache);
// flush current cache
$this->cache = new Cache();
$this->delCache = new Cache();
$this->config->load($this->cache);
$this->cache = clone $this->config->getCache();
} catch (\Exception $e) {
throw new ConfigPersistenceException('Cannot save config', $e);
}

View file

@ -69,16 +69,22 @@ class ConfigFileManager
*/
private $staticDir;
/**
* @var array
*/
private $server;
/**
* @param string $baseDir The base
* @param string $configDir
* @param string $staticDir
*/
public function __construct(string $baseDir, string $configDir, string $staticDir)
public function __construct(string $baseDir, string $configDir, string $staticDir, array $server = [])
{
$this->baseDir = $baseDir;
$this->configDir = $configDir;
$this->staticDir = $staticDir;
$this->server = $server;
}
/**
@ -87,34 +93,33 @@ class ConfigFileManager
* First loads the default value for all the configuration keys, then the legacy configuration files, then the
* expected local.config.php
*
* @param Cache $config The config cache to load to
* @param array $server The $_SERVER array
* @param bool $raw Set up the raw config format
* @param Cache $configCache The config cache to load to
* @param bool $raw Set up the raw config format
*
* @throws ConfigFileException
*/
public function setupCache(Cache $config, array $server = [], bool $raw = false)
public function setupCache(Cache $configCache, bool $raw = false)
{
// Load static config files first, the order is important
$config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_STATIC);
$config->load($this->loadStaticConfig('settings'), Cache::SOURCE_STATIC);
$configCache->load($this->loadStaticConfig('defaults'), Cache::SOURCE_STATIC);
$configCache->load($this->loadStaticConfig('settings'), Cache::SOURCE_STATIC);
// try to load the legacy config first
$config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
$config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
$configCache->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
$configCache->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
// Now load every other config you find inside the 'config/' directory
$this->loadCoreConfig($config);
$this->loadCoreConfig($configCache);
// Now load the node.config.php file with the node specific config values (based on admin gui/console actions)
$this->loadDataConfig($config);
$this->loadDataConfig($configCache);
$config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
$configCache->load($this->loadEnvConfig(), Cache::SOURCE_ENV);
// In case of install mode, add the found basepath (because there isn't a basepath set yet
if (!$raw && empty($config->get('system', 'basepath'))) {
if (!$raw && empty($configCache->get('system', 'basepath'))) {
// Setting at least the basepath we know
$config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
$configCache->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
}
}
@ -134,7 +139,7 @@ class ConfigFileManager
if (file_exists($configName)) {
return $this->loadConfigFile($configName);
} elseif (file_exists($iniName)) {
} else if (file_exists($iniName)) {
return $this->loadINIConfigFile($iniName);
} else {
return [];
@ -144,82 +149,154 @@ class ConfigFileManager
/**
* Tries to load the specified core-configuration into the config cache.
*
* @param Cache $config The Config cache
* @param Cache $configCache The Config cache
*
* @throws ConfigFileException if the configuration file isn't readable
*/
private function loadCoreConfig(Cache $config)
private function loadCoreConfig(Cache $configCache)
{
// try to load legacy ini-files first
foreach ($this->getConfigFiles(true) as $configFile) {
$config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
$configCache->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
}
// try to load supported config at last to overwrite it
foreach ($this->getConfigFiles() as $configFile) {
$config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
$configCache->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
}
}
/**
* Tries to load the data config file with the overridden data
*
* @param Cache $config The Config cache
* @param Cache $configCache The Config cache
*
* @throws ConfigFileException In case the config file isn't loadable
*/
private function loadDataConfig(Cache $config)
private function loadDataConfig(Cache $configCache)
{
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
if (file_exists($filename)) {
// The fallback empty return content
$content = '<?php return [];';
/**
* This code-block creates a readonly node.config.php content stream (fopen() with "r")
* The stream is locked shared (LOCK_SH), so not exclusively, but the OS knows that there's a lock
*
* Any exclusive locking (LOCK_EX) would need to wait until all LOCK_SHs are unlocked
*/
$configStream = fopen($filename, 'r');
if (flock($configStream, LOCK_SH)) {
$content = fread($configStream, filesize($filename));
if (!$content) {
throw new ConfigFileException(sprintf('Couldn\'t read file %s', $filename));
try {
if (flock($configStream, LOCK_SH)) {
$content = fread($configStream, filesize($filename));
if (!$content) {
throw new ConfigFileException(sprintf('Couldn\'t read file %s', $filename));
}
}
} finally {
// unlock and close the stream for every circumstances
flock($configStream, LOCK_UN);
fclose($configStream);
}
fclose($configStream);
/**
* Evaluate the content string as PHP code
*
* @see https://www.php.net/manual/en/function.eval.php
*
* @note
* To leave the PHP mode, we have to use the appropriate PHP tags '?>' as prefix.
*/
$dataArray = eval('?>' . $content);
if (!is_array($dataArray)) {
throw new ConfigFileException(sprintf('Error loading config file %s', $filename));
if (is_array($dataArray)) {
$configCache->load($dataArray, Cache::SOURCE_DATA);
}
$config->load($dataArray, Cache::SOURCE_DATA);
}
}
/**
* Saves overridden config entries back into the data.config.phpR
* Saves overridden config entries back into the data.config.php
*
* @param Cache $config The config cache
* @param Cache $configCache The config cache
*
* @throws ConfigFileException In case the config file isn't writeable or the data is invalid
*/
public function saveData(Cache $config)
public function saveData(Cache $configCache)
{
$data = $config->getDataBySource(Cache::SOURCE_DATA);
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
$encodedData = ConfigFileTransformer::encode($data);
if (!$encodedData) {
throw new ConfigFileException('config source cannot get encoded');
if (file_exists($filename)) {
$fileExists = true;
} else {
$fileExists = false;
}
$configStream = fopen($this->configDir . '/' . self::CONFIG_DATA_FILE, 'w');
/**
* Creates a read-write stream
*
* @see https://www.php.net/manual/en/function.fopen.php
* @note Open the file for reading and writing. If the file does not exist, it is created.
* If it exists, it is neither truncated (as opposed to 'w'), nor the call to this function fails
* (as is the case with 'x'). The file pointer is positioned on the beginning of the file.
*
*/
$configStream = fopen($filename, 'c+');
if (flock($configStream, LOCK_EX)) {
fwrite($configStream, $encodedData);
fflush($configStream);
try {
// We do want an exclusive lock, so we wait until every LOCK_SH (config reading) is unlocked
if (flock($configStream, LOCK_EX)) {
/**
* If the file exists, we read the whole file again to avoid a race condition with concurrent threads that could have modified the file between the first config read of this thread and now
* Since we're currently exclusive locked, no other process can now change the config again
*/
if ($fileExists) {
// When reading the config file too fast, we get a wrong filesize, "clearstatcache" prevents that
clearstatcache(true, $filename);
$content = fread($configStream, filesize($filename));
if (!$content) {
throw new ConfigFileException(sprintf('Cannot read file %s', $filename));
}
// Event truncating the whole content wouldn't automatically rewind the stream,
// so we need to do it manually
rewind($configStream);
$dataArray = eval('?>' . $content);
// Merge the new content into the existing file based config cache and use it
// as the new config cache
if (is_array($dataArray)) {
$fileConfigCache = new Cache();
$fileConfigCache->load($dataArray, Cache::SOURCE_DATA);
$configCache = $fileConfigCache->merge($configCache);
}
}
// Only SOURCE_DATA is wanted, the rest isn't part of the node.config.php file
$data = $configCache->getDataBySource(Cache::SOURCE_DATA);
$encodedData = ConfigFileTransformer::encode($data);
if (!$encodedData) {
throw new ConfigFileException('config source cannot get encoded');
}
// Once again to avoid wrong, implicit "filesize" calls during the fwrite() or ftruncate() call
clearstatcache(true, $filename);
if (!ftruncate($configStream, 0) ||
!fwrite($configStream, $encodedData) ||
!fflush($configStream)) {
throw new ConfigFileException(sprintf('Cannot modify locked file %s', $filename));
}
}
} finally {
// unlock and close the stream for every circumstances
flock($configStream, LOCK_UN);
fclose($configStream);
}
}
@ -237,7 +314,7 @@ class ConfigFileManager
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
$name . DIRECTORY_SEPARATOR . // openstreetmap/
'config'. DIRECTORY_SEPARATOR . // config/
'config' . DIRECTORY_SEPARATOR . // config/
$name . ".config.php"; // openstreetmap.config.php
if (file_exists($filepath)) {
@ -250,13 +327,11 @@ class ConfigFileManager
/**
* Tries to load environment specific variables, based on the `env.config.php` mapping table
*
* @param array $server The $_SERVER variable
*
* @return array The config array (empty if no config was found)
*
* @throws ConfigFileException if the configuration file isn't readable
*/
public function loadEnvConfig(array $server): array
protected function loadEnvConfig(): array
{
$filepath = $this->staticDir . DIRECTORY_SEPARATOR . // /var/www/html/static/
"env.config.php"; // env.config.php
@ -270,8 +345,8 @@ class ConfigFileManager
$return = [];
foreach ($envConfig as $envKey => $configStructure) {
if (isset($server[$envKey])) {
$return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
if (isset($this->server[$envKey])) {
$return[$configStructure[0]][$configStructure[1]] = $this->server[$envKey];
}
}
@ -296,7 +371,9 @@ class ConfigFileManager
$sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
foreach ($files as $filename) {
if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
if (fnmatch($filePattern, $filename) &&
substr_compare($filename, $sampleEnd, -strlen($sampleEnd)) &&
$filename !== self::CONFIG_DATA_FILE) {
$found[] = $this->configDir . '/' . $filename;
}
}

View file

@ -34,6 +34,11 @@ class ConfigFileTransformer
$categories = array_keys($data);
foreach ($categories as $category) {
if (is_null($data[$category])) {
$dataString .= "\t'$category' => null," . PHP_EOL;
continue;
}
$dataString .= "\t'$category' => [" . PHP_EOL;
if (is_array($data[$category])) {
@ -66,7 +71,9 @@ class ConfigFileTransformer
{
$string = str_repeat("\t", $level + 2) . "'$key' => ";
if (is_array($value)) {
if (is_null($value)) {
$string .= "null,";
} elseif (is_array($value)) {
$string .= "[" . PHP_EOL;
$string .= static::extractArray($value, ++$level);
$string .= str_repeat("\t", $level + 1) . '],';

View file

@ -65,7 +65,7 @@ class Cache
* @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
* @param int $source Sets a source of the initial config values
*/
public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
public function __construct(array $config = [], bool $hidePasswordOutput = true, int $source = self::SOURCE_DEFAULT)
{
$this->hidePasswordOutput = $hidePasswordOutput;
$this->load($config, $source);
@ -87,11 +87,10 @@ class Cache
$keys = array_keys($config[$category]);
foreach ($keys as $key) {
$value = $config[$category][$key];
if (isset($value)) {
$this->set($category, $key, $value, $source);
}
$this->set($category, $key, $config[$category][$key] ?? null, $source);
}
} else {
$this->set($category, null, $config[$category], $source);
}
}
}
@ -150,6 +149,8 @@ class Cache
$data[$category][$key] = $this->config[$category][$key];
}
}
} elseif (is_int($this->source[$category])) {
$data[$category] = null;
}
}
@ -159,40 +160,49 @@ class Cache
/**
* Sets a value in the config cache. Accepts raw output from the config table
*
* @param string $cat Config category
* @param string $key Config key
* @param mixed $value Value to set
* @param int $source The source of the current config key
* @param string $cat Config category
* @param ?string $key Config key
* @param ?mixed $value Value to set
* @param int $source The source of the current config key
*
* @return bool True, if the value is set
*/
public function set(string $cat, string $key, $value, int $source = self::SOURCE_DEFAULT): bool
public function set(string $cat, string $key = null, $value = null, int $source = self::SOURCE_DEFAULT): bool
{
if (!isset($this->config[$cat])) {
if (!isset($this->config[$cat]) && $key !== null) {
$this->config[$cat] = [];
$this->source[$cat] = [];
}
if (isset($this->source[$cat][$key]) &&
$source < $this->source[$cat][$key]) {
if ((isset($this->source[$cat][$key]) && $source < $this->source[$cat][$key]) ||
(is_int($this->source[$cat] ?? null) && $source < $this->source[$cat])) {
return false;
}
if ($this->hidePasswordOutput &&
$key == 'password' &&
is_string($value)) {
$this->config[$cat][$key] = new HiddenString((string)$value);
$this->setCatKeyValueSource($cat, $key, new HiddenString($value), $source);
} else if (is_string($value)) {
$this->config[$cat][$key] = self::toConfigValue($value);
$this->setCatKeyValueSource($cat, $key, self::toConfigValue($value), $source);
} else {
$this->config[$cat][$key] = $value;
$this->setCatKeyValueSource($cat, $key, $value, $source);
}
$this->source[$cat][$key] = $source;
return true;
}
private function setCatKeyValueSource(string $cat, string $key = null, $value = null, int $source = self::SOURCE_DEFAULT)
{
if (isset($key)) {
$this->config[$cat][$key] = $value;
$this->source[$cat][$key] = $source;
} else {
$this->config[$cat] = $value;
$this->source[$cat] = $source;
}
}
/**
* Formats a DB value to a config value
* - null = The db-value isn't set
@ -222,24 +232,27 @@ class Cache
/**
* Deletes a value from the config cache.
*
* @param string $cat Config category
* @param string $key Config key
* @param string $cat Config category
* @param ?string $key Config key (if not set, the whole category will get deleted)
* @param int $source The source of the current config key
*
* @return bool true, if deleted
*/
public function delete(string $cat, string $key): bool
public function delete(string $cat, string $key = null, int $source = self::SOURCE_DEFAULT): bool
{
if (isset($this->config[$cat][$key])) {
unset($this->config[$cat][$key]);
unset($this->source[$cat][$key]);
if (count($this->config[$cat]) == 0) {
unset($this->config[$cat]);
unset($this->source[$cat]);
$this->config[$cat][$key] = null;
$this->source[$cat][$key] = $source;
if (empty(array_filter($this->config[$cat], function($value) { return !is_null($value); }))) {
$this->config[$cat] = null;
$this->source[$cat] = $source;
}
return true;
} else {
return false;
} elseif (isset($this->config[$cat])) {
$this->config[$cat] = null;
$this->source[$cat] = $source;
}
return true;
}
/**
@ -302,39 +315,9 @@ class Cache
$newConfig[$category][$key] = $cache->config[$category][$key];
$newSource[$category][$key] = $cache->source[$category][$key];
}
}
}
$newCache = new Cache();
$newCache->config = $newConfig;
$newCache->source = $newSource;
return $newCache;
}
/**
* Diffs a new Cache into the existing one and returns the diffed Cache
*
* @param Cache $cache The cache, which should get deleted for the current Cache
*
* @return Cache The diffed Cache
*/
public function diff(Cache $cache): Cache
{
$newConfig = $this->config;
$newSource = $this->source;
$categories = array_keys($cache->config);
foreach ($categories as $category) {
if (is_array($cache->config[$category])) {
$keys = array_keys($cache->config[$category]);
foreach ($keys as $key) {
unset($newConfig[$category][$key]);
unset($newSource[$category][$key]);
}
} else {
$newConfig[$category] = $cache->config[$category];
$newSource[$category] = $cache->source[$category];
}
}

View file

@ -47,7 +47,7 @@ class Update
* @return void
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
public static function check(string $basePath, bool $via_worker, App\Mode $mode)
public static function check(string $basePath, bool $via_worker)
{
if (!DBA::connected()) {
return;
@ -61,8 +61,18 @@ class Update
$build = DI::config()->get('system', 'build');
if (empty($build)) {
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
$build = DB_UPDATE_VERSION - 1;
// legacy option - check if there's something in the Config table
if (DBStructure::existsTable('config')) {
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
if (!empty($dbConfig)) {
$build = $dbConfig['v'];
}
}
if (empty($build)) {
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
$build = DB_UPDATE_VERSION - 1;
}
}
// We don't support upgrading from very old versions anymore
@ -119,11 +129,21 @@ class Update
DI::lock()->release('dbupdate', true);
}
$build = DI::config()->get('system', 'build', null);
$build = DI::config()->get('system', 'build');
if (empty($build) || ($build > DB_UPDATE_VERSION)) {
$build = DB_UPDATE_VERSION - 1;
DI::config()->set('system', 'build', $build);
if (empty($build)) {
// legacy option - check if there's something in the Config table
if (DBStructure::existsTable('config')) {
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
if (!empty($dbConfig)) {
$build = $dbConfig['v'];
}
}
if (empty($build) || ($build > DB_UPDATE_VERSION)) {
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
$build = DB_UPDATE_VERSION - 1;
}
}
if ($build != DB_UPDATE_VERSION || $force) {
@ -141,11 +161,21 @@ class Update
Logger::notice('Update starting.', ['from' => $stored, 'to' => $current]);
// Checks if the build changed during Lock acquiring (so no double update occurs)
$retryBuild = DI::config()->get('system', 'build', null);
if ($retryBuild !== $build) {
Logger::notice('Update already done.', ['from' => $stored, 'to' => $current]);
DI::lock()->release('dbupdate');
return '';
$retryBuild = DI::config()->get('system', 'build');
if ($retryBuild != $build) {
// legacy option - check if there's something in the Config table
if (DBStructure::existsTable('config')) {
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
if (!empty($dbConfig)) {
$retryBuild = intval($dbConfig['v']);
}
}
if ($retryBuild != $build) {
Logger::notice('Update already done.', ['from' => $build, 'retry' => $retryBuild, 'to' => $current]);
DI::lock()->release('dbupdate');
return '';
}
}
DI::config()->set('system', 'maintenance', 1);

View file

@ -1315,8 +1315,8 @@ class Worker
return $added;
}
// Quit on daemon mode
if (Worker\Daemon::isMode()) {
// Quit on daemon mode, except the priority is critical (like for db updates)
if (Worker\Daemon::isMode() && $priority !== self::PRIORITY_CRITICAL) {
return $added;
}

View file

@ -154,7 +154,7 @@ class Summary extends BaseAdmin
}
// check legacy basepath settings
$configLoader = (new Config())->createConfigFileLoader($a->getBasePath(), $_SERVER);
$configLoader = (new Config())->createConfigFileManager($a->getBasePath(), $_SERVER);
$configCache = new Cache();
$configLoader->setupCache($configCache);
$confBasepath = $configCache->get('system', 'basepath');