2021-12-08 23:58:28 +00:00
|
|
|
<?php
|
|
|
|
|
2021-12-23 22:22:25 +00:00
|
|
|
namespace SparkPlug\Com\Noccy\Docker\Commands;
|
2021-12-08 23:58:28 +00:00
|
|
|
|
|
|
|
use Spark\Commands\Command;
|
|
|
|
use SparkPlug;
|
|
|
|
use Symfony\Component\Console\Input\Input;
|
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
|
|
|
|
class DockerDbExportCommand extends Command
|
|
|
|
{
|
|
|
|
protected function configure()
|
|
|
|
{
|
|
|
|
$this->setName("docker:db:export")
|
|
|
|
->setDescription("Export a database")
|
|
|
|
->addOption("mysql", null, InputOption::VALUE_NONE, "Export from a MySQL database")
|
|
|
|
->addOption("dsn", null, InputOption::VALUE_REQUIRED, "Database DSN")
|
|
|
|
->addOption("service", null, InputOption::VALUE_REQUIRED, "Service name in stack")
|
|
|
|
->addOption("database", null, InputOption::VALUE_REQUIRED, "Database name")
|
|
|
|
->addOption("output", "o", InputOption::VALUE_REQUIRED, "Output to file instead of stdout")
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output)
|
|
|
|
{
|
|
|
|
$docker = get_plugin("com.noccy.docker");
|
|
|
|
|
|
|
|
$service = $input->getOption("service");
|
|
|
|
$dsn = $input->getOption("dsn");
|
|
|
|
if ($service) {
|
|
|
|
$stack = $docker->getComposeStack();
|
|
|
|
if ($input->getOption("mysql")) {
|
|
|
|
$dbtype = 'mysql';
|
|
|
|
} else {
|
|
|
|
$services = $stack->getServiceNames();
|
|
|
|
if (!in_array($service, $services)) {
|
|
|
|
$output->writeln("<error>Invalid service {$service}. Valid are ".join(", ", $services)."</>");
|
|
|
|
return Command::INVALID;
|
|
|
|
}
|
|
|
|
$image = $stack->getService($service)->getImage();
|
|
|
|
if (preg_match('/(mysql|mariadb)/i', $image)) {
|
|
|
|
$dbtype = 'mysql';
|
|
|
|
$env = $stack->getService($service)->getEnvironment();
|
|
|
|
$database = $env['MYSQL_DATABASE']??null;
|
|
|
|
if ($dbpass = $env['MYSQL_ROOT_PASSWORD']??null) {
|
|
|
|
$dbuser = 'root';
|
|
|
|
} else {
|
|
|
|
$dbuser = $env['MYSQL_USER']??null;
|
|
|
|
$dbpass = $env['MYSQL_PASSWORD']??null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$output->writeln("<error>Unable to determine database type from service</>");
|
|
|
|
return Command::INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$database = $database ?? $input->getOption("database");
|
|
|
|
if (empty($database)) {
|
|
|
|
$output->writeln("<error>No --database specified</>");
|
|
|
|
return Command::INVALID;
|
|
|
|
}
|
|
|
|
switch ($dbtype) {
|
|
|
|
case 'mysql':
|
|
|
|
$cmd = sprintf("mysqldump -u%s -p%s %s", $dbuser, $dbpass, $database);
|
|
|
|
break;
|
|
|
|
}
|
2021-12-11 00:44:01 +00:00
|
|
|
$this->exportFromService($service, $cmd, $output, $input->getOption("output"));
|
2021-12-08 23:58:28 +00:00
|
|
|
} elseif ($dsn) {
|
|
|
|
$url = parse_url($dsn);
|
|
|
|
if (empty($url)) {
|
|
|
|
$output->writeln("<error>Bad database DSN {$dsn}. Should look like mysql://user:pass@host:port/database</>");
|
|
|
|
return Command::INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Command::SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-12-11 00:44:01 +00:00
|
|
|
private function exportFromService(string $service, string $command, OutputInterface $output, ?string $outfile=null)
|
2021-12-08 23:58:28 +00:00
|
|
|
{
|
|
|
|
$cmd = sprintf("docker-compose exec -T %s %s", $service, $command);
|
2021-12-11 00:44:01 +00:00
|
|
|
if ($outfile) {
|
|
|
|
$cmd .= " > ".escapeshellarg($outfile);
|
|
|
|
}
|
|
|
|
$output->writeln(sprintf("→ <info>%s</>", $cmd));
|
2021-12-08 23:58:28 +00:00
|
|
|
passthru($cmd);
|
|
|
|
}
|
|
|
|
}
|