Test Failed
Pull Request — master (#85)
by Keoghan
06:33
created

Porter   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 224
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 24
eloc 54
c 4
b 0
f 0
dl 0
loc 224
ccs 0
cts 72
cp 0
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A turnOffService() 0 12 3
A start() 0 9 4
A stop() 0 13 3
A restart() 0 8 2
A getDockerImageSet() 0 4 1
A isUp() 0 3 1
A __construct() 0 10 1
A status() 0 3 1
A compose() 0 5 1
A logs() 0 3 1
A turnOnService() 0 12 3
A restartServing() 0 20 2
A build() 0 3 1
1
<?php
2
3
namespace App;
4
5
use App\Models\PhpVersion;
6
use App\Models\Setting;
7
use App\Events\StartedPorter;
8
use App\Events\StoppedPorter;
9
use App\Events\StoppingPorter;
10
use App\Events\StartingPorter;
11
use App\Events\BuiltDockerCompose;
12
use App\Events\StartedPorterService;
13
use App\Events\StoppedPorterService;
14
use App\Events\StoppingPorterService;
15
use App\Events\StartingPorterService;
16
use App\Support\Console\DockerCompose\CliCommandFactory;
17
use App\Support\Console\DockerCompose\YamlBuilder;
18
use App\Support\Contracts\Cli;
19
use App\Support\Contracts\ImageRepository;
20
use App\Support\Contracts\ImageSetRepository;
21
22
class Porter
23
{
24
    /**
25
     * The docker images sets used by Porter to serve sites.
26
     *
27
     * @var ImageSetRepository
28
     */
29
    protected $imageSets;
30
31
    /**
32
     * The CLI class that executes commands.
33
     *
34
     * @var Cli
35
     */
36
    protected $cli;
37
38
    /**
39
     * The Docker composer command factory.
40
     *
41
     * @var CliCommandFactory
42
     */
43
    protected $dockerCompose;
44
45
    /**
46
     * The DockerCompose YAML file builder.
47
     *
48
     * @var YamlBuilder
49
     */
50
    protected $yamlBuilder;
51
52
    /**
53
     * Porter constructor.
54
     *
55
     * @param ImageSetRepository $imageSets
56
     * @param Cli                $cli
57
     * @param CliCommandFactory  $commandFactory
58
     * @param YamlBuilder        $yamlBuilder
59
     */
60
    public function __construct(
61
        ImageSetRepository $imageSets,
62
        Cli $cli,
63
        CliCommandFactory $commandFactory,
64
        YamlBuilder $yamlBuilder
65
    ) {
66
        $this->imageSets = $imageSets;
67
        $this->cli = $cli;
68
        $this->dockerCompose = $commandFactory;
69
        $this->yamlBuilder = $yamlBuilder;
70
    }
71
72
    /**
73
     * Check if the Porter containers are running.
74
     *
75
     * @param string|null $service
76
     *
77
     * @return bool
78
     */
79
    public function isUp($service = null)
80
    {
81
        return (bool) stristr($this->dockerCompose->command('ps')->perform(), "porter_{$service}");
82
    }
83
84
    /**
85
     * Create the docker-compose.yaml file.
86
     */
87
    public function compose()
88
    {
89
        $filePath = $this->yamlBuilder->build($this->getDockerImageSet());
90
91
        event(new BuiltDockerCompose($filePath));
92
    }
93
94
    /**
95
     * Start Porter containers, optionally start a specific service, and force them to be recreated.
96
     *
97
     * @param string|null $service
98
     * @param bool        $recreate
99
     */
100
    public function start($service = null, $recreate = false)
101
    {
102
        $recreate = $recreate ? '--force-recreate ' : '';
103
104
        event(is_null($service) ? new StartingPorter : new StartingPorterService($service));
105
106
        $this->dockerCompose->command("up -d {$recreate}--remove-orphans {$service}")->realTime()->perform();
107
108
        event(is_null($service) ? new StartedPorter : new StartedPorterService($service));
109
    }
110
111
    /**
112
     * Stop Porter containers.
113
     *
114
     * @param string|null $service
115
     */
116
    public function stop($service = null)
117
    {
118
        event(is_null($service) ? new StoppingPorter : new StoppingPorterService($service));
119
120
        if ($service) {
121
            $this->dockerCompose->command("stop {$service}")->realTime()->perform();
122
            event(new StoppedPorterService($service));
123
124
            return;
125
        }
126
127
        $this->dockerCompose->command('down --remove-orphans')->realTime()->perform();
128
        event(new StoppedPorter);
129
    }
130
131
    /**
132
     * Restart Porter containers.
133
     *
134
     * @param string|null $service
135
     */
136
    public function restart($service = null)
137
    {
138
        if ($this->isUp($service)) {
139
            $this->stop($service);
140
        }
141
142
        // If we're restarting something it's probably because config changed - so force recreation
143
        $this->start($service, true);
144
    }
145
146
    /**
147
     * Restart serving, picking up changes in used PHP versions and NGiNX.
148
     */
149
    public function restartServing()
150
    {
151
        // Build up docker-compose again - so we pick up any new PHP containers to be used
152
        $this->compose();
153
154
        if (!$this->isUp()) {
155
            return;
156
        }
157
158
        PhpVersion::active()
159
            ->get()
160
            ->reject(function ($phpVersion) {
161
                return $this->isUp($phpVersion->fpm_name);
162
            })
163
            ->each(function ($phpVersion) {
164
                $this->start($phpVersion->fpm_name);
165
                $this->start($phpVersion->cli_name);
166
            });
167
168
        $this->restart('nginx');
169
    }
170
171
    /**
172
     * Turn a service on.
173
     *
174
     * @param string $service
175
     */
176
    public function turnOnService($service)
177
    {
178
        if (setting("use_{$service}") == 'on') {
179
            return;
180
        }
181
182
        Setting::updateOrCreate("use_{$service}", 'on');
183
184
        $this->compose();
185
186
        if ($this->isUp()) {
187
            $this->start($service);
188
        }
189
    }
190
191
    /**
192
     * Turn a service off.
193
     *
194
     * @param string $service
195
     */
196
    public function turnOffService($service)
197
    {
198
        if (in_array(setting("use_{$service}"), [null, 'off'])) {
199
            return;
200
        }
201
202
        Setting::updateOrCreate("use_{$service}", 'off');
203
204
        if ($this->isUp()) {
205
            $this->stop($service);
206
        }
207
        $this->compose();
208
    }
209
210
    /**
211
     * (Re)build Porter containers.
212
     */
213
    public function build()
214
    {
215
        $this->dockerCompose->command('build')->perform();
216
    }
217
218
    /**
219
     * Get the current image set to use.
220
     *
221
     * @return ImageRepository
222
     */
223
    public function getDockerImageSet()
224
    {
225
        return $this->imageSets->getImageRepository(
226
            setting('docker_image_set', config('porter.default-docker-image-set'))
227
        );
228
    }
229
230
    /**
231
     * Show container status.
232
     */
233
    public function status()
234
    {
235
        echo $this->dockerCompose->command('ps')->perform();
236
    }
237
238
    /**
239
     * Show container logs.
240
     *
241
     * @param string|null $service
242
     */
243
    public function logs($service = null)
244
    {
245
        echo $this->dockerCompose->command("logs {$service}")->perform();
246
    }
247
}
248