Worker now run real functions
This commit is contained in:
parent
58cbc4ce3a
commit
2af2484afa
|
@ -403,7 +403,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
->label('sdk.description', '/docs/references/functions/create-execution.md')
|
||||
->param('functionId', '', function () { return new UID(); }, 'Function unique ID.')
|
||||
->param('async', 1, function () { return new Range(0, 1); }, 'Execute code asynchronously. Pass 1 for true, 0 for false. Default value is 1.', true)
|
||||
->action(function ($functionId, $async, $response, $projectDB) {
|
||||
->action(function ($functionId, $async, $response, $project, $projectDB) {
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
|
@ -442,10 +442,9 @@ App::post('/v1/functions/:functionId/executions')
|
|||
if((bool)$async) {
|
||||
// Issue a TLS certificate when domain is verified
|
||||
Resque::enqueue('v1-functions', 'FunctionsV1', [
|
||||
'projectId' => $project->getId(),
|
||||
'functionId' => $function->getId(),
|
||||
'functionTag' => $tag->getId(),
|
||||
'functionEnv' => $function->getAttribute('env', ''),
|
||||
'functionCommand' => $tag->getAttribute('command', ''),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -453,7 +452,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->json($execution->getArrayCopy())
|
||||
;
|
||||
}, ['response', 'projectDB']);
|
||||
}, ['response', 'project', 'projectDB']);
|
||||
|
||||
App::get('/v1/functions/:functionId/executions')
|
||||
->groups(['api', 'functions'])
|
||||
|
|
|
@ -7,7 +7,7 @@ $events = array_keys($this->getParam('events', []));
|
|||
<div
|
||||
data-service="functions.get"
|
||||
data-name="project-function"
|
||||
data-event="load,functions.update"
|
||||
data-event="load,functions.update,functions.updateTag"
|
||||
data-param-function-id="{{router.params.id}}"
|
||||
data-success="trigger"
|
||||
data-success-param-trigger-events="functions.get">
|
||||
|
@ -73,9 +73,10 @@ $events = array_keys($this->getParam('events', []));
|
|||
<div class="margin-bottom"
|
||||
data-service="functions.listTags"
|
||||
data-scope="sdk"
|
||||
data-event="load,functions.createTag,functions.deleteTag"
|
||||
data-event="load,functions.createTag,functions.deleteTag,functions.updateTag"
|
||||
data-name="project-function-tags"
|
||||
data-param-function-id="{{router.params.id}}"
|
||||
data-param-order-type="DESC"
|
||||
data-success="trigger"
|
||||
data-success-param-trigger-events="functions.listTags">
|
||||
|
||||
|
@ -89,20 +90,20 @@ $events = array_keys($this->getParam('events', []));
|
|||
<div class="box margin-bottom">
|
||||
<ul data-ls-loop="project-function-tags.tags" data-ls-as="tag" class="list">
|
||||
<li class="clear">
|
||||
<form name="functions.updateTag" class="pull-end"
|
||||
<form data-ls-if="{{tag.$id}} !== {{project-function.tag}}" name="functions.updateTag" class="pull-end"
|
||||
data-analytics-event="submit"
|
||||
data-analytics-category="console"
|
||||
data-analytics-label="Create Function Execution"
|
||||
data-service="functions.updateTag"
|
||||
data-event="submit"
|
||||
data-param-function-id="{{router.params.id}}"
|
||||
data-param-tag="{{tag.$id}}"
|
||||
data-success="alert,trigger"
|
||||
data-success-param-alert-text="Tag updated successfully"
|
||||
data-success-param-trigger-events="functions.updateTag"
|
||||
data-failure="alert"
|
||||
data-failure-param-alert-text="Failed to update tag"
|
||||
data-failure-param-alert-classname="error">
|
||||
<input type="hidden" name="tag" data-ls-bind="{{tag.$id}}">
|
||||
<button class="margin-bottom-small">Activate</button>
|
||||
</form>
|
||||
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Adapter\MySQL as MySQLAdapter;
|
||||
use Appwrite\Database\Adapter\Redis as RedisAdapter;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
|
@ -49,17 +56,39 @@ class FunctionsV1
|
|||
|
||||
public function perform()
|
||||
{
|
||||
global $environments;
|
||||
global $environments, $register;
|
||||
|
||||
$projectId = $this->args['projectId'];
|
||||
$functionId = $this->args['functionId'];
|
||||
$functionTag = $this->args['functionTag'];
|
||||
$functionCommand = $this->args['functionCommand'];
|
||||
$functionEnv = $this->args['functionEnv'];
|
||||
|
||||
$environment = (isset($environments[$functionEnv])) ? $environments[$functionEnv] : null;
|
||||
$projectDB = new Database();
|
||||
$projectDB->setAdapter(new RedisAdapter(new MySQLAdapter($register), $register));
|
||||
$projectDB->setNamespace('app_'.$projectId);
|
||||
$projectDB->setMocks(Config::getParam('collections', []));
|
||||
|
||||
Authorization::disable();
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
Authorization::reset();
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
Authorization::disable();
|
||||
$tag = $projectDB->getDocument($functionTag);
|
||||
Authorization::reset();
|
||||
|
||||
if($tag->getAttribute('functionId') !== $function->getId()) {
|
||||
throw new Exception('Tag not found', 404);
|
||||
}
|
||||
|
||||
$environment = (isset($environments[$function->getAttribute('env', '')]))
|
||||
? $environments[$function->getAttribute('env', '')]
|
||||
: null;
|
||||
|
||||
if(is_null($environment)) {
|
||||
throw new Exception('Environment "'.$functionEnv.' is not supported');
|
||||
if(\is_null($environment)) {
|
||||
throw new Exception('Environment "'.$function->getAttribute('env', '').' is not supported');
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -75,7 +104,6 @@ class FunctionsV1
|
|||
* If error count bigger than allowed change status to pause
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 1. Get event args
|
||||
* 2. Unpackage code in the isolated container
|
||||
|
@ -92,7 +120,7 @@ class FunctionsV1
|
|||
$stderr = '';
|
||||
$timeout = 15;
|
||||
|
||||
$start = microtime(true);
|
||||
$start = \microtime(true);
|
||||
|
||||
//TODO aviod scheduled execution if delay is bigger than X offest
|
||||
|
||||
|
@ -104,6 +132,28 @@ class FunctionsV1
|
|||
* Make sure no access to NFS server / storage volumes
|
||||
* Access Appwrite REST from internal network for improved performance
|
||||
*/
|
||||
|
||||
$tagPath = $tag->getAttribute('codePath', '');
|
||||
$tagDir = \pathinfo($tag->getAttribute('codePath', ''), PATHINFO_DIRNAME);
|
||||
$tagFile = \pathinfo($tag->getAttribute('codePath', ''), PATHINFO_BASENAME);
|
||||
$tagPathTarget = '/tmp/project-'.$projectId.'/'.$tag->getId().'/code.tar.gz';
|
||||
$tagPathTargetDir = \pathinfo($tagPathTarget, PATHINFO_DIRNAME);
|
||||
|
||||
if(!\is_readable($tagPath)) {
|
||||
throw new Exception('Code is not readable: '.$tag->getAttribute('codePath', ''));
|
||||
}
|
||||
|
||||
if (!\file_exists($tagPathTargetDir)) {
|
||||
if (!\mkdir($tagPathTargetDir, 0755, true)) {
|
||||
throw new Exception('Can\'t create directory '.$tagPathTargetDir);
|
||||
}
|
||||
}
|
||||
|
||||
if (!\file_exists($tagPathTarget)) {
|
||||
if(!\copy($tagPath, $tagPathTarget)) {
|
||||
throw new Exception('Can\'t create temporary code file '.$tagPathTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//--storage-opt size=120m \
|
||||
$exitCode = Console::execute("docker run \
|
||||
|
@ -112,23 +162,24 @@ class FunctionsV1
|
|||
--memory-swap=50m \
|
||||
--rm \
|
||||
--name=appwrite-function-{$functionId} \
|
||||
--volume $(pwd):/app \
|
||||
--workdir /app \
|
||||
--volume {$tagPathTargetDir}:/tmp:rw \
|
||||
--workdir /usr/local/src \
|
||||
--env APPWRITE_FUNCTION_ID={$functionId} \
|
||||
--env APPWRITE_FUNCTION_TAG={$functionTag} \
|
||||
--env APPWRITE_FUNCTION_ENV_NAME={$environment['name']} \
|
||||
--env APPWRITE_FUNCTION_ENV_VERSION={$environment['version']} \
|
||||
{$environment['image']} \
|
||||
{$functionCommand}", null, $stdout, $stderr, $timeout);
|
||||
sh -c 'mv /tmp/code.tar.gz /usr/local/src/code.tar.gz && tar -zxf /usr/local/src/code.tar.gz --strip 1 && rm /usr/local/src/code.tar.gz && {$tag->getAttribute('command', '')}'"
|
||||
, null, $stdout, $stderr, $timeout);
|
||||
|
||||
$end = microtime(true);
|
||||
$end = \microtime(true);
|
||||
|
||||
var_dump('stdout', $stdout);
|
||||
var_dump('stderr', $stderr);
|
||||
|
||||
Console::info("Code executed in " . ($end - $start) . " seconds with exit code {$exitCode}");
|
||||
|
||||
// Double-check Cleanup
|
||||
|
||||
var_dump($stdout);
|
||||
var_dump($stderr);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
|
|
|
@ -223,11 +223,17 @@ services:
|
|||
- mariadb
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /tmp:/tmp:rw
|
||||
- appwrite-functions:/storage/functions:rw
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
- _APP_DB_HOST
|
||||
- _APP_DB_PORT
|
||||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
|
||||
appwrite-worker-mails:
|
||||
entrypoint: worker-mails
|
||||
|
|
Loading…
Reference in a new issue