mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 08:58:35 +00:00
Merge pull request #9469 from appwrite/feat-site-specifications
Feat: Merge specs
This commit is contained in:
commit
8ff4d60dbb
23 changed files with 209 additions and 224 deletions
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Functions\Specification;
|
||||
|
||||
return [
|
||||
Specification::S_05VCPU_512MB => [
|
||||
'slug' => Specification::S_05VCPU_512MB,
|
||||
'memory' => 512,
|
||||
'cpus' => 0.5
|
||||
],
|
||||
Specification::S_1VCPU_512MB => [
|
||||
'slug' => Specification::S_1VCPU_512MB,
|
||||
'memory' => 512,
|
||||
'cpus' => 1
|
||||
],
|
||||
Specification::S_1VCPU_1GB => [
|
||||
'slug' => Specification::S_1VCPU_1GB,
|
||||
'memory' => 1024,
|
||||
'cpus' => 1
|
||||
],
|
||||
Specification::S_2VCPU_2GB => [
|
||||
'slug' => Specification::S_2VCPU_2GB,
|
||||
'memory' => 2048,
|
||||
'cpus' => 2
|
||||
],
|
||||
Specification::S_2VCPU_4GB => [
|
||||
'slug' => Specification::S_2VCPU_4GB,
|
||||
'memory' => 4096,
|
||||
'cpus' => 2
|
||||
],
|
||||
Specification::S_4VCPU_4GB => [
|
||||
'slug' => Specification::S_4VCPU_4GB,
|
||||
'memory' => 4096,
|
||||
'cpus' => 4
|
||||
],
|
||||
Specification::S_4VCPU_8GB => [
|
||||
'slug' => Specification::S_4VCPU_8GB,
|
||||
'memory' => 8192,
|
||||
'cpus' => 4
|
||||
],
|
||||
Specification::S_8VCPU_4GB => [
|
||||
'slug' => Specification::S_8VCPU_4GB,
|
||||
'memory' => 4096,
|
||||
'cpus' => 8
|
||||
],
|
||||
Specification::S_8VCPU_8GB => [
|
||||
'slug' => Specification::S_8VCPU_8GB,
|
||||
'memory' => 8192,
|
||||
'cpus' => 8
|
||||
]
|
||||
];
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Sites\Specification;
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
|
||||
return [
|
||||
Specification::S_05VCPU_512MB => [
|
||||
|
|
@ -174,7 +174,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
|||
};
|
||||
|
||||
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
|
||||
$spec = Config::getParam('runtime-specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
$spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
|
||||
$runtime = match ($type) {
|
||||
'function' => $runtimes[$resource->getAttribute('runtime')] ?? null,
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ use Appwrite\Event\Realtime;
|
|||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Functions\Specification;
|
||||
use Appwrite\GraphQL\Promises\Adapter\Swoole;
|
||||
use Appwrite\GraphQL\Schema;
|
||||
use Appwrite\Hooks\Hooks;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
use Appwrite\PubSub\Adapter\Redis as PubSub;
|
||||
use Appwrite\URL\URL as AppwriteURL;
|
||||
use Appwrite\Utopia\Request;
|
||||
|
|
@ -389,8 +389,7 @@ Config::load('storage-logos', __DIR__ . '/config/storage/logos.php');
|
|||
Config::load('storage-mimes', __DIR__ . '/config/storage/mimes.php');
|
||||
Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php');
|
||||
Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php');
|
||||
Config::load('runtime-specifications', __DIR__ . '/config/runtimes/specifications.php');
|
||||
Config::load('framework-specifications', __DIR__ . '/config/frameworks/specifications.php');
|
||||
Config::load('specifications', __DIR__ . '/config/specifications.php');
|
||||
Config::load('function-templates', __DIR__ . '/config/function-templates.php');
|
||||
Config::load('site-templates', __DIR__ . '/config/site-templates.php');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Functions;
|
||||
|
||||
class Specification
|
||||
{
|
||||
public const S_05VCPU_512MB = 's-0.5vcpu-512mb';
|
||||
public const S_1VCPU_512MB = 's-1vcpu-512mb';
|
||||
public const S_1VCPU_1GB = 's-1vcpu-1gb';
|
||||
public const S_2VCPU_2GB = 's-2vcpu-2gb';
|
||||
public const S_2VCPU_4GB = 's-2vcpu-4gb';
|
||||
public const S_4VCPU_4GB = 's-4vcpu-4gb';
|
||||
public const S_4VCPU_8GB = 's-4vcpu-8gb';
|
||||
public const S_8VCPU_4GB = 's-8vcpu-4gb';
|
||||
public const S_8VCPU_8GB = 's-8vcpu-8gb';
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Sites;
|
||||
namespace Appwrite\Platform\Modules\Compute;
|
||||
|
||||
class Specification
|
||||
{
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Functions\Validator;
|
||||
namespace Appwrite\Platform\Modules\Compute\Validator;
|
||||
|
||||
use Utopia\Validator;
|
||||
|
||||
class RuntimeSpecification extends Validator
|
||||
class Specification extends Validator
|
||||
{
|
||||
private array $plan;
|
||||
|
||||
|
|
@ -35,8 +35,8 @@ class RuntimeSpecification extends Validator
|
|||
|
||||
foreach ($this->specifications as $size => $values) {
|
||||
if ($values['cpus'] <= $this->maxCpus && $values['memory'] <= $this->maxMemory) {
|
||||
if (!empty($this->plan) && array_key_exists('runtimeSpecifications', $this->plan)) {
|
||||
if (!\in_array($size, $this->plan['runtimeSpecifications'])) {
|
||||
if (!empty($this->plan) && array_key_exists('specifications', $this->plan)) {
|
||||
if (!\in_array($size, $this->plan['specifications'])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -140,7 +140,7 @@ class Create extends Base
|
|||
|
||||
$version = $function->getAttribute('version', 'v2');
|
||||
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
|
||||
$spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
$spec = Config::getParam('specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
|
||||
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ namespace Appwrite\Platform\Modules\Functions\Http\Functions;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Validator\FunctionEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Functions\Validator\RuntimeSpecification;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
|
|
@ -85,9 +85,9 @@ class Create extends Base
|
|||
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function.', true)
|
||||
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true)
|
||||
->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true)
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new RuntimeSpecification(
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
|
||||
$plan,
|
||||
Config::getParam('runtime-specifications', []),
|
||||
Config::getParam('specifications', []),
|
||||
App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT),
|
||||
App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT)
|
||||
), 'Runtime specification for the function and builds.', true, ['plan'])
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ use Appwrite\Event\Build;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Validator\FunctionEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Functions\Validator\RuntimeSpecification;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
|
|
@ -89,9 +89,9 @@ class Update extends Base
|
|||
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the function', true)
|
||||
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the function? In silent mode, comments will not be made on commits and pull requests.', true)
|
||||
->param('providerRootDirectory', '', new Text(128, 0), 'Path to function code in the linked repo.', true)
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new RuntimeSpecification(
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
|
||||
$plan,
|
||||
Config::getParam('runtime-specifications', []),
|
||||
Config::getParam('specifications', []),
|
||||
App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT),
|
||||
App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT)
|
||||
), 'Runtime specification for the function and builds.', true, ['plan'])
|
||||
|
|
@ -206,8 +206,6 @@ class Update extends Base
|
|||
$live = false;
|
||||
}
|
||||
|
||||
$spec = Config::getParam('runtime-specifications')[$specification] ?? [];
|
||||
|
||||
// Enforce Cold Start if spec limits change.
|
||||
if ($function->getAttribute('specification') !== $specification && !empty($function->getAttribute('deployment'))) {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class XList extends Base
|
|||
|
||||
public static function getName()
|
||||
{
|
||||
return 'listFunctionsSpecifications';
|
||||
return 'listSpecifications';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
|
|
@ -28,7 +28,7 @@ class XList extends Base
|
|||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/functions/specifications')
|
||||
->groups(['api', 'functions'])
|
||||
->desc('List available function runtime specifications')
|
||||
->desc('List specifications')
|
||||
->label('scope', 'functions.read')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('sdk', new Method(
|
||||
|
|
@ -52,25 +52,25 @@ class XList extends Base
|
|||
|
||||
public function action(Response $response, array $plan)
|
||||
{
|
||||
$allRuntimeSpecs = Config::getParam('runtime-specifications', []);
|
||||
$allSpecs = Config::getParam('specifications', []);
|
||||
|
||||
$runtimeSpecs = [];
|
||||
foreach ($allRuntimeSpecs as $spec) {
|
||||
$specs = [];
|
||||
foreach ($allSpecs as $spec) {
|
||||
$spec['enabled'] = true;
|
||||
|
||||
if (array_key_exists('runtimeSpecifications', $plan)) {
|
||||
$spec['enabled'] = in_array($spec['slug'], $plan['runtimeSpecifications']);
|
||||
if (array_key_exists('specifications', $plan)) {
|
||||
$spec['enabled'] = in_array($spec['slug'], $plan['specifications']);
|
||||
}
|
||||
|
||||
// Only add specs that are within the limits set by environment variables
|
||||
if ($spec['cpus'] <= System::getEnv('_APP_COMPUTE_CPUS', 1) && $spec['memory'] <= System::getEnv('_APP_COMPUTE_MEMORY', 512)) {
|
||||
$runtimeSpecs[] = $spec;
|
||||
$specs[] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'specifications' => $runtimeSpecs,
|
||||
'total' => count($runtimeSpecs)
|
||||
'specifications' => $specs,
|
||||
'total' => count($specs)
|
||||
]), Response::MODEL_SPECIFICATION_LIST);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class Builds extends Action
|
|||
$version = $this->getVersion($resource);
|
||||
$runtime = $this->getRuntime($resource, $version);
|
||||
|
||||
$spec = Config::getParam('runtime-specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
$spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
|
||||
if ($resource->getCollection() === 'functions' && \is_null($runtime)) {
|
||||
throw new \Exception('Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported');
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ namespace Appwrite\Platform\Modules\Sites\Http\Sites;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Sites\Validator\FrameworkSpecification;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
|
|
@ -77,9 +77,9 @@ class Create extends Base
|
|||
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true)
|
||||
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true)
|
||||
->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true)
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new FrameworkSpecification(
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
|
||||
$plan,
|
||||
Config::getParam('framework-specifications', []),
|
||||
Config::getParam('specifications', []),
|
||||
App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT),
|
||||
App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT)
|
||||
), 'Framework specification for the site and builds.', true, ['plan'])
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ use Appwrite\Event\Build;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\Platform\Modules\Compute\Validator\Specification;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Sites\Validator\FrameworkSpecification;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Executor\Executor;
|
||||
use Utopia\App;
|
||||
|
|
@ -81,9 +81,9 @@ class Update extends Base
|
|||
->param('providerBranch', '', new Text(128, 0), 'Production branch for the repo linked to the site.', true)
|
||||
->param('providerSilentMode', false, new Boolean(), 'Is the VCS (Version Control System) connection in silent mode for the repo linked to the site? In silent mode, comments will not be made on commits and pull requests.', true)
|
||||
->param('providerRootDirectory', '', new Text(128, 0), 'Path to site code in the linked repo.', true)
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new FrameworkSpecification(
|
||||
->param('specification', APP_COMPUTE_SPECIFICATION_DEFAULT, fn (array $plan) => new Specification(
|
||||
$plan,
|
||||
Config::getParam('framework-specifications', []),
|
||||
Config::getParam('specifications', []),
|
||||
App::getEnv('_APP_COMPUTE_CPUS', APP_COMPUTE_CPUS_DEFAULT),
|
||||
App::getEnv('_APP_COMPUTE_MEMORY', APP_COMPUTE_MEMORY_DEFAULT)
|
||||
), 'Framework specification for the site and builds.', true, ['plan'])
|
||||
|
|
@ -204,8 +204,6 @@ class Update extends Base
|
|||
$live = false;
|
||||
}
|
||||
|
||||
$spec = Config::getParam('framework-specifications')[$specification] ?? [];
|
||||
|
||||
// Enforce Cold Start if spec limits change.
|
||||
if ($site->getAttribute('specification') !== $specification && !empty($site->getAttribute('deploymentId'))) {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Sites\Http\Specifications;
|
||||
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
|
||||
class XList extends Base
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'listSpecifications';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/sites/specifications')
|
||||
->groups(['api', 'sites'])
|
||||
->desc('List specifications')
|
||||
->label('scope', 'sites.read')
|
||||
->label('resourceType', RESOURCE_TYPE_SITES)
|
||||
->label('sdk', new Method(
|
||||
namespace: 'sites',
|
||||
name: 'listSpecifications',
|
||||
description: <<<EOT
|
||||
List allowed site specifications for this instance.
|
||||
EOT,
|
||||
auth: [AuthType::KEY, AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_SPECIFICATION_LIST,
|
||||
)
|
||||
]
|
||||
))
|
||||
->inject('response')
|
||||
->inject('plan')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
public function action(Response $response, array $plan)
|
||||
{
|
||||
$allSpecs = Config::getParam('specifications', []);
|
||||
|
||||
$specs = [];
|
||||
foreach ($allSpecs as $spec) {
|
||||
$spec['enabled'] = true;
|
||||
|
||||
if (array_key_exists('specifications', $plan)) {
|
||||
$spec['enabled'] = in_array($spec['slug'], $plan['specifications']);
|
||||
}
|
||||
|
||||
// Only add specs that are within the limits set by environment variables
|
||||
if ($spec['cpus'] <= System::getEnv('_APP_COMPUTE_CPUS', 1) && $spec['memory'] <= System::getEnv('_APP_COMPUTE_MEMORY', 512)) {
|
||||
$specs[] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'specifications' => $specs,
|
||||
'total' => count($specs)
|
||||
]), Response::MODEL_SPECIFICATION_LIST);
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ use Appwrite\Platform\Modules\Sites\Http\Sites\Deployment\Update as UpdateSiteDe
|
|||
use Appwrite\Platform\Modules\Sites\Http\Sites\Get as GetSite;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Sites\Update as UpdateSite;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Sites\XList as ListSites;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Specifications\XList as ListSpecifications;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Templates\Get as GetTemplate;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Templates\XList as ListTemplates;
|
||||
use Appwrite\Platform\Modules\Sites\Http\Usage\Get as GetUsage;
|
||||
|
|
@ -79,5 +80,7 @@ class Http extends Service
|
|||
// Usage
|
||||
$this->addAction(ListUsage::getName(), new ListUsage());
|
||||
$this->addAction(GetUsage::getName(), new GetUsage());
|
||||
|
||||
$this->addAction(ListSpecifications::getName(), new ListSpecifications());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ class Functions extends Action
|
|||
$user ??= new Document();
|
||||
$functionId = $function->getId();
|
||||
$deploymentId = $function->getAttribute('deployment', '');
|
||||
$spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
$spec = Config::getParam('specifications')[$function->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
|
||||
$log->addTag('deploymentId', $deploymentId);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Sites\Validator;
|
||||
|
||||
use Utopia\Validator;
|
||||
|
||||
class FrameworkSpecification extends Validator
|
||||
{
|
||||
private array $plan;
|
||||
|
||||
private array $specifications;
|
||||
|
||||
private float $maxCpus;
|
||||
|
||||
private int $maxMemory;
|
||||
|
||||
public function __construct(array $plan, array $specifications, float $maxCpus, int $maxMemory)
|
||||
{
|
||||
$this->plan = $plan;
|
||||
$this->specifications = $specifications;
|
||||
$this->maxCpus = $maxCpus;
|
||||
$this->maxMemory = $maxMemory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Allowed Specifications.
|
||||
*
|
||||
* Get allowed specifications taking into account the limits set by the environment variables and the plan.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAllowedSpecifications(): array
|
||||
{
|
||||
$allowedSpecifications = [];
|
||||
|
||||
foreach ($this->specifications as $size => $values) {
|
||||
if ($values['cpus'] <= $this->maxCpus && $values['memory'] <= $this->maxMemory) {
|
||||
if (!empty($this->plan) && array_key_exists('frameworkSpecifications', $this->plan)) {
|
||||
if (!\in_array($size, $this->plan['frameworkSpecifications'])) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$allowedSpecifications[] = $size;
|
||||
}
|
||||
}
|
||||
|
||||
return $allowedSpecifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Description.
|
||||
*
|
||||
* Returns validator description.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Specification must be one of: ' . implode(', ', $this->getAllowedSpecifications());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid.
|
||||
*
|
||||
* Returns true if valid or false if not.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (empty($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!\in_array($value, $this->getAllowedSpecifications())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array.
|
||||
*
|
||||
* Function will return true if object is array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type.
|
||||
*
|
||||
* Returns validator type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_STRING;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Tests\E2E\General;
|
||||
|
||||
use Appwrite\Functions\Specification;
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
use Appwrite\Tests\Retry;
|
||||
use CURLFile;
|
||||
use DateTime;
|
||||
|
|
|
|||
|
|
@ -389,4 +389,13 @@ trait FunctionsBase
|
|||
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
protected function listSpecifications(): mixed
|
||||
{
|
||||
$specifications = $this->client->call(Client::METHOD_GET, '/functions/specifications', array_merge([
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
return $specifications;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Tests\E2E\Services\Functions;
|
||||
|
||||
use Appwrite\Functions\Specification;
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
use Appwrite\Tests\Retry;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
|
|
@ -22,6 +22,41 @@ class FunctionsCustomServerTest extends Scope
|
|||
use ProjectCustom;
|
||||
use SideServer;
|
||||
|
||||
public function testListSpecs(): void
|
||||
{
|
||||
$specifications = $this->listSpecifications();
|
||||
$this->assertEquals(200, $specifications['headers']['status-code']);
|
||||
$this->assertGreaterThan(0, $specifications['body']['total']);
|
||||
$this->assertArrayHasKey(0, $specifications['body']['specifications']);
|
||||
$this->assertArrayHasKey('memory', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('cpus', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('enabled', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('slug', $specifications['body']['specifications'][0]);
|
||||
|
||||
$function = $this->createFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Specs function',
|
||||
'runtime' => 'php-8.0',
|
||||
'specification' => $specifications['body']['specifications'][0]['slug']
|
||||
]);
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
$this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['specification']);
|
||||
|
||||
$function = $this->getFunction($function['body']['$id']);
|
||||
$this->assertEquals(200, $function['headers']['status-code']);
|
||||
$this->assertEquals($specifications['body']['specifications'][0]['slug'], $function['body']['specification']);
|
||||
|
||||
$this->cleanupFunction($function['body']['$id']);
|
||||
|
||||
$function = $this->createFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Specs function',
|
||||
'runtime' => 'php-8.0',
|
||||
'specification' => 'cheap-please'
|
||||
]);
|
||||
$this->assertEquals(400, $function['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateFunction(): array
|
||||
{
|
||||
/**
|
||||
|
|
@ -2006,14 +2041,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
$this->assertStringContainsString('APPWRITE_FUNCTION_ID', $execution['body']['responseBody']);
|
||||
|
||||
$site = $this->updateFunction($functionId, [
|
||||
$function = $this->updateFunction($functionId, [
|
||||
'runtime' => 'node-18.0',
|
||||
'name' => 'Duplicate Deployment Test',
|
||||
'entrypoint' => 'index.js',
|
||||
'commands' => 'rm index.js && mv maintenance.js index.js'
|
||||
]);
|
||||
$this->assertEquals(200, $site['headers']['status-code']);
|
||||
$this->assertStringContainsString('maintenance.js', $site['body']['commands']);
|
||||
$this->assertEquals(200, $function['headers']['status-code']);
|
||||
$this->assertStringContainsString('maintenance.js', $function['body']['commands']);
|
||||
|
||||
$deploymentId2 = $this->setupDuplicateDeployment($functionId, $deploymentId1);
|
||||
$this->assertNotEmpty($deploymentId2);
|
||||
|
|
|
|||
|
|
@ -414,4 +414,13 @@ trait SitesBase
|
|||
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
protected function listSpecifications(): mixed
|
||||
{
|
||||
$specifications = $this->client->call(Client::METHOD_GET, '/sites/specifications', array_merge([
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
return $specifications;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Tests\E2E\Services\Sites;
|
||||
|
||||
use Appwrite\Sites\Specification;
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
use Appwrite\Tests\Retry;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
|
|
@ -20,6 +20,43 @@ class SitesCustomServerTest extends Scope
|
|||
use ProjectCustom;
|
||||
use SideServer;
|
||||
|
||||
public function testListSpecs(): void
|
||||
{
|
||||
$specifications = $this->listSpecifications();
|
||||
$this->assertEquals(200, $specifications['headers']['status-code']);
|
||||
$this->assertGreaterThan(0, $specifications['body']['total']);
|
||||
$this->assertArrayHasKey(0, $specifications['body']['specifications']);
|
||||
$this->assertArrayHasKey('memory', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('cpus', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('enabled', $specifications['body']['specifications'][0]);
|
||||
$this->assertArrayHasKey('slug', $specifications['body']['specifications'][0]);
|
||||
|
||||
$site = $this->createSite([
|
||||
'buildRuntime' => 'node-22',
|
||||
'framework' => 'other',
|
||||
'name' => 'Specs site',
|
||||
'siteId' => ID::unique(),
|
||||
'specification' => $specifications['body']['specifications'][0]['slug']
|
||||
]);
|
||||
$this->assertEquals(201, $site['headers']['status-code']);
|
||||
$this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['specification']);
|
||||
|
||||
$site = $this->getSite($site['body']['$id']);
|
||||
$this->assertEquals(200, $site['headers']['status-code']);
|
||||
$this->assertEquals($specifications['body']['specifications'][0]['slug'], $site['body']['specification']);
|
||||
|
||||
$this->cleanupSite($site['body']['$id']);
|
||||
|
||||
$site = $this->createSite([
|
||||
'buildRuntime' => 'node-22',
|
||||
'framework' => 'other',
|
||||
'name' => 'Specs site',
|
||||
'siteId' => ID::unique(),
|
||||
'specification' => 'cheap-please'
|
||||
]);
|
||||
$this->assertEquals(400, $site['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testCreateSite(): void
|
||||
{
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue