Containers::execRunServiceContainer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 6
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner;
6
7
use Ktomk\Pipelines\Cli\Docker;
8
use Ktomk\Pipelines\Cli\Exec;
9
use Ktomk\Pipelines\Cli\Streams;
10
use Ktomk\Pipelines\File\Definitions\Service;
11
use Ktomk\Pipelines\File\Pipeline\Step;
12
use Ktomk\Pipelines\Lib;
13
use Ktomk\Pipelines\Runner\Containers\NameBuilder;
14
use Ktomk\Pipelines\Runner\Containers\StepContainer;
15
use Ktomk\Pipelines\Runner\Docker\ArgsBuilder;
16
use Ktomk\Pipelines\Runner\Docker\ImageLogin;
17
18
/**
19
 * Class Containers
20
 *
21
 * Containers as per the runner
22
 *
23
 * An extraction of more generic container functionality from the
24
 * StepContainer that is more specific and did host them since
25
 * introducing services
26
 *
27
 * @package Ktomk\Pipelines\Runner
28
 */
29
class Containers
30
{
31
    /**
32
     * @var Runner
33
     */
34
    private $runner;
35
36
    /**
37
     * kill and remove static implementation
38
     *
39
     * @param Exec $exec
40
     * @param string|string[] $idOrIds container id(s) or name(s)
41
     * @param bool $kill
42
     * @param bool $remove
43
     *
44
     * @return void
45
     */
46 2
    public static function execKillAndRemove(Exec $exec, $idOrIds, $kill, $remove)
47
    {
48 2
        if ($kill) {
49 2
            Docker::create($exec)->getProcessManager()->kill($idOrIds);
50
        }
51
52 2
        if ($remove) {
53 2
            Docker::create($exec)->getProcessManager()->remove($idOrIds);
54
        }
55
    }
56
57
    /**
58
     * @param Exec $exec
59
     * @param array $args
60
     *
61
     * @return array array(int $status, string $out, string $err, string|null $id)
62
     */
63 1
    public static function execRun(Exec $exec, array $args)
64
    {
65 1
        $status = $exec->capture('docker', Lib::merge('run', $args), $out, $err);
66
67 1
        $id = null;
68 1
        if (0 === $status) {
69 1
            $id = rtrim($out) ?: null;
70
        }
71
72 1
        return array($status, $out, $err, $id);
73
    }
74
75
    /**
76
     * Run service container
77
     *
78
     * @param Exec $exec
79
     * @param Service $service
80
     * @param callable $resolver
81
     * @param string $prefix
82
     * @param string $project
83
     * @param array $labels
84
     *
85
     * @return array
86
     * @psalm-return array{0: int, 1: array}
87
     */
88 1
    public static function execRunServiceContainer(Exec $exec, Service $service, $resolver, $prefix, $project, array $labels)
89
    {
90 1
        $execRunServiceRunner = self::execRunServiceContainerImpl($exec, $service, $resolver, $prefix, $project);
91
92 1
        return $execRunServiceRunner(false, Lib::merge('--detach', ArgsBuilder::optMap('-l', $labels)));
93
    }
94
95
    /**
96
     * Run service container attached
97
     *
98
     * @param Exec $exec
99
     * @param Service $service
100
     * @param callable $resolver
101
     * @param string $prefix
102
     * @param string $project
103
     * @param array $labels
104
     *
105
     * @return array
106
     */
107 1
    public static function execRunServiceContainerAttached(Exec $exec, Service $service, $resolver, $prefix, $project, array $labels)
108
    {
109 1
        $execRunServiceRunner = self::execRunServiceContainerImpl($exec, $service, $resolver, $prefix, $project);
110
111 1
        return $execRunServiceRunner(true, Lib::merge('--rm', ArgsBuilder::optMap('-l', $labels)));
112
    }
113
114
    /**
115
     * @param Exec $exec
116
     * @param Service $service
117
     * @param callable $resolver
118
     * @param string $prefix
119
     * @param string $project
120
     *
121
     * @return \Closure
122
     */
123 3
    public static function execRunServiceContainerImpl(Exec $exec, Service $service, $resolver, $prefix, $project)
124
    {
125
        /**
126
         * @param bool $pass (or capture)
127
         * @param string|string[] $additionalArgs
128
         *
129
         * @return array
130
         */
131 3
        return function ($pass, $additionalArgs) use ($exec, $service, $resolver, $prefix, $project) {
132 3
            $network = array('--network', 'host');
133 3
            $image = $service->getImage();
134 3
            ImageLogin::loginImage($exec, $resolver, null, $image);
135
136 3
            $containerName = NameBuilder::serviceContainerName($prefix, $service->getName(), $project);
137
138 3
            $variables = $resolver($service->getVariables());
139
140 3
            $args = Lib::merge(
141
                $network,
142
                '--name',
143
                $containerName,
144
                $additionalArgs,
145 3
                ArgsBuilder::optMap('-e', $variables, true),
146 3
                $image->getName()
147
            );
148
149 3
            $status = $pass
150 2
                ? $exec->pass('docker', Lib::merge('run', $args))
151 2
                : $exec->capture('docker', Lib::merge('run', $args), $out, $err);
152
153 3
            return array($status, $network);
154
        };
155
    }
156
157
    /**
158
     * @param Exec $exec
159
     * @param Streams $streams
160
     * @param string|string[] $idOrIds
161
     * @param int $status
162
     * @param Flags $flags
163
     * @param string $message
164
     *
165
     * @return void
166
     *
167
     * @see StepRunner::shutdownStepContainer
168
     */
169 1
    public static function execShutdownContainer(Exec $exec, Streams $streams, $idOrIds, $status, Flags $flags, $message)
170
    {
171
        # keep container on error
172 1
        if (0 !== $status && $flags->keepOnError()) {
173 1
            $streams->err(sprintf("error, %s\n", $message));
174
175 1
            return;
176
        }
177
178
        # keep or kill/remove container
179 1
        self::execKillAndRemove($exec, $idOrIds, $flags->killContainer(), $flags->removeContainer());
180
181 1
        if ($flags->keep()) {
182 1
            $streams->out(sprintf("%s\n", $message));
183
        }
184
    }
185
186
    /**
187
     * StepContainers constructor.
188
     *
189
     * @param Runner $runner
190
     */
191 2
    public function __construct(Runner $runner)
192
    {
193 2
        $this->runner = $runner;
194
    }
195
196
    /**
197
     * @param Step $step
198
     *
199
     * @return StepContainer
200
     */
201 1
    public function createStepContainer(Step $step)
202
    {
203 1
        $prefix = $this->runner->getPrefix();
204 1
        $projectName = $this->runner->getProject();
205
206 1
        $name = NameBuilder::stepContainerNameByStep($step, $prefix, $projectName);
207
208 1
        return new StepContainer($name, $step, $this->runner);
209
    }
210
}
211