Allow direct restore from the internal Docker backups volume.
This commit is contained in:
parent
1573391d01
commit
f7d33b3d3b
28
docker.sh
28
docker.sh
|
@ -664,6 +664,14 @@ backup() {
|
||||||
# ./docker.sh restore [/custom/backup/dir/custombackupname.zip]
|
# ./docker.sh restore [/custom/backup/dir/custombackupname.zip]
|
||||||
#
|
#
|
||||||
restore() {
|
restore() {
|
||||||
|
if [[ ! -f .env ]] || [[ ! -f azuracast.env ]]; then
|
||||||
|
echo "AzuraCast hasn't been installed yet on this server."
|
||||||
|
echo "You should run './docker.sh install' first before restoring."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ask "Restoring will remove any existing AzuraCast installation data, replacing it with your backup. Continue?" Y; then
|
||||||
|
if [[ $1 != "" ]]; then
|
||||||
local BACKUP_PATH BACKUP_DIR BACKUP_FILENAME BACKUP_EXT
|
local BACKUP_PATH BACKUP_DIR BACKUP_FILENAME BACKUP_EXT
|
||||||
BACKUP_PATH=$(readlink -f ${1:-"./backup.tar.gz"})
|
BACKUP_PATH=$(readlink -f ${1:-"./backup.tar.gz"})
|
||||||
BACKUP_DIR=$(dirname -- "$BACKUP_PATH")
|
BACKUP_DIR=$(dirname -- "$BACKUP_PATH")
|
||||||
|
@ -671,20 +679,12 @@ restore() {
|
||||||
BACKUP_EXT="${BACKUP_FILENAME##*.}"
|
BACKUP_EXT="${BACKUP_FILENAME##*.}"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
if [[ ! -f .env ]] || [[ ! -f azuracast.env ]]; then
|
|
||||||
echo "AzuraCast hasn't been installed yet on this server."
|
|
||||||
echo "You should run './docker.sh install' first before restoring."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -f ${BACKUP_PATH} ]]; then
|
if [[ ! -f ${BACKUP_PATH} ]]; then
|
||||||
echo "File '${BACKUP_PATH}' does not exist. Nothing to restore."
|
echo "File '${BACKUP_PATH}' does not exist. Nothing to restore."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ask "Restoring will remove any existing AzuraCast installation data, replacing it with your backup. Continue?" Y; then
|
|
||||||
docker-compose down -v
|
docker-compose down -v
|
||||||
|
|
||||||
docker volume create azuracast_backups
|
docker volume create azuracast_backups
|
||||||
|
|
||||||
# Move from local filesystem to Docker volume
|
# Move from local filesystem to Docker volume
|
||||||
|
@ -707,8 +707,18 @@ restore() {
|
||||||
|
|
||||||
docker-compose down
|
docker-compose down
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
fi
|
else
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Remove all volumes except the backup volume.
|
||||||
|
docker volume rm -f $(docker volume ls | grep -v "azuracast_backups" | awk 'NR>1 {print $2}')
|
||||||
|
|
||||||
|
docker-compose run --rm web -- azuracast_restore "$@"
|
||||||
|
|
||||||
|
docker-compose down
|
||||||
|
docker-compose up -d
|
||||||
|
fi
|
||||||
|
fi
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Console\Command\Backup;
|
namespace App\Console\Command\Backup;
|
||||||
|
|
||||||
|
use App\Entity\StorageLocation;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -22,7 +23,7 @@ class RestoreCommand extends AbstractBackupCommand
|
||||||
{
|
{
|
||||||
protected function configure(): void
|
protected function configure(): void
|
||||||
{
|
{
|
||||||
$this->addArgument('path', InputArgument::REQUIRED)
|
$this->addArgument('path', InputArgument::OPTIONAL)
|
||||||
->addOption('restore', null, InputOption::VALUE_NONE)
|
->addOption('restore', null, InputOption::VALUE_NONE)
|
||||||
->addOption('release', null, InputOption::VALUE_NONE);
|
->addOption('release', null, InputOption::VALUE_NONE);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +33,39 @@ class RestoreCommand extends AbstractBackupCommand
|
||||||
$io = new SymfonyStyle($input, $output);
|
$io = new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
$path = $input->getArgument('path');
|
$path = $input->getArgument('path');
|
||||||
|
|
||||||
$start_time = microtime(true);
|
$start_time = microtime(true);
|
||||||
|
|
||||||
$io->title('AzuraCast Restore');
|
$io->title('AzuraCast Restore');
|
||||||
$io->writeln('Please wait while the backup is restored...');
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
if ('/' !== $path[0]) {
|
if ('/' !== $path[0]) {
|
||||||
$path = '/var/azuracast/backups/' . $path;
|
$path = StorageLocation::DEFAULT_BACKUPS_PATH . '/' . $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($path)) {
|
if (!file_exists($path)) {
|
||||||
|
@ -52,6 +78,8 @@ class RestoreCommand extends AbstractBackupCommand
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$io->writeln('Please wait while the backup is restored...');
|
||||||
|
|
||||||
// Extract tar.gz archive
|
// Extract tar.gz archive
|
||||||
$io->section('Extracting backup file...');
|
$io->section('Extracting backup file...');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue