From: Dan Brown Date: Mon, 22 May 2023 08:03:59 +0000 (+0100) Subject: Improved symlink support for backup/restore X-Git-Url: http://source.bookstackapp.com/system-cli/commitdiff_plain/e6d2f17dac06a3a0431a27dda54aeae4de553f47 Improved symlink support for backup/restore Updates filesystem iteration to specifically handle symlinks when iterating through files, and uses the file's real path when fetching their contents. Fixes #10 Adds test to cover backup case. --- diff --git a/src/Commands/BackupCommand.php b/src/Commands/BackupCommand.php index 0c4f014..47da179 100644 --- a/src/Commands/BackupCommand.php +++ b/src/Commands/BackupCommand.php @@ -6,6 +6,7 @@ use Cli\Services\AppLocator; use Cli\Services\EnvironmentLoader; use Cli\Services\MySqlRunner; use Cli\Services\Paths; +use FilesystemIterator; use RecursiveDirectoryIterator; use SplFileInfo; use Symfony\Component\Console\Command\Command; @@ -158,12 +159,15 @@ final class BackupCommand extends Command */ protected function addFolderToZipRecursive(ZipArchive $zip, string $dirPath, string $targetZipPath): void { - $dirIter = new RecursiveDirectoryIterator($dirPath); + $dirIter = new RecursiveDirectoryIterator( + $dirPath, + FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::FOLLOW_SYMLINKS + ); $fileIter = new \RecursiveIteratorIterator($dirIter); /** @var SplFileInfo $file */ foreach ($fileIter as $file) { if (!$file->isDir()) { - $zip->addFile($file->getPathname(), $targetZipPath . '/' . $fileIter->getSubPathname()); + $zip->addFile($file->getRealPath(), $targetZipPath . '/' . $fileIter->getSubPathname()); } } } diff --git a/src/Services/AppLocator.php b/src/Services/AppLocator.php index 155b8bb..c972906 100644 --- a/src/Services/AppLocator.php +++ b/src/Services/AppLocator.php @@ -13,8 +13,6 @@ class AppLocator static::getCliDirectory(), ]; - var_dump($directoriesToSearch); - foreach ($directoriesToSearch as $directory) { if ($directory && static::isProbablyAppDirectory($directory)) { return $directory; diff --git a/src/Services/Directories.php b/src/Services/Directories.php index 6418235..8886c60 100644 --- a/src/Services/Directories.php +++ b/src/Services/Directories.php @@ -1,6 +1,7 @@ -fail("Error when setting up symlinks"); + } + } + + chdir('/var/www/bookstack-symlink-backup'); + $this->assertCount(0, glob('storage/backups/bookstack-backup-*.zip')); + $result = $this->runCommand('backup'); + $result->assertSuccessfulExit(); + $this->assertCount(1, glob('storage/backups/bookstack-backup-*.zip')); + $zipFile = glob('storage/backups/bookstack-backup-*.zip')[0]; + + $zip = new \ZipArchive(); + $zip->open($zipFile); + foreach ($symDirs as $dir) { + $fileData = $zip->getFromName("{$dir}/test.txt"); + $this->assertNotFalse($fileData); + $this->assertStringContainsString("Hello from {$dir}", $fileData); + } + $zip->close(); + + exec('rm -rf /symlinks'); + exec('rm -rf /var/www/bookstack-symlink-backup'); + } + } \ No newline at end of file diff --git a/tests/Commands/RestoreCommandTest.php b/tests/Commands/RestoreCommandTest.php index 288b056..93b27bf 100644 --- a/tests/Commands/RestoreCommandTest.php +++ b/tests/Commands/RestoreCommandTest.php @@ -162,6 +162,7 @@ class RestoreCommandTest extends TestCase $this->assertStringEqualsFile('/var/www/bookstack-symlink-restore/themes/test.txt', 'hello-themes'); exec('rm -rf /var/www/bookstack-symlink-restore'); + exec('rm -rf /symlinks'); } protected function buildZip(callable $builder): string