From 419fabd80aceda39fc58df3036d3d9f1d8a5e417 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Tue, 26 May 2020 20:11:20 +0300 Subject: [PATCH] Updated delete method to support recrusive deletes --- app/app.php | 9 +++- app/controllers/api/projects.php | 6 ++- app/workers/deletes.php | 57 ++++++++++++++++++++++++++ docker/supervisord.conf | 17 ++++++++ src/Appwrite/Storage/Device.php | 3 +- src/Appwrite/Storage/Devices/Local.php | 18 +++++++- 6 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 app/workers/deletes.php diff --git a/app/app.php b/app/app.php index a438950f3f..447a593ae1 100644 --- a/app/app.php +++ b/app/app.php @@ -27,6 +27,7 @@ $services = include __DIR__.'/config/services.php'; // List of services $webhook = new Event('v1-webhooks', 'WebhooksV1'); $audit = new Event('v1-audits', 'AuditsV1'); $usage = new Event('v1-usage', 'UsageV1'); +$deletes = new Event('v1-deletes', 'DeletesV1'); /** * Get All verified client URLs for both console and current projects @@ -215,10 +216,10 @@ $utopia->init(function () use ($utopia, $request, $response, &$user, $project, $ ; }); -$utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage, $mode, $project, $utopia) { +$utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage, $deletes, $mode, $project, $utopia) { /* - * Trigger Events for background jobs + * Trigger events for background workers */ if (!empty($webhook->getParam('event'))) { $webhook->trigger(); @@ -228,6 +229,10 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage $audit->trigger(); } + if (!empty($deletes->getParam('document'))) { + $deletes->trigger(); + } + $route = $utopia->match($request); if($project->getId() diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 0b1d46e60d..e839355dc5 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -1,6 +1,6 @@ delete('/v1/projects/:projectId') ->param('projectId', '', function () { return new UID(); }, 'Project unique ID.') ->param('password', '', function () { return new UID(); }, 'Your user password for confirmation.') ->action( - function ($projectId, $password) use ($response, $consoleDB, $user) { + function ($projectId, $password) use ($response, $consoleDB, $user, $deletes) { if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password throw new Exception('Invalid credentials', 401); } @@ -413,6 +413,8 @@ $utopia->delete('/v1/projects/:projectId') throw new Exception('Project not found', 404); } + $deletes->setParam('document', $project->getArrayCopy()); + foreach(['keys', 'webhooks', 'tasks', 'platforms', 'domains'] as $key) { // Delete all children (keys, webhooks, tasks [stop tasks?], platforms) $list = $project->getAttribute('webhooks', []); diff --git a/app/workers/deletes.php b/app/workers/deletes.php new file mode 100644 index 0000000000..a158a23926 --- /dev/null +++ b/app/workers/deletes.php @@ -0,0 +1,57 @@ +args['document']; + $document = new Document($document); + + switch ($document->getCollection()) { + case Database::SYSTEM_COLLECTION_PROJECTS: + $this->deleteProject($document); + break; + + default: + break; + } + } + + public function tearDown() + { + // ... Remove environment for this job + } + + protected function deleteProject(Document $document) + { + global $consoleDB; + + // Delete all DBs + $consoleDB->deleteNamespace($document->getId()); + $uploads = new Local(APP_STORAGE_UPLOADS.'/app-'.$document->getId()); + $cache = new Local(APP_STORAGE_CACHE.'/app-'.$document->getId()); + + // Optimize DB? + + // Delete all storage files + // Delete all storage cache + } +} diff --git a/docker/supervisord.conf b/docker/supervisord.conf index 78d2d0cade..747e4d590d 100644 --- a/docker/supervisord.conf +++ b/docker/supervisord.conf @@ -116,6 +116,23 @@ stdout_logfile_maxbytes=5000000 stderr_logfile=/dev/stderr stderr_logfile_maxbytes = 0 +[program:v1-deletes] +command=php /usr/share/nginx/html/vendor/bin/resque +autostart=true +autorestart=true +priority=10 +environment=QUEUE='v1-deletes',APP_INCLUDE='/usr/share/nginx/html/app/workers/deletes.php',REDIS_BACKEND='%(ENV__APP_REDIS_HOST)s:%(ENV__APP_REDIS_PORT)s' +stdout_events_enabled=true +stderr_events_enabled=true +stopsignal=QUIT +startretries=10 +;stdout_logfile=/dev/stdout +;stdout_logfile_maxbytes=0 +stdout_logfile=/var/log/appwrite.log +stdout_logfile_maxbytes=5000000 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes = 0 + [program:v1-certificates] command=php /usr/share/nginx/html/vendor/bin/resque autostart=true diff --git a/src/Appwrite/Storage/Device.php b/src/Appwrite/Storage/Device.php index 1f9eb940e4..5c1bd728a5 100644 --- a/src/Appwrite/Storage/Device.php +++ b/src/Appwrite/Storage/Device.php @@ -95,10 +95,11 @@ abstract class Device * @see http://php.net/manual/en/function.filesize.php * * @param string $path + * @param bool $recrusive * * @return bool */ - abstract public function delete(string $path):bool; + abstract public function delete(string $path, bool $recrusive):bool; /** * Returns given file path its size. diff --git a/src/Appwrite/Storage/Devices/Local.php b/src/Appwrite/Storage/Devices/Local.php index 17dbbb28ea..109b7a7983 100644 --- a/src/Appwrite/Storage/Devices/Local.php +++ b/src/Appwrite/Storage/Devices/Local.php @@ -151,12 +151,26 @@ class Local extends Device * @see http://php.net/manual/en/function.filesize.php * * @param string $path + * @param bool $recrusive * * @return bool */ - public function delete(string $path):bool + public function delete(string $path, bool $recrusive = false):bool { - return unlink($path); + if(is_dir($path) && $recrusive) { + $files = glob($path.'*', GLOB_MARK); // GLOB_MARK adds a slash to directories returned + + foreach($files as $file) { + $this->delete($file); + } + + rmdir($path); + } + elseif(is_file($path)) { + return unlink($path); + } + + return false; } /**