GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 4bf8be...514a6b )
by Sam
06:11
created

Module::createEntrypoint()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0494

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 14
cts 17
cp 0.8235
rs 9.1344
c 0
b 0
f 0
cc 3
nc 4
nop 0
crap 3.0494
1
<?php
2
declare(strict_types=1);
3
4
namespace SamIT\Yii2\PhpFpm;
5
6
use SamIT\Docker\Context;
7
use yii\base\InvalidConfigException;
8
use yii\base\UnknownPropertyException;
9
use yii\helpers\ArrayHelper;
10
use yii\helpers\Console;
11
12
/**
13
 * Class Module
14
 * @package SamIT\Yii2\PhpFpm
15
 * @property-write string[] $additionalExtensions
16
 * @property-write string|int[] $additionalPoolConfig
17
 * @property-write string[] $additionalPhpConfig
18
 * @property-write string[] $additionalFpmConfig
19
 */
20
class Module extends \yii\base\Module
21
{
22
    /**
23
     * The variables will be written to /runtime/env.json as JSON, where your application can read them.
24
     * @var string[] List of required environment variables. If one is missing the container will exit.
25
     *
26
     */
27
    public $environmentVariables = [];
28
29
    /**
30
     * @var array Pool directives
31
     * @see http://php.net/manual/en/install.fpm.configuration.php
32
     *
33
     */
34
    public $poolConfig = [
35
        'user' => 'nobody',
36
        'group' => 'nobody',
37
        'listen' => 9000,
38
        'pm' => 'dynamic',
39
        'pm.max_children' => 40,
40
        'pm.start_servers' => 3,
41
        'pm.min_spare_servers' => 1,
42
        'pm.max_spare_servers' => 3,
43
        'access.log' => '/proc/self/fd/2',
44
        'clear_env' => 'yes',
45
        'catch_workers_output' => 'yes'
46
    ];
47
48
    /**
49
     * @var array PHP configuration, supplied via php_admin_value in fpm config.
50
     */
51
    public $phpConfig = [
52
        'upload_max_filesize' => '20M',
53
        'post_max_size' => '25M'
54
    ];
55
56
    /**
57
     * @var array Global directives
58
     * @see http://php.net/manual/en/install.fpm.configuration.php
59
     *
60
     */
61
    public $fpmConfig = [
62
        'error_log' => '/proc/self/fd/2',
63
        'daemonize' => 'no',
64
    ];
65
66
    /**
67
     * List of php extensions to install
68
     */
69
    public $extensions = [
70
        'ctype',
71
        'gd',
72
        'iconv',
73
        'intl',
74
        'json',
75
        'mbstring',
76
        'session',
77
        'pdo_mysql',
78
        'session',
79
        'curl'
80
    ];
81
82
    /**
83
     * @var string The name of the created image.
84
     */
85
    public $image;
86
87
    /**
88
     * @var string The tag of the created image.
89
     */
90
    public $tag = 'latest';
91
92
    /**
93
     * @var bool wheter to push successful builds.
94
     */
95
    public $push = false;
96
97
    /**
98
     * @var string Location of composer.json / composer.lock
99
     */
100
    public $composerFilePath = '@app/../';
101
102
    /**
103
     * @var string[] List of console commands that are executed upon container launch.
104
     */
105
    public $initializationCommands = [];
106
    /**
107
     * @return string A PHP-FPM config file.
108
     */
109 1
    protected function createFpmConfig()
110
    {
111 1
        $config = [];
112
        // Add global directives.
113 1
        $config[] = '[global]';
114 1
        foreach ($this->fpmConfig as $key => $value) {
115 1
            $config[] = "$key = $value";
116
        }
117
118
        // Add pool directives.
119 1
        $poolConfig = $this->poolConfig;
120 1
        foreach ($this->phpConfig as $key => $value) {
121 1
            $poolConfig["php_admin_value[$key]"] = $value;
122
        }
123
124 1
        $config[] = '[www]';
125 1
        foreach ($poolConfig as $key => $value) {
126 1
            $config[] = "$key = $value";
127
        }
128
129 1
        return \implode("\n", $config);
130
    }
131
132
    /**
133
     * @return string A shell script that checks for existence of (non-empty) variables and runs php-fpm.
134
     */
135 1
    protected function createEntrypoint(): string
136
    {
137
        // Get the route.
138 1
        $script = "/project/{$this->getConsoleEntryScript()}";
139 1
        $result = [];
140 1
        $result[] = '#!/bin/sh';
141
        // Check for variables.
142 1
        foreach ($this->environmentVariables as $name) {
143
            $result[] = \strtr('if [ -z "${name}" ]; then echo "Variable \${name} is required."; exit 1; fi', [
144
                '{name}' => $name
145
            ]);
146
        }
147
148
        // Check if runtime directory is writable.
149 1
        $result[] = <<<SH
150
su nobody -s /bin/touch /runtime/testfile && rm /runtime/testfile;
151
if [ $? -ne 0 ]; then
152
  echo Runtime directory is not writable;
153
  exit 1
154
fi
155
SH;
156
157
158
159
        // Check if runtime is a tmpfs.
160 1
        $message = Console::ansiFormat('/runtime should really be a tmpfs.', [Console::FG_RED]);
161 1
        $result[] = <<<SH
162 1
grep 'tmpfs /runtime' /proc/mounts;
163
if [ $? -ne 0 ]; then
164 1
  echo $message;
165
fi
166
SH;
167 1
        $result[] = <<<SH
168
su nobody -s /bin/touch /runtime/env.json
169
jq -n env > /runtime/env.json
170
if [ $? -ne 0 ]; then
171
  echo "failed to store env in /runtime/env.json";
172
  exit 1
173
fi
174
SH;
175
176
177 1
        foreach ($this->initializationCommands as $route) {
178
            $result[] = "$script $route --interactive=0 || exit";
179
        }
180 1
        $result[] = 'exec php-fpm7 --force-stderr --fpm-config /php-fpm.conf';
181 1
        return \implode("\n", $result);
182
    }
183
184
    /**
185
     * @param string $version This is stored in the VERSION environment variable.
186
     * @throws InvalidConfigException
187
     * @return Context
188
     */
189 1
    public function createBuildContext(string $version): Context
190
    {
191 1
        $root = \Yii::getAlias('@app');
192 1
        if (!\is_string($root)) {
193
            throw new \Exception('Alias @app must be defined.');
194
        }
195
196 1
        $context = new Context();
197
198
        /**
199
         * BEGIN COMPOSER
200
         */
201 1
        $context->command('FROM composer');
202 1
        $context->addFile('/build/composer.json', \Yii::getAlias($this->composerFilePath) .'/composer.json');
203
204 1
        if (\file_exists(\Yii::getAlias($this->composerFilePath) . '/composer.lock')) {
205 1
            $context->addFile('/build/composer.lock', \Yii::getAlias($this->composerFilePath) . '/composer.lock');
206
        }
207
208 1
        $context->run('composer global require hirak/prestissimo');
209
210 1
        $context->run('cd /build && composer install --no-dev --no-autoloader --ignore-platform-reqs --prefer-dist');
211
212
        // Add the actual source code.
213 1
        $context->addFile('/build/' . \basename($root), $root);
214 1
        $context->run('cd /build && composer dumpautoload -o --no-dev');
215
        /**
216
         * END COMPOSER
217
         */
218
219 1
        $context->from('php:7.4-fpm-alpine');
220 1
        $context->addUrl("/usr/local/bin/", "https://raw.githubusercontent.com/mlocati/docker-php-extension-installer/master/install-php-extensions");
221 1
        $context->run("chmod +x /usr/local/bin/install-php-extensions");
222 1
        $context->run('install-php-extensions ' . implode(' ', $this->extensions));
223 1
        $context->run('mkdir /runtime && chown nobody:nobody /runtime');
224 1
        $context->volume('/runtime');
225 1
        $context->copyFromLayer("/project", "0", "/build");
226
227 1
        $context->add('/entrypoint.sh', $this->createEntrypoint());
228
229 1
        $context->run('chmod +x /entrypoint.sh');
230
231 1
        $context->add('/php-fpm.conf', $this->createFpmConfig());
232
233 1
        $context->run("php-fpm --force-stderr --fpm-config /php-fpm.conf -t");
234
235 1
        $context->entrypoint(["/entrypoint.sh"]);
236
237 1
        $context->env('VERSION', $version);
238
        // Test if we can run a console command.
239 1
        if (\stripos($this->getConsoleEntryScript(), 'codecept') === false) {
240
            $script = "[ -f /project/{$this->getConsoleEntryScript()} ]";
241
            $context->run($script);
242
        }
243 1
        return $context;
244
    }
245
246
    /**
247
     * @throws InvalidConfigException in case the app is not configured as expected
248
     * @return string the relative path of the (console) entry script with respect to the project (not app) root.
249
     */
250 1
    public function getConsoleEntryScript(): string
251
    {
252 1
        $full = \array_slice(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), -1)[0]['file'];
253 1
        $relative = \strtr($full, [\dirname(\Yii::getAlias('@app')) => '']);
254 1
        if ($relative === $full) {
255
            throw new InvalidConfigException("The console entry script must be located inside the @app directory.");
256
        }
257 1
        return \ltrim($relative, '/');
258
    }
259
260
261 1
    public function __set($name, $value): void
262
    {
263 1
        if (\strncmp($name, 'additional', 10) === 0) {
264 1
            $this->add(\lcfirst(\substr($name, 10)), $value);
265
        } else {
266
            parent::__set($name, $value);
267
        }
268 1
    }
269
270 1
    private function add($name, array $value): void
271
    {
272 1
        if (!\property_exists($this, $name)) {
273
            throw new UnknownPropertyException("Unknown property $name");
274
        }
275 1
        $this->$name = ArrayHelper::merge($this->$name, $value);
276 1
    }
277
}
278