diff --git a/bin/kloud b/bin/kloud index 67aa541..df8d656 100755 --- a/bin/kloud +++ b/bin/kloud @@ -118,6 +118,11 @@ $app->addCommands([ Command\Environment\Database\DumpCommand::$defaultName, $app, )), + + (new Command\Environment\Database\LoadCommand( + Command\Environment\Database\LoadCommand::$defaultName, + $app, + )), ]); $app->run(new ArgvInput($argv), new ConsoleOutput()); diff --git a/src/Platform/Console/Command/Environment/Database/DumpCommand.php b/src/Platform/Console/Command/Environment/Database/DumpCommand.php index 5a8f8f0..4747008 100644 --- a/src/Platform/Console/Command/Environment/Database/DumpCommand.php +++ b/src/Platform/Console/Command/Environment/Database/DumpCommand.php @@ -105,7 +105,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $sqlService = $format->askQuestion(new Question('What is the name of your SQL service?', 'sql')); $process = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'cd', $remoteProjectPath, '&&', 'docker-compose', 'ps', '-q', $sqlService]); - try { $process->mustRun(); $containerIds = rtrim($process->getOutput(), PHP_EOL); @@ -130,7 +129,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if ('postgresql' === $dbms) { $process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'pg_dump', '-U', $username, $databaseName, '>', $dumpPath]); try { - $process2->mustRun(); + $process2->setTimeout(0)->mustRun(); $format->success('Dump well created at '.$host->getUser().'@'.$host->getHostname().':'.$dumpPath); return 0; @@ -142,7 +141,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } else { $process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', $containerIds, '/usr/bin/mysqldump', '-u', $username, '--password='.$password, $databaseName, '>', $dumpPath]); try { - $process2->mustRun(); + $process2->setTimeout(0)->mustRun(); $format->success('Dump well created at '.$host->getUser().'@'.$host->getHostname().':'.$dumpPath); return 0; diff --git a/src/Platform/Console/Command/Environment/Database/LoadCommand.php b/src/Platform/Console/Command/Environment/Database/LoadCommand.php new file mode 100644 index 0000000..b6b89e8 --- /dev/null +++ b/src/Platform/Console/Command/Environment/Database/LoadCommand.php @@ -0,0 +1,155 @@ +console = $console; + $this->wizard = new EnvironmentWizard(); + parent::__construct($name); + } + + protected function configure() + { + $this->setDescription('Dumps the database in the current state'); + + $this->wizard->configureConsoleCommand($this); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $workingDirectory = $input->getOption('working-directory') ?: getcwd(); + + $finder = (new Finder()) + ->files() + ->ignoreDotFiles(false) + ->in($workingDirectory); + + $format = new SymfonyStyle($input, $output); + + $serializer = new Serializer( + [ + new CustomNormalizer(), + new PropertyNormalizer(), + ], + [ + new YamlEncoder(), + ] + ); + + if ($finder->hasResults()) { + foreach ($finder->name('/^\.?kloud.environment.ya?ml$/') as $environmentFile) { + try { + /** @var EnvironmentContext $environementContext */ + $environementContext = $serializer->deserialize($environmentFile->getContents(), EnvironmentContext::class, 'yaml'); + } catch (\Throwable $exception) { + $format->error($exception->getMessage()); + continue; + } + + break; + } + foreach ($finder->name('/^\.?kloud.ya?ml$/') as $stackFile) { + try { + /** @var StackContext $stackContext */ + $stackContext = $serializer->deserialize($stackFile->getContents(), StackContext::class, 'yaml'); + } catch (\Throwable $exception) { + $format->error($exception->getMessage()); + continue; + } + + break; + } + } + + if (!isset($environementContext)) { + $format->error('No .kloud.environment.yaml file found in your directory. You must initialize it using environment:init command'); + + return 1; + } + + $host = new Host($environementContext->deployment->server->hostname); + $host->port($environementContext->deployment->server->port); + $host->user($environementContext->deployment->server->username); + + $directories = explode('/', $workingDirectory); + $projectName = end($directories); + $remoteProjectPath = $environementContext->deployment->path.'/'.$projectName; + + $sqlService = $format->askQuestion(new Question('What is the name of your SQL service?', 'sql')); + $process = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'cd', $remoteProjectPath, '&&', 'docker-compose', 'ps', '-q', $sqlService]); + try { + $process->mustRun(); + $containerIds = rtrim($process->getOutput(), PHP_EOL); + } catch (\Exception $exception) { + $format->error($exception->getMessage()); + + return 1; + } + + if (!empty($stackContext->dbms)) { + $dbms = $stackContext->dbms; + } else { + $dbms = strtolower($format->askQuestion(new ChoiceQuestion('Is it a MySQL or PostgreSQL database?', ['MySQL', 'PostgreSQL']))); + } + + $dumpName = $format->askQuestion(new Question('Name of your SQL dump to load')); + $dumpPath = $remoteProjectPath.'/.docker/'.$dumpName; + $databaseName = $environementContext->database->databaseName; + $username = $environementContext->database->username; + $password = $environementContext->database->password; + + if ('postgresql' === $dbms) { + $process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'psql', '-U', $username, $databaseName, '<', $dumpPath]); + try { + $process2->setTimeout(0)->mustRun(); + $format->success('Dump well loaded'); + + return 0; + } catch (\Exception $exception) { + $format->error($exception->getMessage()); + + return 1; + } + } else { + $process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'mysql', '-u', $username, '--password='.$password, $databaseName, '<', $dumpPath]); + try { + $process2->setTimeout(0)->mustRun(); + $format->success('Dump well loaded'); + + return 0; + } catch (\Exception $exception) { + $format->error($exception->getMessage()); + + return 1; + } + } + } +}