diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 13db86cf4c2..78814824f70 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -1296,7 +1296,8 @@ ->inject('deviceForFunctions') ->inject('deviceForLocal') ->inject('queueForBuilds') - ->action(function (string $functionId, ?string $entrypoint, ?string $commands, mixed $code, mixed $activate, Request $request, Response $response, Database $dbForProject, Event $queueForEvents, Document $project, Device $deviceForFunctions, Device $deviceForLocal, Build $queueForBuilds) { + ->inject('plan') + ->action(function (string $functionId, ?string $entrypoint, ?string $commands, mixed $code, mixed $activate, Request $request, Response $response, Database $dbForProject, Event $queueForEvents, Document $project, Device $deviceForFunctions, Device $deviceForLocal, Build $queueForBuilds, array $plan) { $activate = \strval($activate) === 'true' || \strval($activate) === '1'; @@ -1329,8 +1330,14 @@ throw new Exception(Exception::STORAGE_FILE_EMPTY, 'No file sent'); } + $sizeLimit = (int) System::getEnv('_APP_FUNCTIONS_SIZE_LIMIT', '30000000'); + if (isset($plan['deploymentSize'])) { + $sizeLimit = $plan['deploymentSize'] * 1000 * 1000; + } + $fileExt = new FileExt([FileExt::TYPE_GZIP]); - $fileSizeValidator = new FileSize(System::getEnv('_APP_FUNCTIONS_SIZE_LIMIT', '30000000')); + $fileSizeValidator = new FileSize($sizeLimit); + $upload = new Upload(); // Make sure we handle a single file and multiple files the same way @@ -1368,7 +1375,7 @@ } } - if (!$fileSizeValidator->isValid($fileSize)) { // Check if file size is exceeding allowed limit + if (!$fileSizeValidator->isValid($fileSize) && $sizeLimit !== 0) { // Check if file size is exceeding allowed limit throw new Exception(Exception::STORAGE_INVALID_FILE_SIZE); } diff --git a/app/worker.php b/app/worker.php index 232e0b36846..f00376e0749 100644 --- a/app/worker.php +++ b/app/worker.php @@ -266,6 +266,10 @@ Server::setResource('log', fn () => new Log()); +Server::setResource('plan', function (array $plan = []) { + return []; +}); + Server::setResource('publisher', function (Group $pools) { return $pools->get('publisher')->pop()->getResource(); }, ['pools']); diff --git a/src/Appwrite/Platform/Workers/Builds.php b/src/Appwrite/Platform/Workers/Builds.php index 4057d4b1900..ae431b389d4 100644 --- a/src/Appwrite/Platform/Workers/Builds.php +++ b/src/Appwrite/Platform/Workers/Builds.php @@ -60,8 +60,9 @@ public function __construct() ->inject('isResourceBlocked') ->inject('log') ->inject('executor') - ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, Executor $executor) => - $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $usage, $cache, $dbForProject, $deviceForFunctions, $isResourceBlocked, $log, $executor)); + ->inject('plan') + ->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, Executor $executor, array $plan) => + $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $usage, $cache, $dbForProject, $deviceForFunctions, $isResourceBlocked, $log, $executor, $plan)); } /** @@ -78,10 +79,11 @@ public function __construct() * @param Device $deviceForFunctions * @param Log $log * @param Executor $executor + * @param array $plan * @return void * @throws \Utopia\Database\Exception */ - public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, Executor $executor): void + public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, callable $isResourceBlocked, Log $log, Executor $executor, array $plan): void { $payload = $message->getPayload() ?? []; @@ -102,7 +104,7 @@ public function action(Message $message, Document $project, Database $dbForPlatf case BUILD_TYPE_RETRY: Console::info('Creating build for deployment: ' . $deployment->getId()); $github = new GitHub($cache); - $this->buildDeployment($deviceForFunctions, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log, $executor); + $this->buildDeployment($deviceForFunctions, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log, $executor, $plan); break; default: @@ -126,11 +128,12 @@ public function action(Message $message, Document $project, Database $dbForPlatf * @param Document $template * @param Log $log * @param Executor $executor + * @param array $plan * @return void * @throws \Utopia\Database\Exception * @throws Exception */ - protected function buildDeployment(Device $deviceForFunctions, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, callable $isResourceBlocked, Log $log, Executor $executor): void + protected function buildDeployment(Device $deviceForFunctions, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $function, Document $deployment, Document $template, callable $isResourceBlocked, Log $log, Executor $executor, array $plan): void { $functionId = $function->getId(); $log->addTag('functionId', $function->getId()); @@ -401,9 +404,13 @@ protected function buildDeployment(Device $deviceForFunctions, Webhook $queueFor } $directorySize = $localDevice->getDirectorySize($tmpDirectory); - $functionsSizeLimit = (int)System::getEnv('_APP_FUNCTIONS_SIZE_LIMIT', '30000000'); - if ($directorySize > $functionsSizeLimit) { - throw new \Exception('Repository directory size should be less than ' . number_format($functionsSizeLimit / 1048576, 2) . ' MBs.'); + $sizeLimit = (int)System::getEnv('_APP_FUNCTIONS_SIZE_LIMIT', '30000000'); + if (isset($plan['deploymentSize'])) { + $sizeLimit = (int) $plan['deploymentSize'] * 1000 * 1000; + } + + if ($directorySize > $sizeLimit && $sizeLimit !== 0) { + throw new \Exception('Repository directory size should be less than ' . number_format($sizeLimit / (1000 * 1000), 2) . ' MBs.'); } Console::execute('find ' . \escapeshellarg($tmpDirectory) . ' -type d -name ".git" -exec rm -rf {} +', '', $stdout, $stderr); @@ -619,9 +626,12 @@ protected function buildDeployment(Device $deviceForFunctions, Webhook $queueFor $endTime = DateTime::now(); $durationEnd = \microtime(true); - $buildSizeLimit = (int)System::getEnv('_APP_FUNCTIONS_BUILD_SIZE_LIMIT', '2000000000'); - if ($response['size'] > $buildSizeLimit) { - throw new \Exception('Build size should be less than ' . number_format($buildSizeLimit / 1048576, 2) . ' MBs.'); + $sizeLimit = (int)System::getEnv('_APP_FUNCTIONS_BUILD_SIZE_LIMIT', '2000000000'); + if (isset($plan['buildSize'])) { + $sizeLimit = $plan['buildSize'] * 1000 * 1000; + } + if ($response['size'] > $sizeLimit && $sizeLimit !== 0) { + throw new \Exception('Build size should be less than ' . number_format($sizeLimit / (1000 * 1000), 2) . ' MBs.'); } /** Update the build document */