2019-05-23 15:29:22 +00:00
|
|
|
<?php
|
2020-10-14 22:19:31 +00:00
|
|
|
|
2021-07-19 05:53:45 +00:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2020-09-21 14:06:24 +00:00
|
|
|
namespace App\Console\Command\Backup;
|
2019-05-23 15:29:22 +00:00
|
|
|
|
2022-06-24 15:36:55 +00:00
|
|
|
use App\Entity\StorageLocation;
|
2021-12-23 01:32:40 +00:00
|
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
|
|
use Symfony\Component\Console\Input\InputArgument;
|
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
|
use Symfony\Component\Console\Input\InputOption;
|
2019-05-23 15:29:22 +00:00
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
2022-04-13 02:30:19 +00:00
|
|
|
use Symfony\Component\Filesystem\Filesystem;
|
2020-10-14 22:19:31 +00:00
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
use const PATHINFO_EXTENSION;
|
2019-05-23 15:29:22 +00:00
|
|
|
|
2021-12-23 01:32:40 +00:00
|
|
|
#[AsCommand(
|
|
|
|
name: 'azuracast:restore',
|
|
|
|
description: 'Restore a backup previously generated by AzuraCast.',
|
|
|
|
)]
|
2022-05-07 13:50:48 +00:00
|
|
|
class RestoreCommand extends AbstractBackupCommand
|
2019-05-23 15:29:22 +00:00
|
|
|
{
|
2021-12-23 01:32:40 +00:00
|
|
|
protected function configure(): void
|
|
|
|
{
|
2022-06-24 15:36:55 +00:00
|
|
|
$this->addArgument('path', InputArgument::OPTIONAL)
|
2021-12-23 01:32:40 +00:00
|
|
|
->addOption('restore', null, InputOption::VALUE_NONE)
|
|
|
|
->addOption('release', null, InputOption::VALUE_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
|
|
{
|
|
|
|
$io = new SymfonyStyle($input, $output);
|
|
|
|
|
|
|
|
$path = $input->getArgument('path');
|
2019-05-24 22:23:27 +00:00
|
|
|
$start_time = microtime(true);
|
|
|
|
|
2019-05-23 15:29:22 +00:00
|
|
|
$io->title('AzuraCast Restore');
|
2022-06-24 15:36:55 +00:00
|
|
|
|
|
|
|
if (empty($path)) {
|
|
|
|
$filesRaw = glob(StorageLocation::DEFAULT_BACKUPS_PATH . '/*', GLOB_NOSORT) ?: [];
|
|
|
|
usort(
|
|
|
|
$filesRaw,
|
|
|
|
static fn($a, $b) => filemtime($b) <=> filemtime($a)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (0 === count($filesRaw)) {
|
|
|
|
$io->getErrorStyle()
|
|
|
|
->error('Backups directory has no available files. You must explicitly specify a backup file.');
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
$files = [];
|
|
|
|
$i = 1;
|
|
|
|
foreach ($filesRaw as $filePath) {
|
|
|
|
$files[$i] = basename($filePath);
|
|
|
|
|
|
|
|
if (10 === $i) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
$path = $io->choice('Select backup file to restore:', $files, 1);
|
|
|
|
}
|
2019-05-23 15:29:22 +00:00
|
|
|
|
2019-09-10 23:10:57 +00:00
|
|
|
if ('/' !== $path[0]) {
|
2022-06-24 15:36:55 +00:00
|
|
|
$path = StorageLocation::DEFAULT_BACKUPS_PATH . '/' . $path;
|
2019-05-23 15:29:22 +00:00
|
|
|
}
|
|
|
|
|
2019-09-10 23:10:57 +00:00
|
|
|
if (!file_exists($path)) {
|
2022-05-07 16:44:14 +00:00
|
|
|
$io->getErrorStyle()->error(
|
|
|
|
sprintf(
|
|
|
|
__('Backup path %s not found!'),
|
|
|
|
$path
|
|
|
|
)
|
|
|
|
);
|
2019-05-23 15:29:22 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2022-06-24 15:36:55 +00:00
|
|
|
$io->writeln('Please wait while the backup is restored...');
|
|
|
|
|
2019-05-23 15:29:22 +00:00
|
|
|
// Extract tar.gz archive
|
|
|
|
$io->section('Extracting backup file...');
|
|
|
|
|
2019-09-10 23:10:57 +00:00
|
|
|
$file_ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
2019-05-24 14:58:33 +00:00
|
|
|
|
2019-09-04 18:00:51 +00:00
|
|
|
switch ($file_ext) {
|
2021-12-13 03:37:13 +00:00
|
|
|
case 'tzst':
|
|
|
|
$this->passThruProcess(
|
|
|
|
$io,
|
|
|
|
[
|
|
|
|
'tar',
|
|
|
|
'-I',
|
|
|
|
'unzstd',
|
|
|
|
'-xvf',
|
|
|
|
$path,
|
|
|
|
],
|
|
|
|
'/'
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
|
2019-05-24 14:58:33 +00:00
|
|
|
case 'gz':
|
|
|
|
case 'tgz':
|
2020-12-11 02:43:58 +00:00
|
|
|
$this->passThruProcess(
|
|
|
|
$io,
|
|
|
|
[
|
|
|
|
'tar',
|
|
|
|
'zxvf',
|
|
|
|
$path,
|
|
|
|
],
|
|
|
|
'/'
|
|
|
|
);
|
2019-05-24 14:58:33 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'zip':
|
|
|
|
default:
|
2020-12-11 02:43:58 +00:00
|
|
|
$this->passThruProcess(
|
|
|
|
$io,
|
|
|
|
[
|
|
|
|
'unzip',
|
|
|
|
$path,
|
|
|
|
],
|
|
|
|
'/'
|
|
|
|
);
|
2019-05-24 14:58:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2019-05-23 15:29:22 +00:00
|
|
|
|
|
|
|
$io->newLine();
|
|
|
|
|
|
|
|
// Handle DB dump
|
|
|
|
$io->section('Importing database...');
|
|
|
|
|
|
|
|
$tmp_dir_mariadb = '/tmp/azuracast_backup_mariadb';
|
2019-09-04 18:00:51 +00:00
|
|
|
$path_db_dump = $tmp_dir_mariadb . '/db.sql';
|
2019-05-23 15:29:22 +00:00
|
|
|
|
|
|
|
if (!file_exists($path_db_dump)) {
|
|
|
|
$io->getErrorStyle()->error('Database backup file not found!');
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-12-23 01:32:40 +00:00
|
|
|
$conn = $this->em->getConnection();
|
2019-05-23 15:29:22 +00:00
|
|
|
|
2021-02-22 22:17:11 +00:00
|
|
|
// Drop all preloaded tables prior to running a DB dump backup.
|
|
|
|
$conn->executeQuery('SET FOREIGN_KEY_CHECKS = 0');
|
2021-02-22 21:05:11 +00:00
|
|
|
foreach ($conn->fetchFirstColumn('SHOW TABLES') as $table) {
|
2021-02-22 22:17:11 +00:00
|
|
|
$conn->executeQuery('DROP TABLE IF EXISTS ' . $conn->quoteIdentifier($table));
|
2021-02-22 21:05:11 +00:00
|
|
|
}
|
2021-02-22 22:17:11 +00:00
|
|
|
$conn->executeQuery('SET FOREIGN_KEY_CHECKS = 1');
|
2021-02-22 21:05:11 +00:00
|
|
|
|
2022-05-07 13:50:48 +00:00
|
|
|
[$commandFlags, $commandEnvVars] = $this->getDatabaseSettingsAsCliFlags();
|
|
|
|
|
|
|
|
$commandEnvVars['DB_DUMP'] = $path_db_dump;
|
2022-04-20 12:14:39 +00:00
|
|
|
|
2020-07-08 07:03:50 +00:00
|
|
|
$this->passThruProcess(
|
2019-05-23 15:29:22 +00:00
|
|
|
$io,
|
2022-05-07 13:50:48 +00:00
|
|
|
'mysql ' . implode(' ', $commandFlags) . ' $DB_DATABASE < $DB_DUMP',
|
2019-05-23 15:29:22 +00:00
|
|
|
$tmp_dir_mariadb,
|
2022-05-07 13:50:48 +00:00
|
|
|
$commandEnvVars
|
2019-05-23 15:29:22 +00:00
|
|
|
);
|
|
|
|
|
2022-04-13 02:30:19 +00:00
|
|
|
(new Filesystem())->remove($tmp_dir_mariadb);
|
2019-05-23 15:29:22 +00:00
|
|
|
$io->newLine();
|
|
|
|
|
|
|
|
// Update from current version to latest.
|
|
|
|
$io->section('Running standard updates...');
|
|
|
|
|
|
|
|
$this->runCommand($output, 'azuracast:setup', ['--update' => true]);
|
|
|
|
|
2019-05-24 22:23:27 +00:00
|
|
|
$end_time = microtime(true);
|
|
|
|
$time_diff = $end_time - $start_time;
|
|
|
|
|
2020-12-11 02:43:58 +00:00
|
|
|
$io->success(
|
|
|
|
[
|
|
|
|
'Restore complete in ' . round($time_diff, 3) . ' seconds.',
|
|
|
|
]
|
|
|
|
);
|
2019-05-23 15:29:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|