Passed
Push — test ( b77416...a68431 )
by Tom
02:58
created

Containers::execRun()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

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