From a5624ab1aa12b1393dc43719fba2b1ea8bc7d504 Mon Sep 17 00:00:00 2001 From: Luke-Roy-IBM <83647952+Luke-Roy-IBM@users.noreply.github.com> Date: Thu, 20 Jul 2023 10:06:54 +0200 Subject: [PATCH] PHP 8.2 Initial commit (#134) * PHP 8.2 Initial commit * Package updates --- .github/workflows/ci.yaml | 2 + README.md | 25 +++- core/php8.2Action/CHANGELOG.md | 38 ++++++ core/php8.2Action/Dockerfile | 115 ++++++++++++++++++ core/php8.2Action/build.gradle | 19 +++ core/php8.2Action/compile.php | 82 +++++++++++++ core/php8.2Action/composer.json | 11 ++ core/php8.2Action/php.ini | 37 ++++++ core/php8.2Action/runner.php | 92 ++++++++++++++ settings.gradle | 1 + .../Php82ActionContainerTests.scala | 27 ++++ 11 files changed, 445 insertions(+), 4 deletions(-) create mode 100644 core/php8.2Action/CHANGELOG.md create mode 100644 core/php8.2Action/Dockerfile create mode 100644 core/php8.2Action/build.gradle create mode 100755 core/php8.2Action/compile.php create mode 100644 core/php8.2Action/composer.json create mode 100644 core/php8.2Action/php.ini create mode 100755 core/php8.2Action/runner.php create mode 100644 tests/src/test/scala/runtime/actionContainers/Php82ActionContainerTests.scala diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4f61fc70..9a4d016b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -92,6 +92,8 @@ jobs: ./gradlew :core:php8.0Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT ./gradlew :core:php8.1Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=nightly ./gradlew :core:php8.1Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT + ./gradlew :core:php8.2Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=nightly + ./gradlew :core:php8.2Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT - name: Push Release Images if: ${{ env.PUSH_RELEASE == 'true' }} working-directory: runtime diff --git a/README.md b/README.md index f076b8f0..6b349398 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,16 @@ ## PHP versions -This runtime provides PHP 8.1, 8.0 +This runtime provides PHP 8.2, 8.1 and 8.0 ### Give it a try today To use as a docker action +PHP 8.2: +``` +wsk action update myAction myAction.php --docker openwhisk/action-php-v8.2:latest +``` + PHP 8.1: ``` wsk action update myAction myAction.php --docker openwhisk/action-php-v8.1:latest @@ -43,6 +48,11 @@ This works on any deployment of Apache OpenWhisk ### To use on deployment that contains the runtime as a kind To use as a kind action +PHP 8.2: +``` +wsk action update myAction myAction.php --kind php:8.2 +``` + PHP 8.1: ``` wsk action update myAction myAction.php --kind php:8.1 @@ -57,19 +67,21 @@ wsk action update myAction myAction.php --kind php:8.0 ### Local development ``` +./gradlew core:php8.2Action:distDocker ./gradlew core:php8.1Action:distDocker ./gradlew core:php8.0Action:distDocker ``` -This will produce the images `whisk/action-php-v8.1` and `whisk/action-php-v8.0` respectively. +This will produce the images `whisk/action-php-v8.2` and `whisk/action-php-v8.1`, `whisk/action-php-v8.0` respectively. Build and Push image ``` docker login +./gradlew core:php8.2Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io +./gradlew core:php8.1Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io ./gradlew core:php8.0Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io -./gradlew core:php7.4Action:distDocker -PdockerImagePrefix=$prefix-user -PdockerRegistry=docker.io ``` -Deploy OpenWhisk using ansible environment that contains the kinds `php:8.1` and `php:8.0` +Deploy OpenWhisk using ansible environment that contains the kinds `php:8.2`, `php:8.1` and `php:8.0` Assuming you have OpenWhisk already deploy locally and `OPENWHISK_HOME` pointing to root directory of OpenWhisk core repository. Set `ROOTDIR` to the root directory of this repository. @@ -91,8 +103,13 @@ ln -s ${ROOTDIR}/ansible/environments/local ${OPENWHISK_HOME}/ansible/environmen wskdev fresh -t local-php ``` + To use as docker action push to your own dockerhub account ``` +docker tag whisk/php8.2Action $user_prefix/action-php-v8.2 +docker push $user_prefix/action-php-v8.2 +``` +``` docker tag whisk/php8.1Action $user_prefix/action-php-v8.1 docker push $user_prefix/action-php-v8.1 ``` diff --git a/core/php8.2Action/CHANGELOG.md b/core/php8.2Action/CHANGELOG.md new file mode 100644 index 00000000..eb18d23e --- /dev/null +++ b/core/php8.2Action/CHANGELOG.md @@ -0,0 +1,38 @@ + + +## Initial release + +- Added: PHP: 8.2.8 +- Added: PHP extensions in addition to the standard ones: + - bcmath + - curl + - gd + - intl + - mbstring + - mysqli + - pdo_mysql + - pdo_pgsql + - pdo_sqlite + - soap + - zip + - mongo +- Added: Composer packages: + - [guzzlehttp/guzzle](https://packagist.org/packages/guzzlehttp/guzzle): 7.7.0 + - [ramsey/uuid](https://packagist.org/packages/ramsey/uuid): 4.7.4 diff --git a/core/php8.2Action/Dockerfile b/core/php8.2Action/Dockerfile new file mode 100644 index 00000000..d0540942 --- /dev/null +++ b/core/php8.2Action/Dockerfile @@ -0,0 +1,115 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# build go proxy from source +FROM golang:1.20 AS builder_source +ARG GO_PROXY_GITHUB_USER=apache +ARG GO_PROXY_GITHUB_BRANCH=master +RUN git clone --branch ${GO_PROXY_GITHUB_BRANCH} \ + https://github.com/${GO_PROXY_GITHUB_USER}/openwhisk-runtime-go /src ;\ + cd /src ; env GO111MODULE=on CGO_ENABLED=0 go build main/proxy.go && \ + mv proxy /bin/proxy + +# or build it from a release +FROM golang:1.20 AS builder_release +ARG GO_PROXY_RELEASE_VERSION=1.20@1.22.0 +RUN curl -sL \ + https://github.com/apache/openwhisk-runtime-go/archive/{$GO_PROXY_RELEASE_VERSION}.tar.gz\ + | tar xzf -\ + && cd openwhisk-runtime-go-*/main\ + && GO111MODULE=on CGO_ENABLED=0 go build -o /bin/proxy + +FROM php:8.2-cli-bullseye + +# select the builder to use +ARG GO_PROXY_BUILD_FROM=release + +# install PHP extensions +RUN apt-get -y update \ + # Upgrade installed packages to get latest security fixes if the base image does not contain them already. + && apt-get upgrade -y --no-install-recommends \ + && apt-get -y install --no-install-recommends \ + unzip \ + libfreetype6 \ + libicu67 \ + libjpeg62-turbo \ + libpng16-16 \ + libssl1.1 \ + libxml2 \ + libzip4 \ + libpq5 \ + zip \ + libfreetype6-dev \ + libicu-dev \ + libjpeg-dev \ + libpng-dev \ + libssl-dev \ + libxml2-dev \ + libzip-dev \ + postgresql-server-dev-13 \ + \ + && docker-php-ext-install \ + bcmath \ + gd \ + intl \ + mysqli \ + opcache \ + pdo_mysql \ + pdo_pgsql \ + soap \ + zip \ + \ + && mkdir -p /usr/src/php/ext/mongodb \ + && curl -fsSL https://pecl.php.net/get/mongodb-1.14.0 | tar xvz -C "/usr/src/php/ext/mongodb" --strip 1 \ + && docker-php-ext-install -j$(nproc) mongodb \ + \ + && apt-get purge -y --auto-remove $PHPIZE_DEPS \ + && apt-get purge -y --auto-remove libfreetype6-dev \ + libicu-dev \ + libjpeg-dev \ + libpng-dev \ + libssl-dev \ + libxml2-dev \ + libzip-dev \ + postgresql-server-dev-13 \ + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /usr/src/php + +COPY php.ini /usr/local/etc/php + +# install composer +RUN curl -s -f -L -o /tmp/installer.php https://getcomposer.org/installer \ + && php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer \ + && composer --ansi --version --no-interaction --no-plugins --no-scripts + +# install default Composer dependencies +RUN mkdir -p /phpAction/composer +COPY composer.json /phpAction/composer +RUN cd /phpAction/composer && /usr/bin/composer install --no-plugins --no-scripts --prefer-dist --no-dev -o && rm composer.lock + +# install proxy binary along with compile and launcher scripts +RUN mkdir -p /phpAction/action +WORKDIR /phpAction +COPY --from=builder_source /bin/proxy /bin/proxy_source +COPY --from=builder_release /bin/proxy /bin/proxy_release +RUN mv /bin/proxy_${GO_PROXY_BUILD_FROM} /bin/proxy +ADD compile.php /bin/compile.php +ADD runner.php /bin/runner.php +ENV OW_COMPILER=/bin/compile.php + +ENTRYPOINT [ "/bin/proxy" ] diff --git a/core/php8.2Action/build.gradle b/core/php8.2Action/build.gradle new file mode 100644 index 00000000..21cbd74e --- /dev/null +++ b/core/php8.2Action/build.gradle @@ -0,0 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +ext.dockerImageName = 'action-php-v8.2' +apply from: '../../gradle/docker.gradle' diff --git a/core/php8.2Action/compile.php b/core/php8.2Action/compile.php new file mode 100755 index 00000000..d74939b4 --- /dev/null +++ b/core/php8.2Action/compile.php @@ -0,0 +1,82 @@ +#!/usr/bin/env php + "); + exit(1); + } + $main = $argv[1]; + $src = realpath($argv[2]); + $bin = realpath($argv[3]); + + $shim = $bin.'/exec'; + + sources($src); + build($shim, $src, $main); +} + +/** + * Sort out the source code + * + * 1. Copy src/exec to src/index.php if necessary + * 2. Ensure vendor directory exists + */ +function sources(string $src) +{ + // If the file uploaded by the user is a plain PHP file, then + // the filename will be called exec by the action proxy. + // Rename it to index.php + if (file_exists($src . '/exec')) { + rename($src . '/exec', $src . '/index.php'); + } + + // put vendor in the right place if it doesn't exist + if (!is_dir($src . '/vendor')) { + exec('cp -a /phpAction/composer/vendor ' . escapeshellarg($src . '/vendor')); + } +} + +/** + * Create bin/exec shim + */ +function build(string $shim, string $src, string $main) : void +{ + $contents = << $value) { + if ($key !== 'value') { + $envKeyName = '__OW_' . strtoupper($key); + $_ENV[$envKeyName] = $value; + putenv($envKeyName . '=' . $value); + } + } + + $values = $data['value'] ?? []; + try { + $result = $__functionName($values); + + // convert result to an array if we can + if (is_object($result)) { + if (method_exists($result, 'getArrayCopy')) { + $result = $result->getArrayCopy(); + } elseif ($result instanceof stdClass) { + $result = (array)$result; + } + } elseif ($result === null) { + $result = []; + } + + // process the result + if (!is_array($result)) { + file_put_contents('php://stderr', 'Result must be an array but has type "' + . gettype($result) . '": ' . $result); + file_put_contents('php://stdout', 'The action did not return a dictionary or array.'); + $result = (string)$result; + } else { + // cast result to an object for json_encode to ensure that an empty array becomes "{} + $result = json_encode((object)$result); + } + } catch (Throwable $e) { + file_put_contents('php://stderr', (string)$e); + $result = 'An error occurred running the action.'; + } + + // ensure that the sentinels will be on their own lines + file_put_contents('php://stderr', "\n"); + file_put_contents('php://stdout', "\n"); + + // send result to fd/3 + fwrite($fd3, $result . "\n"); +} diff --git a/settings.gradle b/settings.gradle index ea85c7aa..b5fbde62 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,6 +19,7 @@ include 'tests' include 'core:php8.0Action' include 'core:php8.1Action' +include 'core:php8.2Action' rootProject.name = 'runtime-php' diff --git a/tests/src/test/scala/runtime/actionContainers/Php82ActionContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/Php82ActionContainerTests.scala new file mode 100644 index 00000000..b8ff1c05 --- /dev/null +++ b/tests/src/test/scala/runtime/actionContainers/Php82ActionContainerTests.scala @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime.actionContainers + +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class Php82ActionContainerTests extends Php7ActionContainerTests { + + override lazy val phpContainerImageName = "action-php-v8.2" +}