From 690a23fe89a91466ae9b05aac11edea6afb658e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 28 Oct 2024 11:17:44 +0100 Subject: [PATCH 1/4] Fix deployments showing wrong domains --- .../Modules/Sites/Http/Deployments/GetDeployment.php | 9 ++++++--- .../Modules/Sites/Http/Deployments/ListDeployments.php | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php index b70bddb842..c70c36a2ec 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/GetDeployment.php @@ -3,9 +3,10 @@ namespace Appwrite\Platform\Modules\Sites\Http\Deployments; use Appwrite\Extend\Exception; -use Appwrite\Query; use Appwrite\Utopia\Response; use Utopia\Database\Database; +use Utopia\Database\Document; +use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; use Utopia\Database\Validator\UID; use Utopia\Platform\Action; @@ -38,12 +39,13 @@ class GetDeployment extends Action ->param('siteId', '', new UID(), 'Site ID.') ->param('deploymentId', '', new UID(), 'Deployment ID.') ->inject('response') + ->inject('project') ->inject('dbForProject') ->inject('dbForConsole') ->callback([$this, 'action']); } - public function action(string $siteId, string $deploymentId, Response $response, Database $dbForProject, Database $dbForConsole) + public function action(string $siteId, string $deploymentId, Response $response, Document $project, Database $dbForProject, Database $dbForConsole) { $site = $dbForProject->getDocument('sites', $siteId); @@ -69,8 +71,9 @@ class GetDeployment extends Action $deployment->setAttribute('size', $deployment->getAttribute('size', 0)); $rule = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ + Query::equal("projectInternalId", [$project->getInternalId()]), Query::equal("resourceType", ["deployment"]), - Query::equal("resourceId", [$deployment->getId()]) + Query::equal("resourceInternalId", [$deployment->getInternalId()]) ])); if (!empty($rule)) { diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php index b1642852dc..4bae69898e 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Deployments/ListDeployments.php @@ -44,12 +44,13 @@ class ListDeployments extends Action ->param('queries', [], new Deployments(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Deployments::ALLOWED_ATTRIBUTES), true) ->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true) ->inject('response') + ->inject('project') ->inject('dbForProject') ->inject('dbForConsole') ->callback([$this, 'action']); } - public function action(string $siteId, array $queries, string $search, Response $response, Database $dbForProject, Database $dbForConsole) + public function action(string $siteId, array $queries, string $search, Response $response, Document $project, Database $dbForProject, Database $dbForConsole) { $site = $dbForProject->getDocument('sites', $siteId); @@ -110,8 +111,9 @@ class ListDeployments extends Action $result->setAttribute('size', $result->getAttribute('size', 0)); $rule = Authorization::skip(fn () => $dbForConsole->findOne('rules', [ + Query::equal("projectInternalId", [$project->getInternalId()]), Query::equal("resourceType", ["deployment"]), - Query::equal("resourceId", [$result->getId()]) + Query::equal("resourceInternalId", [$result->getInternalId()]) ])); if (!empty($rule)) { From febd5294f4bf90c68330965407424bc0937702ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 28 Oct 2024 11:18:15 +0100 Subject: [PATCH 2/4] Ensure function executor is ready --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7c53b03b52..cdd2fa670e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -142,7 +142,7 @@ jobs: run: | docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d - sleep 30 + sleep 60 - name: Run ${{matrix.service}} Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug From bb3503f0c4824586466d49ee597feb0c46170495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 28 Oct 2024 12:00:06 +0100 Subject: [PATCH 3/4] Fix sites deployment logs realtime --- src/Appwrite/Messaging/Adapter/Realtime.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index c437d4d487..52dd3e85c1 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -344,6 +344,16 @@ class Realtime extends Adapter $roles = [Role::team($project->getAttribute('teamId'))->toString()]; } + break; + + case 'sites': + if ($parts[2] === 'deployments') { + $channels[] = 'console'; + $channels[] = 'projects.' . $project->getId(); + $projectId = 'console'; + $roles = [Role::team($project->getAttribute('teamId'))->toString()]; + } + break; case 'migrations': $channels[] = 'console'; From 0c4e597819ea1f23c7b6d4feb31ffbe225e872e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 28 Oct 2024 12:22:34 +0100 Subject: [PATCH 4/4] Implemented styled and timestamped logs, fix cosistency --- app/config/collections.php | 6 +-- app/config/frameworks.php | 3 -- app/config/site-templates.php | 5 ++- app/views/install/compose.phtml | 2 +- docker-compose.yml | 2 +- .../Modules/Functions/Workers/Builds.php | 37 ++++++++++++++++--- .../Sites/Http/Sites/ListFrameworks.php | 1 - .../Utopia/Response/Model/Framework.php | 6 --- .../Response/Model/TemplateFramework.php | 18 ++++++--- .../Utopia/Response/Model/TemplateSite.php | 2 +- 10 files changed, 53 insertions(+), 29 deletions(-) diff --git a/app/config/collections.php b/app/config/collections.php index a33513bfeb..c8866f8116 100644 --- a/app/config/collections.php +++ b/app/config/collections.php @@ -4042,9 +4042,9 @@ $projectCollections = array_merge([ 'size' => 1000000, 'signed' => true, 'required' => false, - 'default' => '', - 'array' => false, - 'filters' => [], + 'default' => [], + 'array' => true, + 'filters' => ['json'], ], [ '$id' => ID::custom('sourceType'), diff --git a/app/config/frameworks.php b/app/config/frameworks.php index 4aeebd14e5..1e34d11df0 100644 --- a/app/config/frameworks.php +++ b/app/config/frameworks.php @@ -19,7 +19,6 @@ return [ 'sveltekit' => [ 'key' => 'sveltekit', 'name' => 'SvelteKit', - 'logo' => 'sveltekit.png', 'defaultServeRuntime' => 'node-22', 'serveRuntimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'defaultBuildRuntime' => 'node-22', @@ -28,7 +27,6 @@ return [ 'nextjs' => [ 'key' => 'nextjs', 'name' => 'Next.js', - 'logo' => 'nextjs.png', 'defaultServeRuntime' => 'node-22', 'serveRuntimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), 'defaultBuildRuntime' => 'node-22', @@ -37,7 +35,6 @@ return [ 'static' => [ 'key' => 'static', 'name' => 'Static', - 'logo' => 'static.png', 'defaultServeRuntime' => 'static-1', 'serveRuntimes' => [ 'static-1' diff --git a/app/config/site-templates.php b/app/config/site-templates.php index a406dc51c2..1467f3415f 100644 --- a/app/config/site-templates.php +++ b/app/config/site-templates.php @@ -2,7 +2,8 @@ const TEMPLATE_FRAMEWORKS = [ 'SVELTEKIT' => [ - 'name' => 'Svelte Kit', + 'key' => 'sveltekit', + 'name' => 'SvelteKit', 'installCommand' => 'npm install', 'buildCommand' => 'npm run build', 'outputDirectory' => './build', @@ -19,7 +20,7 @@ function getFramework(string $frameworkEnum, array $overrides) return [ [ - 'id' => 'starter', + 'key' => 'starter', 'name' => 'Personal portfolio', 'useCases' => ['starter'], 'frameworks' => [ diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 94ad4caec6..146e6bd1d6 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -797,7 +797,7 @@ $image = $this->getParam('image', ''); <<: *x-logging restart: unless-stopped stop_signal: SIGINT - image: openruntimes/executor:0.6.26 + image: openruntimes/executor:0.7.0 networks: - appwrite - runtimes diff --git a/docker-compose.yml b/docker-compose.yml index bac0488ba7..1a90188280 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -879,7 +879,7 @@ services: hostname: exc1 <<: *x-logging stop_signal: SIGINT - image: openruntimes/executor:0.6.26 + image: openruntimes/executor:0.7.0 restart: unless-stopped networks: - appwrite diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index 403941c893..bf598dd9d1 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -175,7 +175,7 @@ class Builds extends Action 'runtime' => $resource->getAttribute('runtime'), 'source' => $deployment->getAttribute('path', ''), 'sourceType' => strtolower($deviceForFunctions->getType()), - 'logs' => '', + 'logs' => [], 'endTime' => null, 'duration' => 0, 'size' => 0 @@ -610,9 +610,29 @@ class Builds extends Action return; } - $logs = \mb_substr($logs, 0, null, 'UTF-8'); // Get only valid UTF8 part - removes leftover half-multibytes causing SQL errors + // Get only valid UTF8 part - removes leftover half-multibytes causing SQL errors + $logs = \mb_substr($logs, 0, null, 'UTF-8'); - $build = $build->setAttribute('logs', $build->getAttribute('logs', '') . $logs); + $currentChunks = $build->getAttribute('logs', []); + + // Parse styled×tamped logs + $streamChunks = []; + $streamLogs = \str_replace("\\n", "{APPWRITE_LINEBREAK_PLACEHOLDER}", $logs); + foreach (\explode("\n", $streamLogs) as $streamLog) { + if (empty($streamLog)) { + continue; + } + + $streamLog = \str_replace("{APPWRITE_LINEBREAK_PLACEHOLDER}", "\n", $streamLog); + $streamParts = \explode(" ", $streamLog, 2); + + $currentChunks[] = [ + 'timestamp' => $streamParts[0] ?? '', + 'content' => $streamParts[1] ?? '' + ]; + } + + $build = $build->setAttribute('logs', $currentChunks); $build = $dbForProject->updateDocument('builds', $build->getId(), $build); /** @@ -666,7 +686,7 @@ class Builds extends Action $build->setAttribute('status', 'ready'); $build->setAttribute('path', $response['path']); $build->setAttribute('size', $response['size']); - $build->setAttribute('logs', $response['output']); + // $build->setAttribute('logs', $response['output']); // TODO: Figure out how to write them all at the end $build = $dbForProject->updateDocument('builds', $buildId, $build); @@ -744,7 +764,14 @@ class Builds extends Action $build->setAttribute('endTime', $endTime); $build->setAttribute('duration', \intval(\ceil($durationEnd - $durationStart))); $build->setAttribute('status', 'failed'); - $build->setAttribute('logs', $th->getMessage()); + + $datetime = new \DateTime(); + $build->setAttribute('logs', [ + [ + 'timestamp' => $datetime->format('Y-m-d\TH:i:s.vP'), + 'content' => "[31m" . $th->getMessage() . "[0m" + ] + ]); $build = $dbForProject->updateDocument('builds', $buildId, $build); diff --git a/src/Appwrite/Platform/Modules/Sites/Http/Sites/ListFrameworks.php b/src/Appwrite/Platform/Modules/Sites/Http/Sites/ListFrameworks.php index 6325ba2351..eede2548b7 100644 --- a/src/Appwrite/Platform/Modules/Sites/Http/Sites/ListFrameworks.php +++ b/src/Appwrite/Platform/Modules/Sites/Http/Sites/ListFrameworks.php @@ -50,7 +50,6 @@ class ListFrameworks extends Base continue; } - $framework['$id'] = $id; $allowed[] = $framework; } diff --git a/src/Appwrite/Utopia/Response/Model/Framework.php b/src/Appwrite/Utopia/Response/Model/Framework.php index b23e73896a..9d55250e87 100644 --- a/src/Appwrite/Utopia/Response/Model/Framework.php +++ b/src/Appwrite/Utopia/Response/Model/Framework.php @@ -10,12 +10,6 @@ class Framework extends Model public function __construct() { $this - ->addRule('$id', [ - 'type' => self::TYPE_STRING, - 'description' => 'Framework ID.', - 'default' => '', - 'example' => 'sveltekit', - ]) ->addRule('key', [ 'type' => self::TYPE_STRING, 'description' => 'Parent framework key.', diff --git a/src/Appwrite/Utopia/Response/Model/TemplateFramework.php b/src/Appwrite/Utopia/Response/Model/TemplateFramework.php index 0b9e81df35..b042de0bc8 100644 --- a/src/Appwrite/Utopia/Response/Model/TemplateFramework.php +++ b/src/Appwrite/Utopia/Response/Model/TemplateFramework.php @@ -10,12 +10,18 @@ class TemplateFramework extends Model public function __construct() { $this - ->addRule('name', [ - 'type' => self::TYPE_STRING, - 'description' => 'Framework Name.', - 'default' => '', - 'example' => 'sveltekit', - ]) + ->addRule('key', [ + 'type' => self::TYPE_STRING, + 'description' => 'Parent framework key.', + 'default' => '', + 'example' => 'sveltekit', + ]) + ->addRule('name', [ + 'type' => self::TYPE_STRING, + 'description' => 'Framework Name.', + 'default' => '', + 'example' => 'SvelteKit' + ]) ->addRule('installCommand', [ 'type' => self::TYPE_STRING, 'description' => 'The install command used to install the dependencies.', diff --git a/src/Appwrite/Utopia/Response/Model/TemplateSite.php b/src/Appwrite/Utopia/Response/Model/TemplateSite.php index 8129e2ca67..86ad52c39c 100644 --- a/src/Appwrite/Utopia/Response/Model/TemplateSite.php +++ b/src/Appwrite/Utopia/Response/Model/TemplateSite.php @@ -10,7 +10,7 @@ class TemplateSite extends Model public function __construct() { $this - ->addRule('id', [ + ->addRule('key', [ 'type' => self::TYPE_STRING, 'description' => 'Site Template ID.', 'default' => '',