Compare commits

...
Author SHA1 Message Date
Christy Jacob 01f55445f1 feat: add new database cluster 2023-08-03 19:29:01 +04:00
Christy JacobandGitHub 875662c066 Merge pull request #5932 from appwrite/fix-missing-active-deployment
Bump console to fix missing active deployment bug
2023-08-02 22:56:13 +04:00
Steven Nguyen 30ef106406 Bump console to fix missing active deployment bug 2023-08-02 11:36:50 -07:00
Eldad A. FuxandGitHub 03aeea857c Merge pull request #5874 from appwrite/feat-upgrade-task
Feat upgrade task
2023-07-27 22:27:16 +03:00
Steven Nguyen 128b9d1b1b Prompt developer to confirm installing over existing install 2023-07-25 13:50:43 -07:00
Steven Nguyen d8ea72b49e Create a dedicated upgrade task
Before, we used the same command for both installation and upgrades.
This lead to problems because developers would try to upgrade in the
wrong folder and end up creating a new installation.

This new upgrade command validates the existence of an existing
installation before proceeding with the upgrade to ensure no new
installation is created when upgrading.
2023-07-24 15:34:38 -07:00
Steven Nguyen c32f8e49e2 Make the install path a class property
This makes it so the property can be used by subclasses.
2023-07-24 15:21:34 -07:00
Steven Nguyen 1989ff873e Fix install analytics 2023-07-24 15:17:52 -07:00
Steven Nguyen f164676b44 Fix install template paths 2023-07-24 15:15:31 -07:00
6 changed files with 96 additions and 21 deletions
+2 -1
View File
@@ -95,6 +95,7 @@ App::post('/v1/projects')
$backups['database_db_fra1_03'] = ['from' => '10:30', 'to' => '11:15'];
$backups['database_db_fra1_04'] = ['from' => '13:30', 'to' => '14:15'];
$backups['database_db_fra1_05'] = ['from' => '4:30', 'to' => '5:15'];
$backups['database_db_fra1_06'] = ['from' => '16:30', 'to' => '17:15'];
$databases = Config::getParam('pools-database', []);
@@ -118,7 +119,7 @@ App::post('/v1/projects')
}
}
if ($index = array_search('database_db_fra1_05', $databases)) {
if ($index = array_search('database_db_fra1_06', $databases)) {
$database = $databases[$index];
} else {
$database = $databases[array_rand($databases)];
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
php /usr/src/code/app/cli.php upgrade $@
+2
View File
@@ -22,6 +22,7 @@ use Appwrite\Platform\Tasks\VolumeSync;
use Appwrite\Platform\Tasks\CalcUsersStats;
use Appwrite\Platform\Tasks\CalcTierStats;
use Appwrite\Platform\Tasks\PatchDeleteProjectCollections;
use Appwrite\Platform\Tasks\Upgrade;
class Tasks extends Service
{
@@ -36,6 +37,7 @@ class Tasks extends Service
->addAction(Hamster::getName(), new Hamster())
->addAction(Doctor::getName(), new Doctor())
->addAction(Install::getName(), new Install())
->addAction(Upgrade::getName(), new Upgrade())
->addAction(Maintenance::getName(), new Maintenance())
->addAction(PatchCreateMissingSchedules::getName(), new PatchCreateMissingSchedules())
->addAction(ClearCardCache::getName(), new ClearCardCache())
+46 -19
View File
@@ -6,7 +6,8 @@ use Appwrite\Auth\Auth;
use Appwrite\Docker\Compose;
use Appwrite\Docker\Env;
use Appwrite\Utopia\View;
use Utopia\Analytics\GoogleAnalytics;
use Utopia\Analytics\Adapter\GoogleAnalytics;
use Utopia\Analytics\Event;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Validator\Text;
@@ -14,6 +15,8 @@ use Utopia\Platform\Action;
class Install extends Action
{
protected string $path = '/usr/src/code/appwrite';
public static function getName(): string
{
return 'install';
@@ -50,7 +53,6 @@ class Install extends Action
* 6. Run data migration
*/
$config = Config::getParam('variables');
$path = '/usr/src/code/appwrite';
$defaultHTTPPort = '80';
$defaultHTTPSPort = '443';
$vars = [];
@@ -70,19 +72,28 @@ class Install extends Action
Console::success('Starting Appwrite installation...');
// Create directory with write permissions
if (null !== $path && !\file_exists(\dirname($path))) {
if (!@\mkdir(\dirname($path), 0755, true)) {
Console::error('Can\'t create directory ' . \dirname($path));
if (null !== $this->path && !\file_exists(\dirname($this->path))) {
if (!@\mkdir(\dirname($this->path), 0755, true)) {
Console::error('Can\'t create directory ' . \dirname($this->path));
Console::exit(1);
}
}
$data = @file_get_contents($path . '/docker-compose.yml');
$data = @file_get_contents($this->path . '/docker-compose.yml');
if ($data !== false) {
if ($interactive == 'Y' && Console::isInteractive()) {
$answer = Console::confirm('Previous installation found, do you want to overwrite it? (Y/n)');
if ($answer !== 'Y') {
Console::info('No action taken.');
return;
}
}
$time = \time();
Console::info('Compose file found, creating backup: docker-compose.yml.' . $time . '.backup');
file_put_contents($path . '/docker-compose.yml.' . $time . '.backup', $data);
file_put_contents($this->path . '/docker-compose.yml.' . $time . '.backup', $data);
$compose = new Compose($data);
$appwrite = $compose->getService('appwrite');
$oldVersion = ($appwrite) ? $appwrite->getImageVersion() : null;
@@ -116,11 +127,11 @@ class Install extends Action
}
}
$data = @file_get_contents($path . '/.env');
$data = @file_get_contents($this->path . '/.env');
if ($data !== false) { // Fetch all env vars from previous .env file
Console::info('Env file found, creating backup: .env.' . $time . '.backup');
file_put_contents($path . '/.env.' . $time . '.backup', $data);
file_put_contents($this->path . '/.env.' . $time . '.backup', $data);
$env = new Env($data);
foreach ($env->list() as $key => $value) {
@@ -198,8 +209,8 @@ class Install extends Action
}
}
$templateForCompose = new View(__DIR__ . '/../views/install/compose.phtml');
$templateForEnv = new View(__DIR__ . '/../views/install/env.phtml');
$templateForCompose = new View(__DIR__ . '/../../../../app/views/install/compose.phtml');
$templateForEnv = new View(__DIR__ . '/../../../../app/views/install/env.phtml');
$templateForCompose
->setParam('httpPort', $httpPort)
@@ -213,16 +224,24 @@ class Install extends Action
->setParam('vars', $input)
;
if (!file_put_contents($path . '/docker-compose.yml', $templateForCompose->render(false))) {
if (!file_put_contents($this->path . '/docker-compose.yml', $templateForCompose->render(false))) {
$message = 'Failed to save Docker Compose file';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$event = new Event();
$event->setName(APP_VERSION_STABLE . ' - ' . $message)
->addProp('category', 'install/server')
->addProp('action', 'install');
$analytics->createEvent($event);
Console::error($message);
Console::exit(1);
}
if (!file_put_contents($path . '/.env', $templateForEnv->render(false))) {
if (!file_put_contents($this->path . '/.env', $templateForEnv->render(false))) {
$message = 'Failed to save environment variables file';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$event = new Event();
$event->setName(APP_VERSION_STABLE . ' - ' . $message)
->addProp('category', 'install/server')
->addProp('action', 'install');
$analytics->createEvent($event);
Console::error($message);
Console::exit(1);
}
@@ -237,19 +256,27 @@ class Install extends Action
}
}
Console::log("Running \"docker compose -f {$path}/docker-compose.yml up -d --remove-orphans --renew-anon-volumes\"");
Console::log("Running \"docker compose -f {$this->path}/docker-compose.yml up -d --remove-orphans --renew-anon-volumes\"");
$exit = Console::execute("${env} docker compose -f {$path}/docker-compose.yml up -d --remove-orphans --renew-anon-volumes", '', $stdout, $stderr);
$exit = Console::execute("${env} docker compose -f {$this->path}/docker-compose.yml up -d --remove-orphans --renew-anon-volumes", '', $stdout, $stderr);
if ($exit !== 0) {
$message = 'Failed to install Appwrite dockers';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$event = new Event();
$event->setName(APP_VERSION_STABLE . ' - ' . $message)
->addProp('category', 'install/server')
->addProp('action', 'install');
$analytics->createEvent($event);
Console::error($message);
Console::error($stderr);
Console::exit($exit);
} else {
$message = 'Appwrite installed successfully';
$analytics->createEvent('install/server', 'install', APP_VERSION_STABLE . ' - ' . $message);
$event = new Event();
$event->setName(APP_VERSION_STABLE . ' - ' . $message)
->addProp('category', 'install/server')
->addProp('action', 'install');
$analytics->createEvent($event);
Console::success($message);
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace Appwrite\Platform\Tasks;
use Utopia\CLI\Console;
use Utopia\Validator\Text;
class Upgrade extends Install
{
public static function getName(): string
{
return 'upgrade';
}
public function __construct()
{
$this
->desc('Upgrade Appwrite')
->param('httpPort', '', new Text(4), 'Server HTTP port', true)
->param('httpsPort', '', new Text(4), 'Server HTTPS port', true)
->param('organization', 'appwrite', new Text(0), 'Docker Registry organization', true)
->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true)
->param('interactive', 'Y', new Text(1), 'Run an interactive session', true)
->callback(fn ($httpPort, $httpsPort, $organization, $image, $interactive) => $this->action($httpPort, $httpsPort, $organization, $image, $interactive));
}
public function action(string $httpPort, string $httpsPort, string $organization, string $image, string $interactive): void
{
// Check for previous installation
$data = @file_get_contents($this->path . '/docker-compose.yml');
if (empty($data)) {
Console::error('Appwrite installation not found.');
Console::log('The command was not run in the parent folder of your appwrite installation.');
Console::log('Please navigate to the parent directory of the Appwrite installation and try again.');
Console::log(' parent_directory <= you run the command in this directory');
Console::log(' └── appwrite');
Console::log(' └── docker-compose.yml');
Console::exit(1);
}
parent::action($httpPort, $httpsPort, $organization, $image, $interactive);
}
}