1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-13 18:32:41 +01:00
phorge-phorge/src/applications/config/check/PhabricatorSetupCheck.php
epriestley b0d815d157 Repair invalid configuration by setting values back to defaults
Summary:
When configuration is set incorrectly (e.g., of the wrong type), detect and repair it by setting it to the default value. A setup warning will be raised separately.

Notably, this removes the need to hard-code all the class types.

This runs separately from the "invalid config" check because we need to run it on every page, but do setup checks only once per restart (some of them are slow).

Also dirty setup when we edit configuration.

Test Plan: Set config incorrectly on purpose, saw Phabricator correct it on restart and on every subsequent page load until it was fixed.

Reviewers: btrahan, vrana

Reviewed By: vrana

CC: aran

Maniphest Tasks: T2292

Differential Revision: https://secure.phabricator.com/D4492
2013-01-17 16:25:38 -08:00

118 lines
3.2 KiB
PHP

<?php
abstract class PhabricatorSetupCheck {
private $issues;
abstract protected function executeChecks();
final protected function newIssue($key) {
$issue = id(new PhabricatorSetupIssue())
->setIssueKey($key);
$this->issues[$key] = $issue;
return $issue;
}
final public function getIssues() {
return $this->issues;
}
final public function runSetupChecks() {
$this->issues = array();
$this->executeChecks();
}
final public static function getOpenSetupIssueCount() {
$cache = PhabricatorCaches::getSetupCache();
return $cache->getKey('phabricator.setup.issues');
}
final public static function setOpenSetupIssueCount($count) {
$cache = PhabricatorCaches::getSetupCache();
$cache->setKey('phabricator.setup.issues', $count);
}
final public static function getConfigNeedsRepair() {
$cache = PhabricatorCaches::getSetupCache();
return $cache->getKey('phabricator.setup.needs-repair');
}
final public static function setConfigNeedsRepair($needs_repair) {
$cache = PhabricatorCaches::getSetupCache();
$cache->setKey('phabricator.setup.needs-repair', $needs_repair);
}
final public static function deleteSetupCheckCache() {
$cache = PhabricatorCaches::getSetupCache();
$cache->deleteKeys(
array(
'phabricator.setup.needs-repair',
'phabricator.setup.issues',
));
}
final public static function willProcessRequest() {
$issue_count = self::getOpenSetupIssueCount();
if ($issue_count === null) {
$issues = self::runAllChecks();
self::setOpenSetupIssueCount(count($issues));
}
// Try to repair configuration unless we have a clean bill of health on it.
// We need to keep doing this on every page load until all the problems
// are fixed, which is why it's separate from setup checks (which run
// once per restart).
$needs_repair = self::getConfigNeedsRepair();
if ($needs_repair !== false) {
$needs_repair = self::repairConfig();
self::setConfigNeedsRepair($needs_repair);
}
}
final public static function runAllChecks() {
$symbols = id(new PhutilSymbolLoader())
->setAncestorClass('PhabricatorSetupCheck')
->setConcreteOnly(true)
->selectAndLoadSymbols();
$checks = array();
foreach ($symbols as $symbol) {
$checks[] = newv($symbol['name'], array());
}
$issues = array();
foreach ($checks as $check) {
$check->runSetupChecks();
foreach ($check->getIssues() as $key => $issue) {
if (isset($issues[$key])) {
throw new Exception(
"Two setup checks raised an issue with key '{$key}'!");
}
$issues[$key] = $issue;
}
}
return $issues;
}
final public static function repairConfig() {
$needs_repair = false;
$options = PhabricatorApplicationConfigOptions::loadAllOptions();
foreach ($options as $option) {
try {
$option->getGroup()->validateOption(
$option,
PhabricatorEnv::getEnvConfig($option->getKey()));
} catch (PhabricatorConfigValidationException $ex) {
PhabricatorEnv::repairConfig($option->getKey(), $option->getDefault());
$needs_repair = true;
}
}
return $needs_repair;
}
}