-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix installer state #11634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix installer state #11634
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||||||||||||||
| namespace Appwrite\Platform\Installer; | ||||||||||||||||||
|
|
||||||||||||||||||
| use Appwrite\Platform\Installer\Http\Installer\Error; | ||||||||||||||||||
| use Appwrite\Platform\Installer\Runtime\Config; | ||||||||||||||||||
| use Appwrite\Platform\Installer\Runtime\State; | ||||||||||||||||||
| use Swoole\Http\Server as SwooleServer; | ||||||||||||||||||
| use Utopia\Http\Adapter\Swoole\Request; | ||||||||||||||||||
|
|
@@ -136,6 +137,7 @@ private function startSwooleServer(string $host, int $port, ?string $readyFile = | |||||||||||||||||
|
|
||||||||||||||||||
| // Register resources for dependency injection into actions | ||||||||||||||||||
| $config = $this->state->buildConfig(); | ||||||||||||||||||
| $this->autoDetectUpgrade($config); | ||||||||||||||||||
| $paths = $this->paths; | ||||||||||||||||||
| $state = $this->state; | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -191,6 +193,77 @@ public function getNativeServer(): SwooleServer | |||||||||||||||||
| $adapter->start(); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| /** | ||||||||||||||||||
| * Auto-detect upgrade mode by checking for existing config files. | ||||||||||||||||||
| * Sets isUpgrade and lockedDatabase on the config when an existing | ||||||||||||||||||
| * installation is found and these values aren't already set. | ||||||||||||||||||
| */ | ||||||||||||||||||
| private function autoDetectUpgrade(Config $config): void | ||||||||||||||||||
| { | ||||||||||||||||||
| if ($config->isUpgrade()) { | ||||||||||||||||||
| return; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| $basePath = $config->isLocal() ? '/usr/src/code' : (getcwd() ?: '.'); | ||||||||||||||||||
| $composePath = $basePath . '/docker-compose.yml'; | ||||||||||||||||||
| $envPath = $basePath . '/.env'; | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!file_exists($composePath) && !file_exists($envPath)) { | ||||||||||||||||||
| return; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| $config->setIsUpgrade(true); | ||||||||||||||||||
|
|
||||||||||||||||||
| if ($config->getLockedDatabase() !== null) { | ||||||||||||||||||
| return; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| $database = $this->detectDatabaseFromFiles($composePath, $envPath); | ||||||||||||||||||
| if ($database !== null) { | ||||||||||||||||||
| $config->setLockedDatabase($database); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private function detectDatabaseFromFiles(string $composePath, string $envPath): ?string | ||||||||||||||||||
| { | ||||||||||||||||||
| $dbServices = ['mariadb', 'mongodb', 'postgresql']; | ||||||||||||||||||
|
|
||||||||||||||||||
| $composeData = @file_get_contents($composePath); | ||||||||||||||||||
| if ($composeData !== false) { | ||||||||||||||||||
| if (preg_match_all('/^\s*(?:container_name:\s*appwrite-(\w+)|(\w+):)\s*$/m', $composeData, $matches)) { | ||||||||||||||||||
| $serviceNames = array_filter(array_merge($matches[1], $matches[2])); | ||||||||||||||||||
| foreach ($dbServices as $db) { | ||||||||||||||||||
| if (in_array($db, $serviceNames, true)) { | ||||||||||||||||||
| return $db; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| foreach ($dbServices as $db) { | ||||||||||||||||||
| if (preg_match('/^\s*' . preg_quote($db, '/') . ':\s*$/m', $composeData)) { | ||||||||||||||||||
| return $db; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+241
to
+245
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The second The second loop can only execute if
Suggested change
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| $envData = @file_get_contents($envPath); | ||||||||||||||||||
| if ($envData !== false) { | ||||||||||||||||||
| if (preg_match('/^_APP_DB_ADAPTER=(.+)$/m', $envData, $m)) { | ||||||||||||||||||
| $adapter = trim($m[1], " \t\n\r\"'"); | ||||||||||||||||||
| if (in_array($adapter, $dbServices, true)) { | ||||||||||||||||||
| return $adapter; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| if (preg_match('/^_APP_DB_HOST=(.+)$/m', $envData, $m)) { | ||||||||||||||||||
| $host = trim($m[1], " \t\n\r\"'"); | ||||||||||||||||||
| if (in_array($host, $dbServices, true)) { | ||||||||||||||||||
| return $host; | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| return null; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| private function removeDockerInstallerContainer(string $container): void | ||||||||||||||||||
| { | ||||||||||||||||||
| $name = escapeshellarg($container); | ||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lockedDatabasedetection whenisUpgradeis already setIf
isUpgradeis alreadytrue(set explicitly in the saved config) butlockedDatabaseisnull, this early return means the database auto-detection never runs. ThelockedDatabasewill remainnulleven though the installation files are present and the database could be inferred.If there is a scenario where
isUpgradecan be persisted astruewithout a correspondinglockedDatabasevalue, the installer may behave incorrectly. Consider checkinglockedDatabaseindependently: