Skip to content

Commit e70ba8b

Browse files
committed
#12 : Add database:load cmd and timeout(0) to database:dump cmd
1 parent 3b874f2 commit e70ba8b

File tree

3 files changed

+162
-3
lines changed

3 files changed

+162
-3
lines changed

Diff for: bin/kloud

+5
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ $app->addCommands([
118118
Command\Environment\Database\DumpCommand::$defaultName,
119119
$app,
120120
)),
121+
122+
(new Command\Environment\Database\LoadCommand(
123+
Command\Environment\Database\LoadCommand::$defaultName,
124+
$app,
125+
)),
121126
]);
122127

123128
$app->run(new ArgvInput($argv), new ConsoleOutput());

Diff for: src/Platform/Console/Command/Environment/Database/DumpCommand.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
105105

106106
$sqlService = $format->askQuestion(new Question('What is the name of your SQL service?', 'sql'));
107107
$process = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'cd', $remoteProjectPath, '&&', 'docker-compose', 'ps', '-q', $sqlService]);
108-
109108
try {
110109
$process->mustRun();
111110
$containerIds = rtrim($process->getOutput(), PHP_EOL);
@@ -130,7 +129,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
130129
if ('postgresql' === $dbms) {
131130
$process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'pg_dump', '-U', $username, $databaseName, '>', $dumpPath]);
132131
try {
133-
$process2->mustRun();
132+
$process2->setTimeout(0)->mustRun();
134133
$format->success('Dump well created at '.$host->getUser().'@'.$host->getHostname().':'.$dumpPath);
135134

136135
return 0;
@@ -142,7 +141,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
142141
} else {
143142
$process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', $containerIds, '/usr/bin/mysqldump', '-u', $username, '--password='.$password, $databaseName, '>', $dumpPath]);
144143
try {
145-
$process2->mustRun();
144+
$process2->setTimeout(0)->mustRun();
146145
$format->success('Dump well created at '.$host->getUser().'@'.$host->getHostname().':'.$dumpPath);
147146

148147
return 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Kiboko\Cloud\Platform\Console\Command\Environment\Database;
6+
7+
use Deployer\Host\Host;
8+
use Kiboko\Cloud\Domain\Environment\DTO\Context as EnvironmentContext;
9+
use Kiboko\Cloud\Domain\Stack\DTO\Context as StackContext;
10+
use Kiboko\Cloud\Platform\Console\EnvironmentWizard;
11+
use Symfony\Component\Console\Application as Console;
12+
use Symfony\Component\Console\Command\Command;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
use Symfony\Component\Console\Question\ChoiceQuestion;
16+
use Symfony\Component\Console\Question\Question;
17+
use Symfony\Component\Console\Style\SymfonyStyle;
18+
use Symfony\Component\Finder\Finder;
19+
use Symfony\Component\Process\Process;
20+
use Symfony\Component\Serializer\Encoder\YamlEncoder;
21+
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
22+
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
23+
use Symfony\Component\Serializer\Serializer;
24+
25+
final class LoadCommand extends Command
26+
{
27+
public static $defaultName = 'environment:database:load';
28+
29+
private Console $console;
30+
private EnvironmentWizard $wizard;
31+
32+
public function __construct(?string $name, Console $console)
33+
{
34+
$this->console = $console;
35+
$this->wizard = new EnvironmentWizard();
36+
parent::__construct($name);
37+
}
38+
39+
protected function configure()
40+
{
41+
$this->setDescription('Dumps the database in the current state');
42+
43+
$this->wizard->configureConsoleCommand($this);
44+
}
45+
46+
protected function execute(InputInterface $input, OutputInterface $output)
47+
{
48+
$workingDirectory = $input->getOption('working-directory') ?: getcwd();
49+
50+
$finder = (new Finder())
51+
->files()
52+
->ignoreDotFiles(false)
53+
->in($workingDirectory);
54+
55+
$format = new SymfonyStyle($input, $output);
56+
57+
$serializer = new Serializer(
58+
[
59+
new CustomNormalizer(),
60+
new PropertyNormalizer(),
61+
],
62+
[
63+
new YamlEncoder(),
64+
]
65+
);
66+
67+
if ($finder->hasResults()) {
68+
foreach ($finder->name('/^\.?kloud.environment.ya?ml$/') as $environmentFile) {
69+
try {
70+
/** @var EnvironmentContext $environementContext */
71+
$environementContext = $serializer->deserialize($environmentFile->getContents(), EnvironmentContext::class, 'yaml');
72+
} catch (\Throwable $exception) {
73+
$format->error($exception->getMessage());
74+
continue;
75+
}
76+
77+
break;
78+
}
79+
foreach ($finder->name('/^\.?kloud.ya?ml$/') as $stackFile) {
80+
try {
81+
/** @var StackContext $stackContext */
82+
$stackContext = $serializer->deserialize($stackFile->getContents(), StackContext::class, 'yaml');
83+
} catch (\Throwable $exception) {
84+
$format->error($exception->getMessage());
85+
continue;
86+
}
87+
88+
break;
89+
}
90+
}
91+
92+
if (!isset($environementContext)) {
93+
$format->error('No .kloud.environment.yaml file found in your directory. You must initialize it using environment:init command');
94+
95+
return 1;
96+
}
97+
98+
$host = new Host($environementContext->deployment->server->hostname);
99+
$host->port($environementContext->deployment->server->port);
100+
$host->user($environementContext->deployment->server->username);
101+
102+
$directories = explode('/', $workingDirectory);
103+
$projectName = end($directories);
104+
$remoteProjectPath = $environementContext->deployment->path.'/'.$projectName;
105+
106+
$sqlService = $format->askQuestion(new Question('What is the name of your SQL service?', 'sql'));
107+
$process = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'cd', $remoteProjectPath, '&&', 'docker-compose', 'ps', '-q', $sqlService]);
108+
try {
109+
$process->mustRun();
110+
$containerIds = rtrim($process->getOutput(), PHP_EOL);
111+
} catch (\Exception $exception) {
112+
$format->error($exception->getMessage());
113+
114+
return 1;
115+
}
116+
117+
if (!empty($stackContext->dbms)) {
118+
$dbms = $stackContext->dbms;
119+
} else {
120+
$dbms = strtolower($format->askQuestion(new ChoiceQuestion('Is it a MySQL or PostgreSQL database?', ['MySQL', 'PostgreSQL'])));
121+
}
122+
123+
$dumpName = $format->askQuestion(new Question('Name of your SQL dump to load'));
124+
$dumpPath = $remoteProjectPath.'/.docker/'.$dumpName;
125+
$databaseName = $environementContext->database->databaseName;
126+
$username = $environementContext->database->username;
127+
$password = $environementContext->database->password;
128+
129+
if ('postgresql' === $dbms) {
130+
$process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'psql', '-U', $username, $databaseName, '<', $dumpPath]);
131+
try {
132+
$process2->setTimeout(0)->mustRun();
133+
$format->success('Dump well loaded');
134+
135+
return 0;
136+
} catch (\Exception $exception) {
137+
$format->error($exception->getMessage());
138+
139+
return 1;
140+
}
141+
} else {
142+
$process2 = new Process(['ssh', '-t', $host->getUser().'@'.$host->getHostname(), 'docker', 'exec', '-i', $containerIds, 'mysql', '-u', $username, '--password='.$password, $databaseName, '<', $dumpPath]);
143+
try {
144+
$process2->setTimeout(0)->mustRun();
145+
$format->success('Dump well loaded');
146+
147+
return 0;
148+
} catch (\Exception $exception) {
149+
$format->error($exception->getMessage());
150+
151+
return 1;
152+
}
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)