From d1978b102f927b0d78d4f4e9b7930d1bdc7a878c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sat, 15 Feb 2025 22:27:16 +0100 Subject: [PATCH] Dark screenshot, upgrade screnshot image, fix redeploy missing domain --- app/config/collections/projects.php | 13 +- app/http.php | 2 +- docker-compose.yml | 2 - .../Modules/Functions/Workers/Builds.php | 123 ++++++++++-------- .../Sites/Http/Deployments/Builds/Create.php | 28 +++- .../Utopia/Response/Model/Deployment.php | 6 + 6 files changed, 114 insertions(+), 60 deletions(-) diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 9674b1f993..3df48fcd55 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -1533,7 +1533,18 @@ return [ '$id' => ID::custom('screenshot'), // File ID from 'screenshots' Console bucket 'type' => Database::VAR_STRING, 'format' => '', - 'size' => Database::LENGTH_KEY, + 'size' => 32, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('screenshotDark'), // File ID from 'screenshots' Console bucket + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, 'signed' => false, 'required' => false, 'default' => null, diff --git a/app/http.php b/app/http.php index b8852e9f74..7e49000734 100644 --- a/app/http.php +++ b/app/http.php @@ -218,7 +218,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg $dbForPlatform->createCollection($key, $attributes, $indexes); } - if ($dbForPlatform->getDocument('buckets', 'default')->isEmpty() ) { + if ($dbForPlatform->getDocument('buckets', 'default')->isEmpty()) { Console::success('[Setup] - Creating default bucket...'); $dbForPlatform->createDocument('buckets', new Document([ '$id' => ID::custom('default'), diff --git a/docker-compose.yml b/docker-compose.yml index a8caddfeae..e3b4533c65 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -886,8 +886,6 @@ services: image: appwrite/browser:0.1.0 networks: - appwrite - environment: - - APPWRITE_BROWSER_SECRET=$_APP_OPENSSL_KEY_V1 openruntimes-executor: container_name: openruntimes-executor diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index b3737f2c4f..bc577a7d08 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -14,7 +14,6 @@ use Appwrite\Vcs\Comment; use Exception; use Executor\Executor; use Swoole\Coroutine as Co; -use Tests\E2E\Client; use Utopia\App; use Utopia\Cache\Cache; use Utopia\CLI\Console; @@ -717,71 +716,85 @@ class Builds extends Action Query::equal("resourceInternalId", [$deployment->getInternalId()]) ])); - if($rule->isEmpty()) { + if ($rule->isEmpty()) { throw new \Exception("Rule for build not found"); } - $client = new FetchClient(); - $client->addHeader('Authorization', 'Bearer ' . App::getEnv('_APP_OPENSSL_KEY_V1', '')); - $response = $client->fetch('http://appwrite-browser:3000/screenshot', query: [ - 'hostname' => $rule->getAttribute('domain'), - 'path' => '/', - ]); - - if($response->getStatusCode() >= 400) { - throw new \Exception("Screenshot failed to generate: " . $response->getBody()); - } - - $screenshot = $response->getBody(); + $client->addHeader('content-type', FetchClient::CONTENT_TYPE_APPLICATION_JSON); $bucket = $dbForPlatform->getDocument('buckets', 'screenshots'); - // TODO: @Khushboo replace with deviceForSites - $fileId = ID::unique(); - $fileName = $fileId . '.png'; - $path = $deviceForFiles->getPath($fileName); - $path = str_ireplace($deviceForFiles->getRoot(), $deviceForFiles->getRoot() . DIRECTORY_SEPARATOR . $bucket->getId(), $path); // Add bucket id to path after root - $success = $deviceForFiles->write($path, $screenshot, "image/png"); + $configs = [ + 'screenshot' => [ + 'headers' => [ 'x-appwrite-hostname' => $rule->getAttribute('domain') ], + 'url' => 'http://traefik/', + 'color' => 'light' + ], + 'screenshotDark' => [ + 'headers' => [ 'x-appwrite-hostname' => $rule->getAttribute('domain') ], + 'url' => 'http://traefik/', + 'color' => 'dark' + ], + ]; - if(!$success) { - throw new \Exception("Screenshot failed to save"); + // TODO: @Meldiron if becomes too slow, do concurrently + foreach ($configs as $key => $config) { + $response = $client->fetch( + url: 'http://appwrite-browser:3000/v1/screenshots', + method: 'POST', + body: $config + ); + + if ($response->getStatusCode() >= 400) { + throw new \Exception("Screenshot failed to generate: " . $response->getBody()); + } + + $screenshot = $response->getBody(); + + // TODO: @Khushboo replace with deviceForSites + $fileId = ID::unique(); + $fileName = $fileId . '.png'; + $path = $deviceForFiles->getPath($fileName); + $path = str_ireplace($deviceForFiles->getRoot(), $deviceForFiles->getRoot() . DIRECTORY_SEPARATOR . $bucket->getId(), $path); // Add bucket id to path after root + $success = $deviceForFiles->write($path, $screenshot, "image/png"); + + if (!$success) { + throw new \Exception("Screenshot failed to save"); + } + + $teamId = $project->getAttribute('teamId', ''); + $file = new Document([ + '$id' => $fileId, + '$permissions' => [ + Permission::read(Role::team(ID::custom($teamId))), + ], + 'bucketId' => $bucket->getId(), + 'bucketInternalId' => $bucket->getInternalId(), + 'name' => $fileName, + 'path' => $path, + 'signature' => $deviceForFiles->getFileHash($path), + 'mimeType' => $deviceForFiles->getFileMimeType($path), + 'sizeOriginal' => \strlen($screenshot), + 'sizeActual' => $deviceForFiles->getFileSize($path), + 'algorithm' => Compression::GZIP, + 'comment' => '', + 'chunksTotal' => 1, + 'chunksUploaded' => 1, + 'openSSLVersion' => null, + 'openSSLCipher' => null, + 'openSSLTag' => null, + 'openSSLIV' => null, + 'search' => implode(' ', [$fileId, $fileName]), + 'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)], + ]); + $file = Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file)); + + $deployment->setAttribute($key, $fileId); } - $teamId = $project->getAttribute('teamId', ''); - $file = new Document([ - '$id' => $fileId, - '$permissions' => [ - Permission::read(Role::team(ID::custom($teamId))), - Permission::update(Role::team(ID::custom($teamId), 'owner')), - Permission::update(Role::team(ID::custom($teamId), 'developer')), - Permission::delete(Role::team(ID::custom($teamId), 'owner')), - Permission::delete(Role::team(ID::custom($teamId), 'developer')), - ], - 'bucketId' => $bucket->getId(), - 'bucketInternalId' => $bucket->getInternalId(), - 'name' => $fileName, - 'path' => $path, - 'signature' => $deviceForFiles->getFileHash($path), - 'mimeType' => $deviceForFiles->getFileMimeType($path), - 'sizeOriginal' => \strlen($screenshot), - 'sizeActual' => $deviceForFiles->getFileSize($path), - 'algorithm' => Compression::GZIP, - 'comment' => '', - 'chunksTotal' => 1, - 'chunksUploaded' => 1, - 'openSSLVersion' => null, - 'openSSLCipher' => null, - 'openSSLTag' => null, - 'openSSLIV' => null, - 'search' => implode(' ', [$fileId, $fileName]), - 'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)], - ]); - $file = Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file)); - - $deployment->setAttribute('screenshot', $fileId); $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment); - } catch(\Throwable $th) { + } catch (\Throwable $th) { Console::warning("Screenshot failed to generate:"); Console::warning($th->getMessage()); Console::warning($th->getTraceAsString()); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Create.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Create.php index 0c5cfc34e4..c28a0be4e5 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Create.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/Builds/Create.php @@ -10,11 +10,14 @@ use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response; use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Database\Helpers\ID; +use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Platform\Action; use Utopia\Platform\Scope\HTTP; use Utopia\Storage\Device; +use Utopia\System\System; class Create extends Action { @@ -53,7 +56,9 @@ class Create extends Action ->param('siteId', '', new UID(), 'Site ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') ->inject('response') + ->inject('project') ->inject('dbForProject') + ->inject('dbForPlatform') ->inject('queueForEvents') ->inject('queueForBuilds') ->inject('deviceForSites') @@ -61,7 +66,7 @@ class Create extends Action ->callback([$this, 'action']); } - public function action(string $siteId, string $deploymentId, Response $response, Database $dbForProject, Event $queueForEvents, Build $queueForBuilds, Device $deviceForSites, Device $deviceForFunctions) + public function action(string $siteId, string $deploymentId, Response $response, Document $project, Database $dbForProject, Database $dbForPlatform, Event $queueForEvents, Build $queueForBuilds, Device $deviceForSites, Device $deviceForFunctions) { $site = $dbForProject->getDocument('sites', $siteId); @@ -97,6 +102,27 @@ class Create extends Action 'search' => implode(' ', [$deploymentId]), ])); + // Preview deployments for sites + $projectId = $project->getId(); + + $sitesDomain = System::getEnv('_APP_DOMAIN_SITES', ''); + $domain = "{$deploymentId}-{$projectId}.{$sitesDomain}"; + $ruleId = md5($domain); + + $rule = Authorization::skip( + fn () => $dbForPlatform->createDocument('rules', new Document([ + '$id' => $ruleId, + 'projectId' => $project->getId(), + 'projectInternalId' => $project->getInternalId(), + 'domain' => $domain, + 'resourceType' => 'deployment', + 'resourceId' => $deploymentId, + 'resourceInternalId' => $deployment->getInternalId(), + 'status' => 'verified', + 'certificateId' => '', + ])) + ); + $queueForBuilds ->setType(BUILD_TYPE_DEPLOYMENT) ->setResource($site) diff --git a/src/Appwrite/Utopia/Response/Model/Deployment.php b/src/Appwrite/Utopia/Response/Model/Deployment.php index c37f256768..3f226d72ea 100644 --- a/src/Appwrite/Utopia/Response/Model/Deployment.php +++ b/src/Appwrite/Utopia/Response/Model/Deployment.php @@ -82,6 +82,12 @@ class Deployment extends Model 'default' => '', 'example' => '5e5ea5c16897e', ]) + ->addRule('screenshotDark', [ + 'type' => self::TYPE_STRING, + 'description' => 'Screenshot with dark theme prefference file ID.', + 'default' => '', + 'example' => '5e5ea5c16897e', + ]) ->addRule('status', [ 'type' => self::TYPE_STRING, 'description' => 'The deployment status. Possible values are "processing", "building", "waiting", "ready", and "failed".',