Skip to content
This repository has been archived by the owner on Oct 19, 2023. It is now read-only.

Commit

Permalink
Adding automatic setup for stackdriver integration (#333)
Browse files Browse the repository at this point in the history
  • Loading branch information
Takashi Matsuo authored Jul 14, 2017
1 parent 8657998 commit 4138057
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
/**
* Copyright 2017 Google Inc.
*
* Licensed 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.
*/

namespace Google\Cloud\Runtimes\Builder\Exception;

class GoogleCloudVersionException extends \RuntimeException
{
}
31 changes: 28 additions & 3 deletions builder/gen-dockerfile/src/Builder/GenFilesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Google\Cloud\Runtimes\Builder\Exception\ExactVersionException;
use Google\Cloud\Runtimes\Builder\Exception\MissingDocumentRootException;
use Google\Cloud\Runtimes\DetectPhpVersion;
use Google\Cloud\Runtimes\ValidateGoogleCloud;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -33,6 +34,7 @@ class GenFilesCommand extends Command
const DEFAULT_WORKSPACE = '/workspace';
const DEFAULT_YAML_PATH = 'app.yaml';
const DEFAULT_FRONT_CONTROLLER_FILE = 'index.php';
const STACKDRIVER_INTEGRATION_ENV = 'ENABLE_STACKDRIVER_INTEGRATION';

/* @var string */
private $workspace;
Expand Down Expand Up @@ -140,6 +142,18 @@ protected function envsFromAppYaml()
: [];
}

protected static function isStackdriverIntegrationEnabled($envs)
{
if (array_key_exists(self::STACKDRIVER_INTEGRATION_ENV, $envs)
&& filter_var(
$envs[self::STACKDRIVER_INTEGRATION_ENV],
FILTER_VALIDATE_BOOLEAN
)) {
return true;
}
return false;
}

protected function envsFromRuntimeConfig()
{
$ret = [];
Expand All @@ -152,15 +166,16 @@ protected function envsFromRuntimeConfig()
: [];
$maps = [
'document_root' => 'DOCUMENT_ROOT',
'whitelist_functions' => 'WHITELIST_FUNCTIONS',
'enable_stackdriver_integration' => self::STACKDRIVER_INTEGRATION_ENV,
'front_controller_file' => 'FRONT_CONTROLLER_FILE',
'nginx_conf_http_include' => 'NGINX_CONF_HTTP_INCLUDE',
'nginx_conf_include' => 'NGINX_CONF_INCLUDE',
'nginx_conf_override' => 'NGINX_CONF_OVERRIDE',
'php_fpm_conf_override' => 'PHP_FPM_CONF_OVERRIDE',
'php_ini_override' => 'PHP_INI_OVERRIDE',
'supervisord_conf_addition' => 'SUPERVISORD_CONF_ADDITION',
'supervisord_conf_override' => 'SUPERVISORD_CONF_OVERRIDE'
'supervisord_conf_override' => 'SUPERVISORD_CONF_OVERRIDE',
'whitelist_functions' => 'WHITELIST_FUNCTIONS'
];
$errorKeys = [];
foreach ($maps as $k => $v) {
Expand Down Expand Up @@ -219,6 +234,14 @@ public function createDockerfile($baseImage)
. ' in app.yaml.'
);
}
if (self::isStackdriverIntegrationEnabled($envs)) {
ValidateGoogleCloud::doCheck($this->workspace);
$enableStackdriverCmd = 'RUN /bin/bash /stackdriver-files/'
. 'enable_stackdriver_integration.sh';
$envs['IS_BATCH_DAEMON_RUNNING'] = 'true';
} else {
$enableStackdriverCmd = '';
}
$envString = 'ENV ';
foreach ($envs as $key => $value) {
$envString .= "$key=$value \\\n";
Expand All @@ -227,9 +250,11 @@ public function createDockerfile($baseImage)
$envString = rtrim($envString, "\n");
$envString = rtrim($envString, '\\');
$template = $this->twig->load('Dockerfile.twig');

$dockerfile = $template->render(array(
'base_image' => $baseImage,
'env_string' => $envString
'env_string' => $envString,
'enable_stackdriver_cmd' => $enableStackdriverCmd
));
file_put_contents($this->workspace . '/Dockerfile', $dockerfile);
}
Expand Down
100 changes: 100 additions & 0 deletions builder/gen-dockerfile/src/ValidateGoogleCloud.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php
/**
* Copyright 2017 Google Inc.
*
* Licensed 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.
*/

namespace Google\Cloud\Runtimes;

use Composer\Semver\Semver;
use Composer\Semver\Comparator;
use Google\Cloud\Runtimes\Builder\Exception\GoogleCloudVersionException;

class ValidateGoogleCloud
{
const MINIMUM_VERSION = 'v0.33';

/*
* @param string $workspace
* @return bool
* @throw GoogleCloudVersionException
*/
public static function doCheck($workspace)
{
$filename = $workspace . '/composer.json';
if (! file_exists($filename)) {
throw new GoogleCloudVersionException(
'composer.json does not exist'
);
}
$composer = json_decode(file_get_contents($filename), true);
if (is_array($composer)
&& array_key_exists('require', $composer)
&& array_key_exists('google/cloud', $composer['require'])) {
$constraints = $composer['require']['google/cloud'];
} else {
throw new GoogleCloudVersionException(
'google/cloud not found in composer.json'
);
}

$versions = self::getCurrentGoogleCloudVersions();

// Check all the available versions against the constraints
// and returns matched ones
$filtered = Semver::satisfiedBy($versions, $constraints);

if (count($filtered) === 0) {
throw new GoogleCloudVersionException(
'no available matching version of google/cloud'
);
}
foreach ($filtered as $version) {
if (Comparator::lessThan($version, self::MINIMUM_VERSION)) {
throw new GoogleCloudVersionException(
'stackdriver integration needs google/cloud '
. self::MINIMUM_VERSION . ' or higher'
);
}
}
return true;
}

/**
* Determine available versions for google/cloud
* @return array
*/
private static function getCurrentGoogleCloudVersions()
{
exec(
'composer show --all google/cloud |grep \'versions : \'',
$output,
$ret
);
if ($ret !== 0) {
throw new GoogleCloudVersionException(
'Failed to determine available versions of google/cloud package'
);
}
// Remove the title
$output = substr($output[0], strlen('versions : '));

// Split the version strings
$versions = preg_split('/[,\s]+/', $output);

// Remove '*', indicator for the latest stable
$versions = array_diff($versions, ['*']);
return $versions;
}
}
2 changes: 2 additions & 0 deletions builder/gen-dockerfile/src/templates/Dockerfile.twig
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ RUN /build-scripts/composer.sh

RUN /bin/bash /build-scripts/move-config-files.sh
RUN /bin/bash /build-scripts/lockdown.sh

{{ enable_stackdriver_cmd }}
48 changes: 48 additions & 0 deletions builder/gen-dockerfile/tests/GenFilesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,54 @@ public function dataProvider()
"DETECTED_PHP_VERSION=7.1 \n"
]
],
[
// stackdriver simple case
__DIR__ . '/test_data/stackdriver_simple',
null,
'',
'/app/web',
'added by the php runtime builder',
'gcr.io/google-appengine/php71:latest',
["GOOGLE_RUNTIME_RUN_COMPOSER_SCRIPT=true \\\n",
"FRONT_CONTROLLER_FILE=index.php \\\n",
"DETECTED_PHP_VERSION=7.1 \\\n",
"IS_BATCH_DAEMON_RUNNING=true \n",
"enable_stackdriver_integration.sh"
]
],
[
// stackdriver no composer.json
__DIR__ . '/test_data/stackdriver_no_composer',
null,
'',
'/app/web',
'added by the php runtime builder',
'gcr.io/google-appengine/php71:latest',
[],
'\\Google\\Cloud\\Runtimes\\Builder\\Exception\\GoogleCloudVersionException'
],
[
// stackdriver no google/cloud
__DIR__ . '/test_data/stackdriver_no_google_cloud',
null,
'',
'/app/web',
'added by the php runtime builder',
'gcr.io/google-appengine/php71:latest',
[],
'\\Google\\Cloud\\Runtimes\\Builder\\Exception\\GoogleCloudVersionException'
],
[
// stackdriver old google/cloud
__DIR__ . '/test_data/stackdriver_old_google_cloud',
null,
'',
'/app/web',
'added by the php runtime builder',
'gcr.io/google-appengine/php71:latest',
[],
'\\Google\\Cloud\\Runtimes\\Builder\\Exception\\GoogleCloudVersionException'
],
[
// PHP 5.6
__DIR__ . '/test_data/php56',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
env: flex
runtime: php

runtime_config:
enable_stackdriver_integration: true
document_root: web
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
env: flex
runtime: php

runtime_config:
enable_stackdriver_integration: true
document_root: web
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"google/cloud-logging": "*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
env: flex
runtime: php

runtime_config:
enable_stackdriver_integration: true
document_root: web
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"google/cloud": "^0.32"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
env: flex
runtime: php

runtime_config:
enable_stackdriver_integration: true
document_root: web
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"google/cloud": "^0.34.1"
}
}
3 changes: 3 additions & 0 deletions php-base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ ENV NGINX_DIR=/etc/nginx \

# Install build scripts - composer, nginx, php
COPY build-scripts /build-scripts
# Files for stackdriver setup
COPY stackdriver-files /stackdriver-files

RUN chown www-data /build-scripts

ARG RUNTIME_DISTRIBUTION="gcp-php-runtime-jessie"
Expand Down
11 changes: 11 additions & 0 deletions php-base/stackdriver-files/batch-daemon.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[program:batch-daemon]
command = php -d auto_prepend_file='' -d disable_functions='' /app/vendor/bin/google-cloud-batch daemon
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes=0
user = www-data
autostart = true
autorestart = true
priority = 5
stopwaitsecs = 20
25 changes: 25 additions & 0 deletions php-base/stackdriver-files/enable_stackdriver_integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# Copyright 2017 Google Inc.
#
# Licensed 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.


# A shell script for installing composer
set -xe

# To start the batch daemon
cp /stackdriver-files/batch-daemon.conf /etc/supervisor/conf.d

# For enabling automatic error reporting
cp /stackdriver-files/stackdriver-errorreporting.ini ${PHP_DIR}/lib/conf.d
2 changes: 2 additions & 0 deletions php-base/stackdriver-files/stackdriver-errorreporting.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Automatic error reporting
auto_prepend_file='/app/vendor/google/cloud/src/ErrorReporting/prepend.php'

0 comments on commit 4138057

Please sign in to comment.