From f5eb3964c20ab3f9f1a9f1ec2ef373ea59650b95 Mon Sep 17 00:00:00 2001 From: fogelito Date: Wed, 13 Sep 2023 13:33:13 +0300 Subject: [PATCH] Add throw catch --- src/Appwrite/Platform/Tasks/Backup.php | 21 +-- src/Appwrite/Platform/Tasks/Restore.php | 195 ++++++++++++------------ 2 files changed, 105 insertions(+), 111 deletions(-) diff --git a/src/Appwrite/Platform/Tasks/Backup.php b/src/Appwrite/Platform/Tasks/Backup.php index 86e6239008..b0303417de 100644 --- a/src/Appwrite/Platform/Tasks/Backup.php +++ b/src/Appwrite/Platform/Tasks/Backup.php @@ -93,13 +93,15 @@ class Backup extends Action try { $this->start(); } catch (Exception $e) { - //todo: send alerts to admin! - // todo: Do we want to terminate the script? or wait for next backup iteration? + //todo: send alerts sentry? Console::error(date('Y-m-d H:i:s') . ' Error: ' . $e->getMessage()); } }, self::BACKUP_INTERVAL_SECONDS); } + /** + * @throws Exception + */ public function start(): void { $start = microtime(true); @@ -114,7 +116,7 @@ class Backup extends Action $backups = $local->getRoot() . '/files'; $tarFile = $local->getPath($filename); - $this->fullBackup($backups); + $this->backup($backups); $this->tar($backups, $tarFile); $this->upload($tarFile, $local); @@ -124,7 +126,7 @@ class Backup extends Action /** * @throws Exception */ - public function fullBackup(string $target) + public function backup(string $target) { $start = microtime(true); self::log('Xtrabackup start'); @@ -197,11 +199,6 @@ class Backup extends Action throw new Exception('Can\'t find tar file: ' . $file); } - $filesize = \filesize($file); - if ($filesize < 5 * 1024 * 1024) { - throw new Exception('Tar file size is very small: ' . $file); - } - self::log('Tar took ' . (microtime(true) - $start) . ' seconds'); } @@ -307,11 +304,7 @@ class Backup extends Action } $processors = str_replace(PHP_EOL, '', $stdout); - $processors = intval($processors); - - if ($processors === 0) { - throw new Exception('Set Processors Error'); - } + $processors = empty($processors) ? 1 : intval($processors); $this->processors = \max(1, $processors - 2); } diff --git a/src/Appwrite/Platform/Tasks/Restore.php b/src/Appwrite/Platform/Tasks/Restore.php index d68d5764f7..668d54d122 100644 --- a/src/Appwrite/Platform/Tasks/Restore.php +++ b/src/Appwrite/Platform/Tasks/Restore.php @@ -38,94 +38,93 @@ class Restore extends Action public function action(string $id, string $cloud, string $database): void { - $this->checkEnvVariables(); - $this->setContainerId(); - $this->setProcessors(); - - $datadir = self::DATADIR; - try { - $dsn = new DSN(App::getEnv('_APP_CONNECTIONS_BACKUPS_STORAGE', '')); - $this->s3 = new DOSpaces('/' . $database . '/full', $dsn->getUser(), $dsn->getPassword(), $dsn->getPath(), $dsn->getParam('region')); - $this->s3->setTransferChunkSize(40 * 1024 * 1024); // 5MB - } catch (\Exception $e) { - Console::error($e->getMessage() . 'Invalid DSN.'); - Console::exit(); - } + $this->checkEnvVariables(); + $this->setContainerId(); + $this->setProcessors(); - if (!file_exists($datadir)) { - Console::error('Datadir not found: ' . $datadir); - Console::exit(); - } + $datadir = self::DATADIR; - if (file_exists($datadir . '/sys') || file_exists($datadir . '/appwrite')) { - Console::error('Datadir ' . $datadir . ' must be empty!'); - //Console::exit(); - } - - $this->log('--- Restore Start ' . $id . ' --- '); - - $filename = $id . '.tar.gz'; - $start = microtime(true); - $cloud = $cloud === 'true' || $cloud === '1'; - - if ($cloud) { - $local = new Local(self::BACKUPS_PATH . '/downloads/' . $id); - - $files = $local->getRoot() . '/files'; - - if (!file_exists($files) && !mkdir($files, 0755, true)) { - Console::error('Error creating directory: ' . $files); - Console::exit(); + try { + $dsn = new DSN(App::getEnv('_APP_CONNECTIONS_BACKUPS_STORAGE', '')); + $this->s3 = new DOSpaces('/' . $database . '/full', $dsn->getUser(), $dsn->getPassword(), $dsn->getPath(), $dsn->getParam('region')); + $this->s3->setTransferChunkSize(40 * 1024 * 1024); // 5MB + } catch (\Exception $e) { + throw new Exception($e->getMessage() . 'Invalid DSN.'); } - $file = $local->getPath($filename); - - if (!file_exists($file)) { - $this->download($file, $local); + if (!file_exists($datadir)) { + throw new Exception('Datadir not found: ' . $datadir); } - $this->untar($file, $files); - } else { - $local = new Local(self::BACKUPS_PATH . '/' . $database . '/full/' . $id); - $files = $local->getRoot() . '/files'; + if (count(scandir($datadir)) > 2) { + throw new Exception($datadir . ' must be empty!'); + } + + $this->log('--- Restore Start ' . $id . ' --- '); + + $filename = $id . '.tar.gz'; + $start = microtime(true); + $cloud = $cloud === 'true' || $cloud === '1'; + + if ($cloud) { + $local = new Local(self::BACKUPS_PATH . '/downloads/' . $id); + + $files = $local->getRoot() . '/files'; + + if (!file_exists($files) && !mkdir($files, 0755, true)) { + throw new Exception('Error creating directory: ' . $files); + } + + $file = $local->getPath($filename); + + if (!file_exists($file)) { + $this->download($file, $local); + } + + $this->untar($file, $files); + } else { + $local = new Local(self::BACKUPS_PATH . '/' . $database . '/full/' . $id); + $files = $local->getRoot() . '/files'; + } + + if (!file_exists($files)) { + throw new Exception('Directory not found: ' . $files); + } + + $this->decompress($files); + $this->prepare($files); + $this->restore($files, $cloud, $datadir); + + $this->log('Restore Finish in ' . (microtime(true) - $start) . ' seconds'); + } catch (Exception $e) { + //todo: send alerts sentry? + Console::error(date('Y-m-d H:i:s') . ' Error: ' . $e->getMessage()); } - - if (!file_exists($files)) { - Console::error('Directory not found: ' . $files); - Console::exit(); - } - - $this->decompress($files); - $this->prepare($files); - // $this->restore($files, $cloud, $datadir); - - $this->log('Restore Finish in ' . (microtime(true) - $start) . ' seconds'); } + /** + * @throws Exception + */ public function download(string $file, Device $local) { $this->log('Download start'); $filename = basename($file); - try { - $path = $this->s3->getPath($filename); + $path = $this->s3->getPath($filename); - if (!$this->s3->exists($path)) { - Console::error('File: ' . $path . ' does not exist on cloud'); - Console::exit(); - } + if (!$this->s3->exists($path)) { + throw new Exception('File: ' . $path . ' does not exist on cloud'); + } - if (!$this->s3->transfer($path, $file, $local)) { - Console::error('Error Downloading ' . $file); - Console::exit(); - } - } catch (Exception $e) { - Console::error($e->getMessage()); - Console::exit(); + if (!$this->s3->transfer($path, $file, $local)) { + throw new Exception('Error Downloading ' . $file); } } + /** + * @throws Exception + */ public function untar(string $file, string $directory) { $this->log('Untar Start'); @@ -135,16 +134,17 @@ class Restore extends Action $cmd = 'tar -xzf ' . $file . ' -C ' . $directory; Console::execute($cmd, '', $stdout, $stderr); if (!empty($stderr)) { - Console::error($stderr); - Console::exit(); + throw new Exception($stderr); } if (!file_exists($file)) { - Console::error('Restore file not found: ' . $file); - Console::exit(); + throw new Exception('Restore file not found: ' . $file); } } + /** + * @throws Exception + */ public function decompress(string $target) { $this->log('Decompress start'); @@ -156,7 +156,7 @@ class Restore extends Action '--decompress', '--strict', '--remove-original', - '--compress-threads=' . $this->processors / 2, + '--compress-threads=' . $this->processors, '--parallel=' . $this->processors, '--target-dir=' . $target, '2> ' . $logfile, @@ -168,18 +168,19 @@ class Restore extends Action $stderr = shell_exec('tail -1 ' . $logfile); if (!str_contains($stderr, 'completed OK!')) { - Console::error('Decompress failed'); - Console::exit(); + throw new Exception('Decompress failed'); } } + /** + * @throws Exception + */ public function prepare(string $target) { $this->log('Prepare start'); if (!file_exists($target)) { - Console::error('prepare error directory not found: ' . $target); - Console::exit(); + throw new Exception('prepare error directory not found: ' . $target); } $logfile = $target . '/../log.txt'; @@ -199,18 +200,19 @@ class Restore extends Action $stderr = shell_exec('tail -1 ' . $logfile); if (!str_contains($stderr, 'completed OK!')) { - Console::error(date('Y-m-d H:i:s') . ' Prepare failed:' . $stderr); - Console::exit(); + throw new Exception(' Prepare failed:' . $stderr); } } + /** + * @throws Exception + */ public function restore(string $target, bool $cloud, string $datadir) { $this->log('Restore start'); if (!file_exists($target)) { - Console::error('restore error directory not found: ' . $target); - Console::exit(); + throw new Exception('Error Restoring directory not found: ' . $target); } $logfile = $target . '/../log.txt'; @@ -231,11 +233,13 @@ class Restore extends Action $stderr = shell_exec('tail -1 ' . $logfile); if (!str_contains($stderr, 'completed OK!')) { - Console::error(date('Y-m-d H:i:s') . ' Restore failed: ' . $stderr); - Console::exit(); + throw new Exception('Restore failed: ' . $stderr); } } + /** + * @throws Exception + */ public function checkEnvVariables(): void { foreach ( @@ -245,8 +249,7 @@ class Restore extends Action ] as $env ) { if (empty(App::getEnv($env))) { - Console::error('Can\'t read ' . $env); - Console::exit(); + throw new Exception('Can\'t read ' . $env); } } } @@ -258,42 +261,40 @@ class Restore extends Action } } + /** + * @throws Exception + */ public function setContainerId() { $stdout = ''; $stderr = ''; Console::execute('docker ps -f "name=xtrabackup" --format "{{.ID}}"', '', $stdout, $stderr); if (!empty($stderr)) { - Console::error('Error setting container Id: ' . $stderr); - Console::exit(); + throw new Exception('Error setting container Id: ' . $stderr); } $containerId = str_replace(PHP_EOL, '', $stdout); if (empty($containerId)) { - Console::error('Xtrabackup Container ID not found'); - Console::exit(); + throw new Exception('Xtrabackup Container ID not found'); } $this->xtrabackupContainerId = $containerId; } + /** + * @throws Exception + */ public function setProcessors() { $stdout = ''; $stderr = ''; Console::execute('docker exec ' . $this->xtrabackupContainerId . ' nproc', '', $stdout, $stderr); if (!empty($stderr)) { - Console::error('Error setting processors: ' . $stderr); - Console::exit(); + throw new Exception('Error setting processors: ' . $stderr); } $processors = str_replace(PHP_EOL, '', $stdout); - $processors = intval($processors); - - if ($processors === 0) { - Console::error('Set Processors Error'); - Console::exit(); - } + $processors = empty($processors) ? 1 : intval($processors); $this->processors = \max(1, $processors - 2); }