From c5e059c118e414d14c877e729dae308612594df9 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 20 Sep 2023 18:58:11 -0700 Subject: [PATCH 1/3] Fix delete function deployment Prior to this, deleting a VCS deployment would fail because the deployment path for VCS deployments are empty. Because an error gets thrown, the delete function would stop and not delete the build files. This change updates the worker to only delete the storage files if the path is set. --- app/workers/deletes.php | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/app/workers/deletes.php b/app/workers/deletes.php index f3968c07f2..51573a0267 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -679,12 +679,25 @@ class DeletesV1 extends Worker /** * Delete deployment files */ - Console::info("Deleting deployment files for deployment " . $deploymentId); - $storageFunctions = $this->getFunctionsDevice($projectId); - if ($storageFunctions->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted deployment files: ' . $document->getAttribute('path', '')); + $deploymentPath = $document->getAttribute('path', ''); + if (empty($deploymentPath)) { + Console::info("No deployment files for deployment " . $deploymentId); } else { - Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', '')); + Console::info("Deleting deployment files for deployment " . $deploymentId); + $storageFunctions = $this->getFunctionsDevice($projectId); + try { + if ($storageFunctions->delete($deploymentPath, true)) { + Console::success('Deleted deployment files: ' . $deploymentPath); + } else { + Console::error('Failed to delete deployment files: ' . $deploymentPath); + } + } catch (\Throwable $th) { + Console::error('Failed to delete deployment files: ' . $deploymentPath); + Console::error('[Error] Type: ' . get_class($th)); + Console::error('[Error] Message: ' . $th->getMessage()); + Console::error('[Error] File: ' . $th->getFile()); + Console::error('[Error] Line: ' . $th->getLine()); + } } /** @@ -695,10 +708,24 @@ class DeletesV1 extends Worker $this->deleteByGroup('builds', [ Query::equal('deploymentInternalId', [$deploymentInternalId]) ], $dbForProject, function (Document $document) use ($storageBuilds) { - if ($storageBuilds->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted build files: ' . $document->getAttribute('path', '')); - } else { - Console::error('Failed to delete build files: ' . $document->getAttribute('path', '')); + $buildPath = $document->getAttribute('path', ''); + if (empty($buildPath)) { + Console::info("No build files for build " . $document->getId()); + return; + } + + try { + if ($storageBuilds->delete($buildPath, true)) { + Console::success('Deleted build files: ' . $buildPath); + } else { + Console::error('Failed to delete build files: ' . $buildPath); + } + } catch (\Throwable $th) { + Console::error('Failed to delete deployment files: ' . $buildPath); + Console::error('[Error] Type: ' . get_class($th)); + Console::error('[Error] Message: ' . $th->getMessage()); + Console::error('[Error] File: ' . $th->getFile()); + Console::error('[Error] Line: ' . $th->getLine()); } }); From 9ca82b76627013b3e91de890142072778e2ee52e Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 20 Sep 2023 19:26:23 -0700 Subject: [PATCH 2/3] Fix missing resourceInternalId on deployments --- app/controllers/api/functions.php | 1 + app/controllers/api/vcs.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 7c51d5377e..6f342df214 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -84,6 +84,7 @@ $redeployVcs = function (Request $request, Document $function, Document $project Permission::delete(Role::any()), ], 'resourceId' => $function->getId(), + 'resourceInternalId' => $function->getInternalId(), 'resourceType' => 'functions', 'entrypoint' => $entrypoint, 'commands' => $function->getAttribute('commands', ''), diff --git a/app/controllers/api/vcs.php b/app/controllers/api/vcs.php index 2abf4ef30c..b0050c61d4 100644 --- a/app/controllers/api/vcs.php +++ b/app/controllers/api/vcs.php @@ -50,6 +50,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId $functionId = $resource->getAttribute('resourceId'); $function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId)); + $functionInternalId = $function->getInternalId(); $deploymentId = ID::unique(); $repositoryId = $resource->getId(); @@ -173,6 +174,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId Permission::delete(Role::any()), ], 'resourceId' => $functionId, + 'resourceInternalId' => $functionInternalId, 'resourceType' => 'functions', 'entrypoint' => $function->getAttribute('entrypoint'), 'commands' => $function->getAttribute('commands'), From bb70860b921ef2e02d9381bdfb07121ac41dcc44 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Wed, 20 Sep 2023 19:31:06 -0700 Subject: [PATCH 3/3] Fix deployment and build files deletion on function delete Make sure deployment and build paths exist before deleting fiels. --- app/workers/deletes.php | 119 +++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 51573a0267..118015ed28 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -14,6 +14,7 @@ use Utopia\Abuse\Adapters\TimeLimit; use Utopia\CLI\Console; use Utopia\Audit\Audit; use Utopia\Database\DateTime; +use Utopia\Storage\Device; require_once __DIR__ . '/../init.php'; @@ -620,33 +621,25 @@ class DeletesV1 extends Worker * Delete Deployments */ Console::info("Deleting deployments for function " . $functionId); - $storageFunctions = $this->getFunctionsDevice($projectId); + $deviceFunctions = $this->getFunctionsDevice($projectId); $deploymentInternalIds = []; $this->deleteByGroup('deployments', [ Query::equal('resourceInternalId', [$functionInternalId]) - ], $dbForProject, function (Document $document) use ($storageFunctions, &$deploymentInternalIds) { + ], $dbForProject, function (Document $document) use ($deviceFunctions, &$deploymentInternalIds) { $deploymentInternalIds[] = $document->getInternalId(); - if ($storageFunctions->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted deployment files: ' . $document->getAttribute('path', '')); - } else { - Console::error('Failed to delete deployment files: ' . $document->getAttribute('path', '')); - } + $this->deleteDeploymentFiles($deviceFunctions, $document); }); /** * Delete builds */ Console::info("Deleting builds for function " . $functionId); - $storageBuilds = $this->getBuildsDevice($projectId); + $deviceBuilds = $this->getBuildsDevice($projectId); foreach ($deploymentInternalIds as $deploymentInternalId) { $this->deleteByGroup('builds', [ Query::equal('deploymentInternalId', [$deploymentInternalId]) - ], $dbForProject, function (Document $document) use ($storageBuilds) { - if ($storageBuilds->delete($document->getAttribute('path', ''), true)) { - Console::success('Deleted build files: ' . $document->getAttribute('path', '')); - } else { - Console::error('Failed to delete build files: ' . $document->getAttribute('path', '')); - } + ], $dbForProject, function (Document $document) use ($deviceBuilds) { + $this->deleteBuildFiles($deviceBuilds, $document); }); } @@ -665,6 +658,58 @@ class DeletesV1 extends Worker $this->deleteRuntimes($document, $project); } + protected function deleteDeploymentFiles(Device $device, Document $deployment) + { + $deploymentId = $deployment->getId(); + $deploymentPath = $deployment->getAttribute('path', ''); + + if (empty($deploymentPath)) { + Console::info("No deployment files for deployment " . $deploymentId); + return; + } + + Console::info("Deleting deployment files for deployment " . $deploymentId); + + try { + if ($device->delete($deploymentPath, true)) { + Console::success('Deleted deployment files: ' . $deploymentPath); + } else { + Console::error('Failed to delete deployment files: ' . $deploymentPath); + } + } catch (\Throwable $th) { + Console::error('Failed to delete deployment files: ' . $deploymentPath); + Console::error('[Error] Type: ' . get_class($th)); + Console::error('[Error] Message: ' . $th->getMessage()); + Console::error('[Error] File: ' . $th->getFile()); + Console::error('[Error] Line: ' . $th->getLine()); + } + } + + protected function deleteBuildFiles(Device $device, Document $build) + { + $buildId = $build->getId(); + $buildPath = $build->getAttribute('path', ''); + + if (empty($buildPath)) { + Console::info("No build files for build " . $buildId); + return; + } + + try { + if ($device->delete($buildPath, true)) { + Console::success('Deleted build files: ' . $buildPath); + } else { + Console::error('Failed to delete build files: ' . $buildPath); + } + } catch (\Throwable $th) { + Console::error('Failed to delete deployment files: ' . $buildPath); + Console::error('[Error] Type: ' . get_class($th)); + Console::error('[Error] Message: ' . $th->getMessage()); + Console::error('[Error] File: ' . $th->getFile()); + Console::error('[Error] Line: ' . $th->getLine()); + } + } + /** * @param Document $document deployment document * @param Document $project @@ -679,54 +724,18 @@ class DeletesV1 extends Worker /** * Delete deployment files */ - $deploymentPath = $document->getAttribute('path', ''); - if (empty($deploymentPath)) { - Console::info("No deployment files for deployment " . $deploymentId); - } else { - Console::info("Deleting deployment files for deployment " . $deploymentId); - $storageFunctions = $this->getFunctionsDevice($projectId); - try { - if ($storageFunctions->delete($deploymentPath, true)) { - Console::success('Deleted deployment files: ' . $deploymentPath); - } else { - Console::error('Failed to delete deployment files: ' . $deploymentPath); - } - } catch (\Throwable $th) { - Console::error('Failed to delete deployment files: ' . $deploymentPath); - Console::error('[Error] Type: ' . get_class($th)); - Console::error('[Error] Message: ' . $th->getMessage()); - Console::error('[Error] File: ' . $th->getFile()); - Console::error('[Error] Line: ' . $th->getLine()); - } - } + $deviceFunctions = $this->getFunctionsDevice($projectId); + $this->deleteDeploymentFiles($deviceFunctions, $document); /** * Delete builds */ Console::info("Deleting builds for deployment " . $deploymentId); - $storageBuilds = $this->getBuildsDevice($projectId); + $deviceBuilds = $this->getBuildsDevice($projectId); $this->deleteByGroup('builds', [ Query::equal('deploymentInternalId', [$deploymentInternalId]) - ], $dbForProject, function (Document $document) use ($storageBuilds) { - $buildPath = $document->getAttribute('path', ''); - if (empty($buildPath)) { - Console::info("No build files for build " . $document->getId()); - return; - } - - try { - if ($storageBuilds->delete($buildPath, true)) { - Console::success('Deleted build files: ' . $buildPath); - } else { - Console::error('Failed to delete build files: ' . $buildPath); - } - } catch (\Throwable $th) { - Console::error('Failed to delete deployment files: ' . $buildPath); - Console::error('[Error] Type: ' . get_class($th)); - Console::error('[Error] Message: ' . $th->getMessage()); - Console::error('[Error] File: ' . $th->getFile()); - Console::error('[Error] Line: ' . $th->getLine()); - } + ], $dbForProject, function (Document $document) use ($deviceBuilds) { + $this->deleteBuildFiles($deviceBuilds, $document); });