Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

Commit

Permalink
PHP runtime (#581)
Browse files Browse the repository at this point in the history
* First commit php runtime

* update php runtime server, fix dev-guide

* refs #000: Fix psr2 coding style

* refs #000: Changed name to kubeless

* update php controller

* Fix response status

* changed name to Controller

* add an example using dependencies

* Fix healtz route typo

* updated langruntime to make use of configmap

* refator runFunction method just using plain include

* add composer.lock, fix include dir

* Add an example using the request object

* Adding tests to bats

* fixing case

* Fixing case

* Add verify tasks

* check the container logs instead of stdout

* Using docker image hash to test travis

* Timeout support

* use just a basic set_time_limit but it does not prevent functions like sleep() to override it

* Use pcntl_fork to make a real timeout

* php upgraded to 7.2

* removed temp files

* Fix healtz route

* Update docker image sha

* Adding php timeout integration tests

* Fixing routing problem due this bug slimphp/Slim#2107

* Just use nginx as the webserver because the php native one does not support multithread requests (retry job)

* Fix supported http verbs

* Retry 5 times

* adding debug

* Change verify of get-php-deps function

* Missing newline

* adding update tests functions

* Move delete function
  • Loading branch information
paolomainardi authored and murali-reddy committed Feb 15, 2018
1 parent 52f1cee commit 5844c40
Show file tree
Hide file tree
Showing 19 changed files with 723 additions and 2 deletions.
1 change: 1 addition & 0 deletions docker/runtime/php-7.2/http-trigger/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
vendor
150 changes: 150 additions & 0 deletions docker/runtime/php-7.2/http-trigger/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<?php

namespace Kubeless;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require 'vendor/autoload.php';
$_SERVER['SCRIPT_NAME'] = '/';

class TimeoutFunctionException extends \RuntimeException {}

class Controller
{
private $app;
private $timeout;
private $root;
private $function;
private $currentDir;

public function __construct()
{

$this->app = new \Slim\App();
$this->timeout = (!empty(getenv('FUNC_TIMEOUT')) ? getenv('FUNC_TIMEOUT') : 180);
$this->root = (!empty(getenv('MOD_ROOT_PATH')) ? getenv('MOD_ROOT_PATH') : '/kubeless/');
$this->file = sprintf("/kubeless/%s.php", getenv('MOD_NAME'));
$this->function = getenv('FUNC_HANDLER');
$this->currentDir = getcwd();
}

/**
* Run the injected function.
*
* @return void
*/
private function runFunction(Request $request)
{
set_time_limit($this->timeout);
ob_start();
chdir($this->root);
include $this->file;
if (!function_exists($this->function)) {
throw new \Exception(sprintf("Function %s not exist", $this->function));
}
$pid = pcntl_fork();
if ($pid == 0) {
call_user_func_array($this->function, [$request]);
$response = ob_get_contents();
ob_end_clean();
chdir($this->currentDir);

return $response;
} else {
sleep($this->timeout);
posix_kill($pid, SIGKILL);
throw new TimeoutFunctionException();
}
}

/**
* Validate some required variables.
*
* @return void
*/
private function validate()
{
if (empty(getenv('FUNC_HANDLER'))) {
throw new \Exception("FUNC_HANDLER is empty");
}
if (empty(getenv('MOD_NAME'))) {
throw new \Exception("MOD_NAME is empty");
}
if (!file_exists($this->file)) {
throw new \Exception(sprintf("%s cannot be found", $this->file));
}
}

/**
* Root route.
*
* @param Request $request
* @param Response $response
* @param array $args
* @return Response $repsonse
*/
public function root(Request $request, Response $response, array $args)
{
try {
$this->validate();
$ret = $this->runFunction($request);
$response->getBody()->write($ret);

return $response;
} catch (\Kubeless\TimeoutFunctionException $e) {
$res = $response->withStatus(408);

return $res;
} catch (\Exception $e) {
$response->getBody()->write($e->getMessage() . "\n");
$res = $response->withStatus(500);

return $res;
}
}

/**
* Healthz route.
*
* @param Request $request
* @param Response $response
* @param array $args
* @return Response $response
*/
public function healthz(Request $request, Response $response, array $args)
{
try {
$this->validate();
$response->getBody()->write("OK");

return $response;
} catch (\Exception $e) {
$response->getBody()->write($e->getMessage() . "\n");
$res = $response->withStatus(500);

return $res;
}
}

/**
* Run the slim framework.
*/
public function run()
{
try {
$this->app->any('/', [$this, 'root']);
$this->app->any('/healthz', [$this, 'healthz']);
$this->app->run();
} catch (\Exception $e) {
ob_end_flush();
ob_start();
print $e->getMessage();
header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
}

}
}

$server = new \Kubeless\Controller();
$server->run();
49 changes: 49 additions & 0 deletions docker/runtime/php-7.2/http-trigger/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
FROM php:7.2-fpm-stretch

# Install composer
ENV COMPOSER_HOME /composer
ENV PATH="/root/.composer/vendor/bin:${PATH}"
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV FUNC_PORT 8080

RUN apt-get update \
&& apt-get install -y \
git unzip libxml2-dev libpng-dev libjpeg-dev libssl-dev libicu-dev \
libcurl4-openssl-dev libmcrypt-dev postgresql-server-dev-all nginx supervisor \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN docker-php-ext-install \
opcache \
bcmath \
ctype \
curl \
dom \
iconv \
gd \
gettext \
intl \
json \
mysqli \
pgsql \
pcntl \
pdo \
ftp \
pdo_mysql \
pdo_pgsql \
phar \
simplexml \
xmlrpc \
zip

WORKDIR /app
COPY . /app

RUN composer install --prefer-dist --optimize-autoloader
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY config/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 8080
ENTRYPOINT [ "" ]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
10 changes: 10 additions & 0 deletions docker/runtime/php-7.2/http-trigger/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@


build:
docker build -t paolomainardi/kubeless-php:latest .

push: build
docker push paolomainardi/kubeless-php:latest

php-cs-fixer:
docker run -it --rm -v $${PWD}:/wd -w /wd shouldbee/php-cs-fixer fix Controller.php || true
10 changes: 10 additions & 0 deletions docker/runtime/php-7.2/http-trigger/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"autoload": {
"psr-4": {
"PHPEnv\\": "src/"
}
},
"require": {
"slim/slim": "^3.9"
}
}
Loading

0 comments on commit 5844c40

Please sign in to comment.