Merge branch 'feat-functions-refactor' into feat-functions-refactor-merge
This commit is contained in:
commit
0990448dda
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
/vendor/
|
||||
/node_modules/
|
||||
/tests/resources/storage/
|
||||
/tests/resources/functions/**/code.tar.gz
|
||||
/app/sdks/*
|
||||
/.idea/
|
||||
.DS_Store
|
||||
|
|
|
@ -558,7 +558,9 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
|
||||
if ((bool) $activate) {
|
||||
$activate = (bool) filter_var($activate, FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($activate) {
|
||||
// Remove deploy for all other deployments.
|
||||
$deployments = $dbForProject->find('deployments', [
|
||||
new Query('activate', Query::TYPE_EQUAL, [true]),
|
||||
|
|
|
@ -601,7 +601,7 @@ App::post('/v1/projects/:projectId/webhooks')
|
|||
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$security = ($security === '1' || $security === 'true' || $security === 1 || $security === true);
|
||||
$security = (bool) filter_var($security, FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
$webhook = new Document([
|
||||
'$id' => $dbForConsole->getId(),
|
||||
|
|
342
app/executor.php
342
app/executor.php
|
@ -12,6 +12,7 @@ use Swoole\Timer;
|
|||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Orchestration\Adapter\DockerCLI;
|
||||
use Utopia\Orchestration\Orchestration;
|
||||
use Utopia\Storage\Device\Local;
|
||||
|
@ -20,29 +21,10 @@ use Utopia\Swoole\Request;
|
|||
use Utopia\Swoole\Response;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Range as ValidatorRange;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
// TODO
|
||||
// Implement other endpoints - Done
|
||||
// Handle shutdown - Done
|
||||
// Get list of supported runtimes on startup - Done
|
||||
// Pull runtimes on startup -- Done
|
||||
// Move some logic to server start - Done
|
||||
// Add updated property to swoole table - Done
|
||||
// Clean up deployments older than X seconds - Done
|
||||
// Remove orphans on startup - done
|
||||
// Remove multiple request attempt to the runtime logic in executor - done
|
||||
// Remove builds param from delete endpoint - done
|
||||
// Shutdown callback isn't working as expected - done
|
||||
// Fix error handling - done
|
||||
// Decide on logic for build and runtime containers names ( runtime-ID and build-ID) - done
|
||||
// Add size validators for the runtime IDs - done
|
||||
|
||||
|
||||
// Fix logging
|
||||
// Fix delete endpoint
|
||||
// Incorporate Matej's changes in the build stage ( moving of the tar file will be performed by the runtime and not the build stage )
|
||||
|
||||
Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL);
|
||||
|
||||
|
@ -71,11 +53,23 @@ $orchestrationPool = new ConnectionPool(function () {
|
|||
return $orchestration;
|
||||
}, 10);
|
||||
|
||||
|
||||
/**
|
||||
* Create logger instance
|
||||
*/
|
||||
$providerName = App::getEnv('_APP_LOGGING_PROVIDER', '');
|
||||
$providerConfig = App::getEnv('_APP_LOGGING_CONFIG', '');
|
||||
$logger = null;
|
||||
|
||||
if(!empty($providerName) && !empty($providerConfig) && Logger::hasProvider($providerName)) {
|
||||
$classname = '\\Utopia\\Logger\\Adapter\\'.\ucfirst($providerName);
|
||||
$adapter = new $classname($providerConfig);
|
||||
$logger = new Logger($adapter);
|
||||
}
|
||||
|
||||
function logError(Throwable $error, string $action, Utopia\Route $route = null)
|
||||
{
|
||||
global $register;
|
||||
|
||||
$logger = $register->get('logger');
|
||||
global $logger;
|
||||
|
||||
if ($logger) {
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
@ -116,55 +110,56 @@ function logError(Throwable $error, string $action, Utopia\Route $route = null)
|
|||
|
||||
App::post('/v1/runtimes')
|
||||
->desc("Create a new runtime server")
|
||||
->param('runtimeId', '', new Text(62), 'Unique runtime ID.')
|
||||
->param('runtimeId', '', new Text(64), 'Unique runtime ID.')
|
||||
->param('source', '', new Text(0), 'Path to source files.')
|
||||
->param('destination', '', new Text(0), 'Destination folder to store build files into.')
|
||||
->param('destination', '', new Text(0), 'Destination folder to store build files into.', true)
|
||||
->param('vars', [], new Assoc(), 'Environment Variables required for the build')
|
||||
->param('commands', [], new ArrayList(new Text(0)), 'Commands required to build the container')
|
||||
->param('runtime', '', new Text(128), 'Runtime for the cloud function')
|
||||
->param('network', '', new Text(128), 'Network to attach the container to')
|
||||
->param('baseImage', '', new Text(128), 'Base image name of the runtime')
|
||||
->param('entrypoint', '', new Text(256), 'Entrypoint of the code file', true)
|
||||
->param('remove', false, new Boolean(), 'Remove a runtime after execution')
|
||||
->param('workdir', '', new Text(256), 'Working directory', true)
|
||||
->inject('orchestrationPool')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
->action(function (string $runtimeId, string $source, string $destination, array $vars, array $commands, string $runtime, string $baseImage, $orchestrationPool, $activeRuntimes, Response $response) {
|
||||
->action(function (string $runtimeId, string $source, string $destination, array $vars, array $commands, string $runtime, string $network, string $baseImage, string $entrypoint, bool $remove, string $workdir, $orchestrationPool, $activeRuntimes, Response $response) {
|
||||
|
||||
$container = 'r-' . $runtimeId;
|
||||
|
||||
if ($activeRuntimes->exists($container)) {
|
||||
if ($activeRuntimes->exists($runtimeId)) {
|
||||
throw new Exception('Runtime already exists.', 409);
|
||||
}
|
||||
|
||||
$build = [];
|
||||
$buildId = '';
|
||||
$buildStdout = '';
|
||||
$buildStderr = '';
|
||||
$buildStart = \time();
|
||||
$buildEnd = 0;
|
||||
$container = [];
|
||||
$containerId = '';
|
||||
$stdout = '';
|
||||
$stderr = '';
|
||||
$startTime = \time();
|
||||
$endTime = 0;
|
||||
|
||||
try {
|
||||
Console::info('Building runtime with ID : ' . $runtimeId);
|
||||
Console::info('Building container : ' . $runtimeId);
|
||||
/**
|
||||
* Temporary file paths in the executor
|
||||
*/
|
||||
$tmpSource = "/tmp/$runtimeId/code.tar.gz";
|
||||
$tmpBuildDir = "/tmp/$runtimeId/builds";
|
||||
$tmpBuild = "/tmp/$runtimeId/builds/code.tar.gz";
|
||||
|
||||
/**
|
||||
* Copy code files from source to a temporary location on the executor
|
||||
*/
|
||||
$device = new Local($destination);
|
||||
$device = new Local();
|
||||
$buffer = $device->read($source);
|
||||
if(!$device->write($tmpSource, $buffer)) {
|
||||
throw new Exception('Failed to copy source code to temporary directory', 500);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a temporary folder to store builds
|
||||
* Create the mount folder
|
||||
*/
|
||||
if (!\file_exists($tmpBuildDir)) {
|
||||
if (!@\mkdir($tmpBuildDir, 0755, true)) {
|
||||
throw new Exception("Can't create directory : $tmpBuildDir", 500);
|
||||
if (!\file_exists(\dirname($tmpBuild))) {
|
||||
if (!@\mkdir(\dirname($tmpBuild), 0755, true)) {
|
||||
throw new Exception("Failed to create temporary directory", 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,174 +167,128 @@ App::post('/v1/runtimes')
|
|||
* Create container
|
||||
*/
|
||||
$orchestration = $orchestrationPool->get();
|
||||
$container = 'b-' . $runtimeId;
|
||||
$secret = \bin2hex(\random_bytes(16));
|
||||
$vars = \array_merge($vars, [
|
||||
'INTERNAL_RUNTIME_KEY' => $secret,
|
||||
'INTERNAL_RUNTIME_ENTRYPOINT' => $entrypoint,
|
||||
]);
|
||||
$vars = array_map(fn ($v) => strval($v), $vars);
|
||||
$orchestration
|
||||
->setCpus(App::getEnv('_APP_FUNCTIONS_CPUS', 1))
|
||||
->setMemory(App::getEnv('_APP_FUNCTIONS_MEMORY', 256))
|
||||
->setSwap(App::getEnv('_APP_FUNCTIONS_MEMORY_SWAP', 256));
|
||||
|
||||
$buildId = $orchestration->run(
|
||||
/** Keep the container alive if we have commands to be executed */
|
||||
$entrypoint = !empty($commands) ? [
|
||||
'tail',
|
||||
'-f',
|
||||
'/dev/null'
|
||||
] : [];
|
||||
|
||||
$containerId = $orchestration->run(
|
||||
image: $baseImage,
|
||||
name: $container,
|
||||
name: $runtimeId,
|
||||
hostname: $runtimeId,
|
||||
vars: $vars,
|
||||
workdir: '/usr/code',
|
||||
command: $entrypoint,
|
||||
labels: [
|
||||
'openruntimes-id' => $runtimeId,
|
||||
'openruntimes-type' => 'build',
|
||||
'openruntimes-created' => strval($buildStart),
|
||||
'openruntimes-type' => 'runtime',
|
||||
'openruntimes-created' => strval($startTime),
|
||||
'openruntimes-runtime' => $runtime,
|
||||
],
|
||||
command: [
|
||||
'tail',
|
||||
'-f',
|
||||
'/dev/null'
|
||||
],
|
||||
hostname: $container,
|
||||
mountFolder: \dirname($tmpSource),
|
||||
workdir: $workdir,
|
||||
volumes: [
|
||||
"$tmpBuildDir:/usr/builds:rw"
|
||||
\dirname($tmpSource). ':/tmp:rw',
|
||||
\dirname($tmpBuild). ":/usr/code:rw"
|
||||
]
|
||||
);
|
||||
|
||||
if (empty($buildId)) {
|
||||
if (empty($containerId)) {
|
||||
throw new Exception('Failed to create build container', 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract user code into build container
|
||||
*/
|
||||
$status = $orchestration->execute(
|
||||
name: $container,
|
||||
command: $commands,
|
||||
stdout: $buildStdout,
|
||||
stderr: $buildStderr,
|
||||
timeout: App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)
|
||||
);
|
||||
|
||||
if (!$status) {
|
||||
throw new Exception('Failed to build dependenices ' . $buildStderr, 500);
|
||||
if (!empty($network)) {
|
||||
$orchestration->networkConnect($runtimeId, $network);
|
||||
}
|
||||
|
||||
// Check if the build was successful by checking if file exists
|
||||
if (!\file_exists($tmpBuild)) {
|
||||
throw new Exception('Something went wrong during the build process', 500);
|
||||
/**
|
||||
* Execute any commands if they were provided
|
||||
*/
|
||||
if (!empty($commands)) {
|
||||
$status = $orchestration->execute(
|
||||
name: $runtimeId,
|
||||
command: $commands,
|
||||
stdout: $stdout,
|
||||
stderr: $stderr,
|
||||
timeout: App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)
|
||||
);
|
||||
|
||||
if (!$status) {
|
||||
throw new Exception('Failed to build dependenices ' . $stderr, 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move built code to expected build directory
|
||||
*/
|
||||
$outputPath = $device->getPath(\uniqid() . '.' . \pathinfo('code.tar.gz', PATHINFO_EXTENSION));
|
||||
if (!empty($destination)) {
|
||||
// Check if the build was successful by checking if file exists
|
||||
if (!\file_exists($tmpBuild)) {
|
||||
throw new Exception('Something went wrong during the build process', 500);
|
||||
}
|
||||
|
||||
if (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) === Storage::DEVICE_LOCAL) {
|
||||
if (!$device->move($tmpBuild, $outputPath)) {
|
||||
$device = new Local($destination);
|
||||
$outputPath = $device->getPath(\uniqid() . '.' . \pathinfo('code.tar.gz', PATHINFO_EXTENSION));
|
||||
|
||||
$buffer = $device->read($tmpBuild);
|
||||
if(!$device->write($outputPath, $buffer)) {
|
||||
throw new Exception('Failed to move built code to storage', 500);
|
||||
}
|
||||
} else {
|
||||
if (!$device->upload($tmpBuild, $outputPath)) {
|
||||
throw new Exception('Failed to upload built code upload to storage', 500);
|
||||
}
|
||||
};
|
||||
|
||||
$container['outputPath'] = $outputPath;
|
||||
}
|
||||
|
||||
if ($buildStdout === '') {
|
||||
$buildStdout = 'Build Successful!';
|
||||
if (empty($stdout)) {
|
||||
$stdout = 'Build Successful!';
|
||||
}
|
||||
|
||||
$buildEnd = \time();
|
||||
$build = [
|
||||
'outputPath' => $outputPath,
|
||||
$endTime = \time();
|
||||
$container = array_merge($container, [
|
||||
'status' => 'ready',
|
||||
'stdout' => \utf8_encode($buildStdout),
|
||||
'stderr' => \utf8_encode($buildStderr),
|
||||
'startTime' => $buildStart,
|
||||
'endTime' => $buildEnd,
|
||||
'duration' => $buildEnd - $buildStart,
|
||||
];
|
||||
'stdout' => \utf8_encode($stdout),
|
||||
'stderr' => \utf8_encode($stderr),
|
||||
'startTime' => $startTime,
|
||||
'endTime' => $endTime,
|
||||
'duration' => $endTime - $startTime,
|
||||
]);
|
||||
|
||||
Console::success('Build Stage completed in ' . ($buildEnd - $buildStart) . ' seconds');
|
||||
if (!$remove) {
|
||||
$activeRuntimes->set($runtimeId, [
|
||||
'id' => $containerId,
|
||||
'name' => $runtimeId,
|
||||
'created' => $startTime,
|
||||
'updated' => $endTime,
|
||||
'status' => 'Up ' . \round($endTime - $startTime, 2) . 's',
|
||||
'key' => $secret,
|
||||
]);
|
||||
}
|
||||
|
||||
Console::success('Build Stage completed in ' . ($endTime - $startTime) . ' seconds');
|
||||
|
||||
} catch (Throwable $th) {
|
||||
Console::error('Build failed: ' . $th->getMessage());
|
||||
throw new Exception($th->getMessage(), 500);
|
||||
} finally {
|
||||
if (!empty($buildId)) {
|
||||
$orchestration->remove($buildId, true);
|
||||
if (!empty($containerId) && $remove) {
|
||||
$orchestration->remove($containerId, true);
|
||||
}
|
||||
$orchestrationPool->put($orchestration);
|
||||
}
|
||||
|
||||
/** Create runtime server */
|
||||
try {
|
||||
$orchestration = $orchestrationPool->get();
|
||||
/**
|
||||
* Copy code files from source to a temporary location on the executor
|
||||
*/
|
||||
$buffer = $device->read($outputPath);
|
||||
if(!$device->write($tmpBuild, $buffer)) {
|
||||
throw new Exception('Failed to copy built code to temporary location.', 500);
|
||||
};
|
||||
|
||||
/**
|
||||
* Launch Runtime
|
||||
*/
|
||||
$container = 'r-' . $runtimeId;
|
||||
$secret = \bin2hex(\random_bytes(16));
|
||||
$vars = \array_merge($vars, [
|
||||
'INTERNAL_RUNTIME_KEY' => $secret
|
||||
]);
|
||||
|
||||
$executionStart = \microtime(true);
|
||||
$executionTime = \time();
|
||||
|
||||
$vars = array_map(fn ($v) => strval($v), $vars);
|
||||
|
||||
$orchestration
|
||||
->setCpus(App::getEnv('_APP_FUNCTIONS_CPUS', 1))
|
||||
->setMemory(App::getEnv('_APP_FUNCTIONS_MEMORY', 256))
|
||||
->setSwap(App::getEnv('_APP_FUNCTIONS_MEMORY_SWAP', 256));
|
||||
|
||||
$id = $orchestration->run(
|
||||
image: $baseImage,
|
||||
name: $container,
|
||||
vars: $vars,
|
||||
labels: [
|
||||
'openruntimes-id' => $runtimeId,
|
||||
'openruntimes-type' => 'function',
|
||||
'openruntimes-created' => strval($executionTime),
|
||||
'openruntimes-runtime' => $runtime
|
||||
],
|
||||
hostname: $container,
|
||||
mountFolder: \dirname($tmpBuild),
|
||||
);
|
||||
|
||||
if (empty($id)) {
|
||||
throw new Exception('Failed to create runtime', 500);
|
||||
}
|
||||
|
||||
$orchestration->networkConnect($container, App::getEnv('_APP_EXECUTOR_RUNTIME_NETWORK', 'openruntimes'));
|
||||
|
||||
$executionEnd = \microtime(true);
|
||||
|
||||
$activeRuntimes->set($container, [
|
||||
'id' => $id,
|
||||
'name' => $container,
|
||||
'created' => $executionTime,
|
||||
'updated' => $executionTime,
|
||||
'status' => 'Up ' . \round($executionEnd - $executionStart, 2) . 's',
|
||||
'key' => $secret,
|
||||
]);
|
||||
|
||||
Console::success('Runtime Server created in ' . ($executionEnd - $executionStart) . ' seconds');
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Runtime Server Creation Failed: '. $th->getMessage());
|
||||
throw new Exception($th->getMessage(), 500);
|
||||
} finally {
|
||||
$orchestrationPool->put($orchestration);
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->json($build);
|
||||
->json($container);
|
||||
});
|
||||
|
||||
|
||||
|
@ -355,51 +304,47 @@ App::get('/v1/runtimes')
|
|||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(200)
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->json($runtimes);
|
||||
});
|
||||
|
||||
App::get('/v1/runtimes/:runtimeId')
|
||||
->desc("Get a runtime by its ID")
|
||||
->param('runtimeId', '', new Text(62), 'Runtime unique ID.')
|
||||
->param('runtimeId', '', new Text(64), 'Runtime unique ID.')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
->action(function ($runtimeId, $activeRuntimes, Response $response) {
|
||||
|
||||
$container = 'r-' . $runtimeId;
|
||||
|
||||
if(!$activeRuntimes->exists($container)) {
|
||||
if(!$activeRuntimes->exists($runtimeId)) {
|
||||
throw new Exception('Runtime not found', 404);
|
||||
}
|
||||
|
||||
$runtime = $activeRuntimes->get($container);
|
||||
$runtime = $activeRuntimes->get($runtimeId);
|
||||
|
||||
$response
|
||||
->setStatusCode(200)
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->json($runtime);
|
||||
});
|
||||
|
||||
App::delete('/v1/runtimes/:runtimeId')
|
||||
->desc('Delete a runtime')
|
||||
->param('runtimeId', '', new Text(62), 'Runtime unique ID.', false)
|
||||
->param('runtimeId', '', new Text(64), 'Runtime unique ID.', false)
|
||||
->inject('orchestrationPool')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
->action(function (string $runtimeId, $orchestrationPool, $activeRuntimes, Response $response) {
|
||||
|
||||
$container = 'r-' . $runtimeId;
|
||||
|
||||
if(!$activeRuntimes->exists($container)) {
|
||||
if(!$activeRuntimes->exists($runtimeId)) {
|
||||
throw new Exception('Runtime not found', 404);
|
||||
}
|
||||
|
||||
Console::info('Deleting runtime: ' . $container);
|
||||
Console::info('Deleting runtime: ' . $runtimeId);
|
||||
|
||||
try {
|
||||
$orchestration = $orchestrationPool->get();
|
||||
$orchestration->remove($container, true);
|
||||
$activeRuntimes->del($container);
|
||||
Console::success('Removed runtime container: ' . $container);
|
||||
$orchestration->remove($runtimeId, true);
|
||||
$activeRuntimes->del($runtimeId);
|
||||
Console::success('Removed runtime container: ' . $runtimeId);
|
||||
} finally {
|
||||
$orchestrationPool->put($orchestration);
|
||||
}
|
||||
|
@ -423,7 +368,7 @@ App::delete('/v1/runtimes/:runtimeId')
|
|||
|
||||
App::post('/v1/execution')
|
||||
->desc('Create an execution')
|
||||
->param('runtimeId', '', new Text(62), 'The runtimeID to execute')
|
||||
->param('runtimeId', '', new Text(64), 'The runtimeID to execute')
|
||||
->param('path', '', new Text(0), 'Path containing the built files.', false)
|
||||
->param('vars', [], new Assoc(), 'Environment variables required for the build', false)
|
||||
->param('data', '', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true)
|
||||
|
@ -436,13 +381,11 @@ App::post('/v1/execution')
|
|||
->action(
|
||||
function (string $runtimeId, string $path, array $vars, string $data, string $runtime, string $entrypoint, $timeout, string $baseImage, $activeRuntimes, Response $response) {
|
||||
|
||||
$container = 'r-' . $runtimeId;
|
||||
|
||||
if (!$activeRuntimes->exists($container)) {
|
||||
if (!$activeRuntimes->exists($runtimeId)) {
|
||||
throw new Exception('Runtime not found. Please create the runtime.', 404);
|
||||
}
|
||||
|
||||
$runtime = $activeRuntimes->get($container);
|
||||
$runtime = $activeRuntimes->get($runtimeId);
|
||||
$secret = $runtime['key'];
|
||||
if (empty($secret)) {
|
||||
throw new Exception('Runtime secret not found. Please re-create the runtime.', 500);
|
||||
|
@ -460,13 +403,11 @@ App::post('/v1/execution')
|
|||
|
||||
$ch = \curl_init();
|
||||
$body = \json_encode([
|
||||
'path' => '/usr/code',
|
||||
'file' => $entrypoint,
|
||||
'env' => $vars,
|
||||
'payload' => $data,
|
||||
'timeout' => $timeout ?? (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)
|
||||
]);
|
||||
\curl_setopt($ch, CURLOPT_URL, "http://" . $container . ":3000/");
|
||||
\curl_setopt($ch, CURLOPT_URL, "http://" . $runtimeId . ":3000/");
|
||||
\curl_setopt($ch, CURLOPT_POST, true);
|
||||
\curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
@ -497,7 +438,7 @@ App::post('/v1/execution')
|
|||
|
||||
// 110 is the Swoole error code for timeout, see: https://www.swoole.co.uk/docs/swoole-error-code
|
||||
if ($errNo !== 0 && $errNo !== CURLE_COULDNT_CONNECT && $errNo !== CURLE_OPERATION_TIMEDOUT && $errNo !== 110) {
|
||||
throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 500);
|
||||
throw new Exception('An internal curl error has occurred within the executor! Error Msg: ' . $error, 406);
|
||||
}
|
||||
|
||||
$executionData = [];
|
||||
|
@ -542,7 +483,7 @@ App::post('/v1/execution')
|
|||
|
||||
/** Update swoole table */
|
||||
$runtime['updated'] = \time();
|
||||
$activeRuntimes->set($container, $runtime);
|
||||
$activeRuntimes->set($runtimeId, $runtime);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
|
@ -559,18 +500,20 @@ App::setResource('orchestrationPool', fn() => $orchestrationPool);
|
|||
App::setResource('activeRuntimes', fn() => $activeRuntimes);
|
||||
|
||||
/** Set callbacks */
|
||||
App::error(function ($error, $response) {
|
||||
// $route = $utopia->match($request);
|
||||
// logError($error, "httpError", $route);
|
||||
|
||||
App::error(function ($utopia, $error, $request, $response) {
|
||||
$route = $utopia->match($request);
|
||||
logError($error, "httpError", $route);
|
||||
|
||||
switch ($error->getCode()) {
|
||||
case 400: // Error allowed publicly
|
||||
case 401: // Error allowed publicly
|
||||
case 402: // Error allowed publicly
|
||||
case 403: // Error allowed publicly
|
||||
case 404: // Error allowed publicly
|
||||
case 406: // Error allowed publicly
|
||||
case 409: // Error allowed publicly
|
||||
case 412: // Error allowed publicly
|
||||
case 425: // Error allowed publicly
|
||||
case 429: // Error allowed publicly
|
||||
case 501: // Error allowed publicly
|
||||
case 503: // Error allowed publicly
|
||||
|
@ -586,7 +529,7 @@ App::error(function ($error, $response) {
|
|||
'file' => $error->getFile(),
|
||||
'line' => $error->getLine(),
|
||||
'trace' => $error->getTrace(),
|
||||
'version' => App::getEnv('OPENRUNTIMES_VERSION', 'UNKNOWN'),
|
||||
'version' => App::getEnv('_APP_VERSION', 'UNKNOWN')
|
||||
];
|
||||
|
||||
$response
|
||||
|
@ -596,7 +539,7 @@ App::error(function ($error, $response) {
|
|||
->setStatusCode($code);
|
||||
|
||||
$response->json($output);
|
||||
}, ['error', 'response']);
|
||||
}, ['utopia', 'error', 'request', 'response']);
|
||||
|
||||
App::init(function ($request, $response) {
|
||||
$secretKey = $request->getHeader('x-appwrite-executor-key', '');
|
||||
|
@ -644,8 +587,7 @@ $http->on('start', function ($http) {
|
|||
Console::info('Removing orphan runtimes...');
|
||||
try {
|
||||
$orchestration = $orchestrationPool->get();
|
||||
$orphans = $orchestration->list(['label' => 'openruntimes-type=function']);
|
||||
} catch (\Throwable $th) {
|
||||
$orphans = $orchestration->list(['label' => 'openruntimes-type=runtime']);
|
||||
} finally {
|
||||
$orchestrationPool->put($orchestration);
|
||||
}
|
||||
|
@ -715,7 +657,7 @@ $http->on('beforeShutdown', function() {
|
|||
Console::info('Cleaning up containers before shutdown...');
|
||||
|
||||
$orchestration = $orchestrationPool->get();
|
||||
$functionsToRemove = $orchestration->list(['label' => 'openruntimes-type=function']);
|
||||
$functionsToRemove = $orchestration->list(['label' => 'openruntimes-type=runtime']);
|
||||
$orchestrationPool->put($orchestration);
|
||||
|
||||
foreach ($functionsToRemove as $container) {
|
||||
|
@ -742,7 +684,7 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
|||
try {
|
||||
$app->run($request, $response);
|
||||
} catch (\Throwable $th) {
|
||||
// logError($e, "serverError");
|
||||
logError($th, "serverError");
|
||||
$swooleResponse->setStatusCode(500);
|
||||
$output = [
|
||||
'message' => 'Error: '. $th->getMessage(),
|
||||
|
|
|
@ -687,7 +687,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
|
|||
<input type="file" name="code" id="deployment-code" size="1" required accept="application/x-gzip,.gz">
|
||||
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">(Max file size allowed: <?php echo $fileLimitHuman; ?>)</div>
|
||||
|
||||
<label for="deployment-activate" class="margin-bottom-large">Auto Activate Deployment after build <input type="checkbox" class="margin-start-small" id="deployment-activate" name="activate" /></label>
|
||||
<label for="deployment-activate" class="margin-bottom-large"><input type="checkbox" class="margin-start-small" id="deployment-activate" name="activate" /> Activate Deployment after build</label>
|
||||
|
||||
<footer>
|
||||
<button type="submit">Create</button> <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
|
||||
|
|
|
@ -117,19 +117,16 @@ class BuildsV1 extends Worker
|
|||
functionId: $functionId,
|
||||
deploymentId: $deploymentId,
|
||||
source: $source,
|
||||
destination: APP_STORAGE_BUILDS . "/app-$projectId",
|
||||
vars: $vars,
|
||||
runtime: $key,
|
||||
baseImage: $baseImage,
|
||||
workdir: '/usr/code',
|
||||
remove: true,
|
||||
commands: [
|
||||
'sh', '-c',
|
||||
'mkdir -p /usr/code && \
|
||||
cp /tmp/code.tar.gz /usr/workspace/code.tar.gz && \
|
||||
cd /usr/workspace/ && \
|
||||
tar -zxf /usr/workspace/code.tar.gz -C /usr/code && \
|
||||
rm /usr/workspace/code.tar.gz && \
|
||||
cd /usr/local/src && \
|
||||
./build.sh && \
|
||||
tar -C /usr/code -czf /usr/builds/code.tar.gz ./'
|
||||
'tar -zxf /tmp/code.tar.gz -C /usr/code && \
|
||||
cd /usr/local/src/ && ./build.sh'
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"ext-zlib": "*",
|
||||
"ext-sockets": "*",
|
||||
"appwrite/php-clamav": "1.1.*",
|
||||
"appwrite/php-runtimes": "dev-refactor",
|
||||
"appwrite/php-runtimes": "0.7.2",
|
||||
"utopia-php/framework": "0.19.*",
|
||||
"utopia-php/logger": "0.1.*",
|
||||
"utopia-php/abuse": "0.7.*",
|
||||
|
|
73
composer.lock
generated
73
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "34f00d2ccd1a38f669028bcab82c0f94",
|
||||
"content-hash": "92614eab8d44998df216484f617c2026",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -115,20 +115,18 @@
|
|||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "dev-refactor",
|
||||
"version": "0.7.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"reference": "ea44eb19af851a3fe4ecf73e789f374f70d778c5"
|
||||
"reference": "5021856c78f61c8dc542ca2fc704a8d1025583e2"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/orchestration": "0.4.*",
|
||||
"utopia-php/system": "0.4.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"utopia-php/cli": "0.11.*",
|
||||
"vimeo/psalm": "4.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -148,10 +146,6 @@
|
|||
{
|
||||
"name": "Torsten Dittmann",
|
||||
"email": "torsten@appwrite.io"
|
||||
},
|
||||
{
|
||||
"name": "Bradley Schofield",
|
||||
"email": "bradley@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "Appwrite repository for Cloud Function runtimes that contains the configurations and tests for all of the Appwrite runtime environments.",
|
||||
|
@ -160,7 +154,7 @@
|
|||
"php",
|
||||
"runtimes"
|
||||
],
|
||||
"time": "2022-02-17T12:06:12+00:00"
|
||||
"time": "2022-02-20T20:31:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
|
@ -2630,16 +2624,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "de12487f77346475e2deed82212c6f842c9ae4a8"
|
||||
"reference": "1921d5da3d155c1e03b26f8f6184dba3a69cd5e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/de12487f77346475e2deed82212c6f842c9ae4a8",
|
||||
"reference": "de12487f77346475e2deed82212c6f842c9ae4a8",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/1921d5da3d155c1e03b26f8f6184dba3a69cd5e4",
|
||||
"reference": "1921d5da3d155c1e03b26f8f6184dba3a69cd5e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2676,9 +2670,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.7.0"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.7.1"
|
||||
},
|
||||
"time": "2022-02-09T13:02:47+00:00"
|
||||
"time": "2022-02-20T13:27:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
|
@ -2911,16 +2905,16 @@
|
|||
"packages-dev": [
|
||||
{
|
||||
"name": "amphp/amp",
|
||||
"version": "v2.6.1",
|
||||
"version": "v2.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/amphp/amp.git",
|
||||
"reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae"
|
||||
"reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/amphp/amp/zipball/c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae",
|
||||
"reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae",
|
||||
"url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
|
||||
"reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2942,13 +2936,13 @@
|
|||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Amp\\": "lib"
|
||||
},
|
||||
"files": [
|
||||
"lib/functions.php",
|
||||
"lib/Internal/functions.php"
|
||||
]
|
||||
],
|
||||
"psr-4": {
|
||||
"Amp\\": "lib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
@ -2973,7 +2967,7 @@
|
|||
}
|
||||
],
|
||||
"description": "A non-blocking concurrency framework for PHP applications.",
|
||||
"homepage": "http://amphp.org/amp",
|
||||
"homepage": "https://amphp.org/amp",
|
||||
"keywords": [
|
||||
"async",
|
||||
"asynchronous",
|
||||
|
@ -2988,7 +2982,7 @@
|
|||
"support": {
|
||||
"irc": "irc://irc.freenode.org/amphp",
|
||||
"issues": "https://github.com/amphp/amp/issues",
|
||||
"source": "https://github.com/amphp/amp/tree/v2.6.1"
|
||||
"source": "https://github.com/amphp/amp/tree/v2.6.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2996,7 +2990,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-09-23T18:43:08+00:00"
|
||||
"time": "2022-02-20T17:52:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "amphp/byte-stream",
|
||||
|
@ -3951,16 +3945,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phar-io/version",
|
||||
"version": "3.1.1",
|
||||
"version": "3.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phar-io/version.git",
|
||||
"reference": "15a90844ad40f127afd244c0cad228de2a80052a"
|
||||
"reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a",
|
||||
"reference": "15a90844ad40f127afd244c0cad228de2a80052a",
|
||||
"url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
|
||||
"reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3996,9 +3990,9 @@
|
|||
"description": "Library for handling version information and constraints",
|
||||
"support": {
|
||||
"issues": "https://github.com/phar-io/version/issues",
|
||||
"source": "https://github.com/phar-io/version/tree/3.1.1"
|
||||
"source": "https://github.com/phar-io/version/tree/3.2.1"
|
||||
},
|
||||
"time": "2022-02-07T21:56:48+00:00"
|
||||
"time": "2022-02-21T01:04:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
|
@ -4229,16 +4223,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "9.2.10",
|
||||
"version": "9.2.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "d5850aaf931743067f4bfc1ae4cbd06468400687"
|
||||
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687",
|
||||
"reference": "d5850aaf931743067f4bfc1ae4cbd06468400687",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/665a1ac0a763c51afc30d6d130dac0813092b17f",
|
||||
"reference": "665a1ac0a763c51afc30d6d130dac0813092b17f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4294,7 +4288,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.11"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -4302,7 +4296,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-05T09:12:13+00:00"
|
||||
"time": "2022-02-18T12:46:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
|
@ -6553,7 +6547,6 @@
|
|||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {
|
||||
"appwrite/php-runtimes": 20,
|
||||
"appwrite/sdk-generator": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
|
|
|
@ -515,10 +515,6 @@ services:
|
|||
- _APP_INFLUXDB_HOST
|
||||
- _APP_INFLUXDB_PORT
|
||||
- _APP_USAGE_SYNC_INTERVAL
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
- _APP_REDIS_USER
|
||||
- _APP_REDIS_PASS
|
||||
|
||||
appwrite-schedule:
|
||||
entrypoint: schedule
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
(function (exports, isomorphicFormData, crossFetch) {
|
||||
'use strict';
|
||||
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
class AppwriteException extends Error {
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Executor;
|
|||
|
||||
use Exception;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
class Executor
|
||||
{
|
||||
|
@ -34,29 +35,37 @@ class Executor
|
|||
string $functionId,
|
||||
string $deploymentId,
|
||||
string $projectId,
|
||||
string $source,
|
||||
array $vars,
|
||||
string $source,
|
||||
string $runtime,
|
||||
string $baseImage,
|
||||
array $commands
|
||||
bool $remove = false,
|
||||
string $entrypoint = '',
|
||||
string $workdir = '',
|
||||
string $destination = '',
|
||||
string $network = '',
|
||||
array $vars = [],
|
||||
array $commands = []
|
||||
) {
|
||||
$route = "/runtimes";
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-executor-key' => App::getEnv('_APP_EXECUTOR_SECRET', '')
|
||||
];
|
||||
$params = [
|
||||
'runtimeId' => "$projectId-$deploymentId",
|
||||
'source' => $source,
|
||||
'destination' => APP_STORAGE_BUILDS . "/app-$projectId",
|
||||
'vars' => $vars,
|
||||
'destination' => $destination,
|
||||
'runtime' => $runtime,
|
||||
'baseImage' => $baseImage,
|
||||
'entrypoint' => $entrypoint,
|
||||
'workdir' => $workdir,
|
||||
'network' => empty($network) ? App::getEnv('_APP_EXECUTOR_RUNTIME_NETWORK', 'appwrite_runtimes') : $network,
|
||||
'vars' => $vars,
|
||||
'remove' => $remove,
|
||||
'commands' => $commands
|
||||
];
|
||||
|
||||
$response = $this->call(self::METHOD_POST, $route, $headers, $params, true, 30);
|
||||
$response = $this->call(self::METHOD_POST, $route, $headers, $params, true, App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900));
|
||||
|
||||
$status = $response['headers']['status-code'];
|
||||
if ($status >= 400) {
|
||||
|
@ -72,7 +81,6 @@ class Executor
|
|||
$route = "/runtimes/$runtimeId";
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-executor-key' => App::getEnv('_APP_EXECUTOR_SECRET', '')
|
||||
];
|
||||
|
||||
|
@ -99,12 +107,11 @@ class Executor
|
|||
string $runtime,
|
||||
string $baseImage,
|
||||
$timeout
|
||||
)
|
||||
{
|
||||
) {
|
||||
|
||||
$route = "/execution";
|
||||
$headers = [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-executor-key' => App::getEnv('_APP_EXECUTOR_SECRET', '')
|
||||
];
|
||||
$params = [
|
||||
|
@ -119,11 +126,46 @@ class Executor
|
|||
];
|
||||
|
||||
$response = $this->call(self::METHOD_POST, $route, $headers, $params, true, 30);
|
||||
|
||||
$status = $response['headers']['status-code'];
|
||||
|
||||
if ($status >= 400) {
|
||||
throw new \Exception($response['body']['message'], $status);
|
||||
}
|
||||
for ($attempts = 0; $attempts < 5; $attempts++) {
|
||||
switch ($status) {
|
||||
case 404:
|
||||
$response = $this->createRuntime(
|
||||
functionId: $functionId,
|
||||
deploymentId: $deploymentId,
|
||||
projectId: $projectId,
|
||||
source: $path,
|
||||
runtime: $runtime,
|
||||
baseImage: $baseImage,
|
||||
vars: $vars,
|
||||
entrypoint: $entrypoint,
|
||||
commands: []
|
||||
);
|
||||
$response = $this->call(self::METHOD_POST, $route, $headers, $params, true, 30);
|
||||
$status = $response['headers']['status-code'];
|
||||
break;
|
||||
case 406:
|
||||
$response = $this->call(self::METHOD_POST, $route, $headers, $params, true, 30);
|
||||
$status = $response['headers']['status-code'];
|
||||
break;
|
||||
default:
|
||||
throw new \Exception($response['body']['message'], $status);
|
||||
}
|
||||
|
||||
if ($status < 400) {
|
||||
return $response['body'];
|
||||
}
|
||||
|
||||
if ($status != 406) {
|
||||
throw new \Exception($response['body']['message'], $status);
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
}
|
||||
throw new Exception($response['body']['message'], 503);
|
||||
}
|
||||
|
||||
return $response['body'];
|
||||
}
|
||||
|
@ -225,10 +267,6 @@ class Executor
|
|||
|
||||
$responseHeaders['status-code'] = $responseStatus;
|
||||
|
||||
if ($responseStatus === 500) {
|
||||
echo 'Server error('.$method.': '.$path.'. Params: '.json_encode($params).'): '.json_encode($responseBody)."\n";
|
||||
}
|
||||
|
||||
return [
|
||||
'headers' => $responseHeaders,
|
||||
'body' => $responseBody
|
||||
|
|
|
@ -3,10 +3,16 @@
|
|||
namespace Tests\E2E\Services\Functions;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
trait FunctionsBase
|
||||
{
|
||||
|
||||
protected string $stdout = '';
|
||||
protected string $stderr = '';
|
||||
|
||||
protected function packageCode($folder) {
|
||||
Console::execute('cd '.realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateTeam
|
||||
|
|
|
@ -7,6 +7,7 @@ use Tests\E2E\Client;
|
|||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
|
||||
class FunctionsCustomClientTest extends Scope
|
||||
|
@ -73,13 +74,17 @@ class FunctionsCustomClientTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$function['body']['$id'].'/deployments', [
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -156,13 +161,17 @@ class FunctionsCustomClientTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$folder = 'php-fn';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', [
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php-fn.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'), //different tarball names intentional
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -338,13 +347,17 @@ class FunctionsCustomClientTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$folder = 'php-fn';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', [
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php-fn.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'), //different tarball names intentional
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)), //different tarball names intentional
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
|
@ -7,6 +7,7 @@ use Tests\E2E\Client;
|
|||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
|
||||
class FunctionsCustomServerTest extends Scope
|
||||
|
@ -277,12 +278,16 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
@ -685,10 +690,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
public function testTimeout()
|
||||
{
|
||||
$name = 'php-8.0';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions').'/timeout.tar.gz';
|
||||
$entrypoint = 'index.php';
|
||||
$timeout = 2;
|
||||
|
||||
$folder = 'timeout';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -712,20 +719,13 @@ class FunctionsCustomServerTest extends Scope
|
|||
], $this->getHeaders()), [
|
||||
'entrypoint' => $entrypoint,
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
|
||||
'activate' => true,
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
$this->assertEquals(201, $deployment['headers']['status-code']);
|
||||
|
||||
// Allow build step to run
|
||||
sleep(10);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployments/'.$deploymentId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $deployment['headers']['status-code']);
|
||||
sleep(5);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
@ -738,7 +738,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
sleep(10);
|
||||
sleep(5);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
@ -771,12 +771,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testTimeout
|
||||
*/
|
||||
public function testCreateCustomExecution()
|
||||
public function testCreateCustomPHPExecution()
|
||||
{
|
||||
$name = 'php-8.0';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions').'/php-fn.tar.gz';
|
||||
$entrypoint = 'index.php';
|
||||
$timeout = 2;
|
||||
$folder = 'php-fn';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
@ -876,9 +878,114 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
|
||||
public function testCreateCustomNodeExecution()
|
||||
{
|
||||
$name = 'node-17.0';
|
||||
$folder = 'node';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$entrypoint = 'index.js';
|
||||
$timeout = 2;
|
||||
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'runtime' => $name,
|
||||
'vars' => [
|
||||
'CUSTOM_VARIABLE' => 'variable',
|
||||
],
|
||||
'events' => [],
|
||||
'schedule' => '',
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
|
||||
$functionId = $function['body']['$id'] ?? '';
|
||||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'entrypoint' => $entrypoint,
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
|
||||
'activate' => true,
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
$this->assertEquals(201, $deployment['headers']['status-code']);
|
||||
|
||||
// Allow build step to run
|
||||
sleep(10);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'data' => 'foobar',
|
||||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
sleep(10);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$output = json_decode($executions['body']['stdout'], true);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('Node.js', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
$this->assertEquals('17.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);
|
||||
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT']);
|
||||
$this->assertEquals('', $output['APPWRITE_FUNCTION_EVENT_DATA']);
|
||||
$this->assertEquals('foobar', $output['APPWRITE_FUNCTION_DATA']);
|
||||
$this->assertEquals('variable', $output['CUSTOM_VARIABLE']);
|
||||
$this->assertEquals('', $output['APPWRITE_FUNCTION_USER_ID']);
|
||||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['sum'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
$this->assertCount(1, $executions['body']['executions']);
|
||||
$this->assertEquals($executions['body']['executions'][0]['$id'], $executionId);
|
||||
$this->assertEquals($executions['body']['executions'][0]['trigger'], 'http');
|
||||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], []);
|
||||
|
||||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
public function testGetRuntimes()
|
||||
{
|
||||
|
||||
$runtimes = $this->client->call(Client::METHOD_GET, '/functions/runtimes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
|
|
@ -7,6 +7,7 @@ use Tests\E2E\Client;
|
|||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\CLI\Console;
|
||||
use WebSocket\ConnectionException;
|
||||
|
||||
|
||||
|
@ -1003,13 +1004,19 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertEquals($function['headers']['status-code'], 201);
|
||||
$this->assertNotEmpty($function['body']['$id']);
|
||||
|
||||
$folder = 'timeout';
|
||||
$stderr = '';
|
||||
$stdout= '';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
Console::execute('cd '.realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $stdout, $stderr);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/timeout.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code))
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
|
@ -7,6 +7,7 @@ use Tests\E2E\Client;
|
|||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
class WebhooksCustomServerTest extends Scope
|
||||
{
|
||||
|
@ -398,12 +399,18 @@ class WebhooksCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$stderr = '';
|
||||
$stdout= '';
|
||||
$folder = 'timeout';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
Console::execute('cd '.realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $stdout, $stderr);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/timeout.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code))
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
|
29
tests/resources/functions/node/index.js
Normal file
29
tests/resources/functions/node/index.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
'req' variable has:
|
||||
'headers' - object with request headers
|
||||
'payload' - object with request body data
|
||||
'env' - object with environment variables
|
||||
'res' variable has:
|
||||
'send(text, status)' - function to return text response. Status code defaults to 200
|
||||
'json(obj, status)' - function to return JSON response. Status code defaults to 200
|
||||
|
||||
If an error is thrown, a response with code 500 will be returned.
|
||||
*/
|
||||
|
||||
module.exports = async (req, res) => {
|
||||
res.json({
|
||||
'APPWRITE_FUNCTION_ID' : req.env.APPWRITE_FUNCTION_ID,
|
||||
'APPWRITE_FUNCTION_NAME' : req.env.APPWRITE_FUNCTION_NAME,
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' : req.env.APPWRITE_FUNCTION_DEPLOYMENT,
|
||||
'APPWRITE_FUNCTION_TRIGGER' : req.env.APPWRITE_FUNCTION_TRIGGER,
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' : req.env.APPWRITE_FUNCTION_RUNTIME_NAME,
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' : req.env.APPWRITE_FUNCTION_RUNTIME_VERSION,
|
||||
'APPWRITE_FUNCTION_EVENT' : req.env.APPWRITE_FUNCTION_EVENT,
|
||||
'APPWRITE_FUNCTION_EVENT_DATA' : req.env.APPWRITE_FUNCTION_EVENT_DATA,
|
||||
'APPWRITE_FUNCTION_DATA' : req.env.APPWRITE_FUNCTION_DATA,
|
||||
'APPWRITE_FUNCTION_USER_ID' : req.env.APPWRITE_FUNCTION_USER_ID,
|
||||
'APPWRITE_FUNCTION_JWT' : req.env.APPWRITE_FUNCTION_JWT,
|
||||
'APPWRITE_FUNCTION_PROJECT_ID' : req.env.APPWRITE_FUNCTION_PROJECT_ID,
|
||||
'CUSTOM_VARIABLE' : req.env.CUSTOM_VARIABLE
|
||||
});
|
||||
}
|
376
tests/resources/functions/node/package-lock.json
generated
376
tests/resources/functions/node/package-lock.json
generated
|
@ -1,376 +0,0 @@
|
|||
{
|
||||
"name": "appwrite-cloud-function-demo",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"requires": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
|
||||
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.27",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
|
||||
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
|
||||
"requires": {
|
||||
"mime-db": "1.44.0"
|
||||
}
|
||||
},
|
||||
"node-appwrite": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-appwrite/-/node-appwrite-1.1.0.tgz",
|
||||
"integrity": "sha512-ZLOsxmsGry4ZRT63QRbNgUxhYiUzJlQntQL2nKAy6PBL1S/hMCChKrdLIdJv3ytGxPrrIWiDWxXivMeUeCW5KA==",
|
||||
"requires": {
|
||||
"request": "^2.88.0",
|
||||
"request-promise-native": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
|
||||
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"request-promise-core": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
|
||||
"integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.19"
|
||||
}
|
||||
},
|
||||
"request-promise-native": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
|
||||
"integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
|
||||
"requires": {
|
||||
"request-promise-core": "1.1.4",
|
||||
"stealthy-require": "^1.1.1",
|
||||
"tough-cookie": "^2.3.3"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"stealthy-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"requires": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz",
|
||||
"integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
echo 'PHP Packaging...'
|
||||
|
||||
cp -r $(pwd)/tests/resources/functions/php-fn $(pwd)/tests/resources/functions/packages/php-fn
|
||||
|
||||
docker run --rm -v $(pwd)/tests/resources/functions/packages/php-fn:/app -w /app composer:2.0 composer install --ignore-platform-reqs
|
||||
|
||||
docker run --rm -v $(pwd)/tests/resources/functions/packages/php-fn:/app -w /app appwrite/env-php-8.0:1.0.0 tar -zcvf code.tar.gz .
|
||||
|
||||
mv $(pwd)/tests/resources/functions/packages/php-fn/code.tar.gz $(pwd)/tests/resources/functions/php-fn.tar.gz
|
||||
|
||||
rm -r $(pwd)/tests/resources/functions/packages/php-fn
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
echo 'PHP Packaging...'
|
||||
|
||||
cp -r $(pwd)/tests/resources/functions/php $(pwd)/tests/resources/functions/packages/php
|
||||
|
||||
docker run --rm -v $(pwd)/tests/resources/functions/packages/php:/app -w /app composer:2.0 composer install --ignore-platform-reqs
|
||||
|
||||
docker run --rm -v $(pwd)/tests/resources/functions/packages/php:/app -w /app appwrite/env-php-8.0:1.0.0 tar -zcvf code.tar.gz .
|
||||
|
||||
mv $(pwd)/tests/resources/functions/packages/php/code.tar.gz $(pwd)/tests/resources/functions/php.tar.gz
|
||||
|
||||
rm -r $(pwd)/tests/resources/functions/packages/php
|
|
@ -1,10 +0,0 @@
|
|||
|
||||
echo 'Timeout Packaging...'
|
||||
|
||||
cp -r $(pwd)/tests/resources/functions/timeout $(pwd)/tests/resources/functions/packages/timeout
|
||||
|
||||
docker run --rm -v $(pwd)/tests/resources/functions/packages/timeout:/app -w /app appwrite/env-php-8.0:1.0.0 tar -zcvf code.tar.gz .
|
||||
|
||||
mv $(pwd)/tests/resources/functions/packages/timeout/code.tar.gz $(pwd)/tests/resources/functions/timeout.tar.gz
|
||||
|
||||
rm -r $(pwd)/tests/resources/functions/packages/timeout
|
Binary file not shown.
|
@ -2,17 +2,17 @@
|
|||
|
||||
return function ($request, $response) {
|
||||
$response->json([
|
||||
'APPWRITE_FUNCTION_ID' => $request->env['APPWRITE_FUNCTION_ID'],
|
||||
'APPWRITE_FUNCTION_NAME' => $request->env['APPWRITE_FUNCTION_NAME'],
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' => $request->env['APPWRITE_FUNCTION_DEPLOYMENT'],
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $request->env['APPWRITE_FUNCTION_TRIGGER'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request->env['APPWRITE_FUNCTION_RUNTIME_NAME'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request->env['APPWRITE_FUNCTION_RUNTIME_VERSION'],
|
||||
'APPWRITE_FUNCTION_EVENT' => $request->env['APPWRITE_FUNCTION_EVENT'],
|
||||
'APPWRITE_FUNCTION_EVENT_DATA' => $request->env['APPWRITE_FUNCTION_EVENT_DATA'],
|
||||
'APPWRITE_FUNCTION_DATA' => $request->env['APPWRITE_FUNCTION_DATA'],
|
||||
'APPWRITE_FUNCTION_USER_ID' => $request->env['APPWRITE_FUNCTION_USER_ID'],
|
||||
'APPWRITE_FUNCTION_JWT' => $request->env['APPWRITE_FUNCTION_JWT'],
|
||||
'APPWRITE_FUNCTION_PROJECT_ID' => $request->env['APPWRITE_FUNCTION_PROJECT_ID'],
|
||||
'APPWRITE_FUNCTION_ID' => $request['env']['APPWRITE_FUNCTION_ID'],
|
||||
'APPWRITE_FUNCTION_NAME' => $request['env']['APPWRITE_FUNCTION_NAME'],
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' => $request['env']['APPWRITE_FUNCTION_DEPLOYMENT'],
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $request['env']['APPWRITE_FUNCTION_TRIGGER'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request['env']['APPWRITE_FUNCTION_RUNTIME_NAME'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request['env']['APPWRITE_FUNCTION_RUNTIME_VERSION'],
|
||||
'APPWRITE_FUNCTION_EVENT' => $request['env']['APPWRITE_FUNCTION_EVENT'],
|
||||
'APPWRITE_FUNCTION_EVENT_DATA' => $request['env']['APPWRITE_FUNCTION_EVENT_DATA'],
|
||||
'APPWRITE_FUNCTION_DATA' => $request['env']['APPWRITE_FUNCTION_DATA'],
|
||||
'APPWRITE_FUNCTION_USER_ID' => $request['env']['APPWRITE_FUNCTION_USER_ID'],
|
||||
'APPWRITE_FUNCTION_JWT' => $request['env']['APPWRITE_FUNCTION_JWT'],
|
||||
'APPWRITE_FUNCTION_PROJECT_ID' => $request['env']['APPWRITE_FUNCTION_PROJECT_ID'],
|
||||
]);
|
||||
};
|
||||
|
|
Binary file not shown.
|
@ -2,14 +2,14 @@
|
|||
|
||||
return function ($request, $response) {
|
||||
return $response->json([
|
||||
'APPWRITE_FUNCTION_ID' => $request->env['APPWRITE_FUNCTION_ID'],
|
||||
'APPWRITE_FUNCTION_NAME' => $request->env['APPWRITE_FUNCTION_NAME'],
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' => $request->env['APPWRITE_FUNCTION_DEPLOYMENT'],
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $request->env['APPWRITE_FUNCTION_TRIGGER'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request->env['APPWRITE_FUNCTION_RUNTIME_NAME'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request->env['APPWRITE_FUNCTION_RUNTIME_VERSION'],
|
||||
'APPWRITE_FUNCTION_EVENT' => $request->env['APPWRITE_FUNCTION_EVENT'],
|
||||
'APPWRITE_FUNCTION_EVENT_DATA' => $request->env['APPWRITE_FUNCTION_EVENT_DATA'],
|
||||
'APPWRITE_FUNCTION_ID' => $request['env']['APPWRITE_FUNCTION_ID'],
|
||||
'APPWRITE_FUNCTION_NAME' => $request['env']['APPWRITE_FUNCTION_NAME'],
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' => $request['env']['APPWRITE_FUNCTION_DEPLOYMENT'],
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $request['env']['APPWRITE_FUNCTION_TRIGGER'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request['env']['APPWRITE_FUNCTION_RUNTIME_NAME'],
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request['env']['APPWRITE_FUNCTION_RUNTIME_VERSION'],
|
||||
'APPWRITE_FUNCTION_EVENT' => $request['env']['APPWRITE_FUNCTION_EVENT'],
|
||||
'APPWRITE_FUNCTION_EVENT_DATA' => $request['env']['APPWRITE_FUNCTION_EVENT_DATA'],
|
||||
'UNICODE_TEST' => "êä" // TODO: Re-add unicode test to FunctionsCustomServerTest.php
|
||||
]);
|
||||
};
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue