StepContainer::obtainLabelOptions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Runner\Containers;
6
7
use Ktomk\Pipelines\Cli\Docker;
8
use Ktomk\Pipelines\File\Pipeline\Step;
9
use Ktomk\Pipelines\LibFs;
10
use Ktomk\Pipelines\LibFsPath;
11
use Ktomk\Pipelines\Runner\Containers;
12
use Ktomk\Pipelines\Runner\Docker\ArgsBuilder;
13
use Ktomk\Pipelines\Runner\Runner;
14
15
/**
16
 * Class StepContainer
17
 *
18
 * @package Ktomk\Pipelines\Runner
19
 */
20
class StepContainer
21
{
22
    /**
23
     * @var null|string id of the (running) container
24
     */
25
    private $id;
26
27
    /**
28
     * @var string name of the container
29
     */
30
    private $name;
31
32
    /**
33
     * @var Step
34
     */
35
    private $step;
36
37
    /**
38
     * @var Runner
39
     */
40
    private $runner;
41
42
    /**
43
     * @var StepServiceContainers
44
     */
45
    private $serviceContainers;
46
47
    /**
48
     * StepContainer constructor.
49
     *
50
     * @param string $name
51
     * @param Step $step
52
     * @param Runner $runner
53
     */
54 14
    public function __construct($name, Step $step, Runner $runner)
55
    {
56 14
        $this->name = $name;
57 14
        $this->step = $step;
58 14
        $this->runner = $runner;
59
    }
60
61
    /**
62
     * the display id
63
     *
64
     *   side-effect: if id is null, this signals a dry-run which is made
65
     * visible by the string "*dry-run*"
66
     *
67
     * @return string
68
     */
69 8
    public function getDisplayId()
70
    {
71 8
        return isset($this->id) ? $this->id : '*dry-run*';
72
    }
73
74
    /**
75
     * @return null|string ID of (once) running container or null if not yet running
76
     */
77 3
    public function getId()
78
    {
79 3
        return $this->id;
80
    }
81
82
    /**
83
     * @return string name of the container [undefined: NULL if no name generated yet]
84
     */
85 5
    public function getName()
86
    {
87 5
        return $this->name;
88
    }
89
90
    /**
91
     * @return StepServiceContainers
92
     */
93 4
    public function getServiceContainers()
94
    {
95 4
        $this->serviceContainers = $this->serviceContainers ?: new StepServiceContainers($this->step, $this->runner);
96
97 4
        return $this->serviceContainers;
98
    }
99
100
    /**
101
     * @param null|bool $keep a container on true, kill on false (if it exists)
102
     *
103
     * @return null|string
104
     */
105 6
    public function keepOrKill($keep = null)
106
    {
107 6
        $keep = null === $keep ? $this->runner->getFlags()->reuseContainer() : $keep;
108
109 6
        $name = $this->name;
110
111 6
        $processManager = Docker::create($this->runner->getExec())->getProcessManager();
112
113 6
        if (false === $keep) {
114 2
            $processManager->zapContainersByName($name);
115
116 2
            return $this->id = null;
117
        }
118
119 5
        return $this->id = $processManager->findContainerIdByName($name);
120
    }
121
122
    /**
123
     * @param bool $kill
124
     * @param bool $remove
125
     *
126
     * @return void
127
     */
128 2
    public function killAndRemove($kill, $remove)
129
    {
130 2
        $id = $this->getDisplayId();
131
132 2
        Containers::execKillAndRemove($this->runner->getExec(), $id, $kill, $remove);
133
    }
134
135
    /**
136
     * @param array $args
137
     *
138
     * @return array array(int $status, string $out, string $err)
139
     */
140 4
    public function run(array $args)
141
    {
142 4
        $execRun = Containers::execRun($this->runner->getExec(), $args);
143 4
        $this->id = array_pop($execRun);
144
145 4
        return $execRun;
146
    }
147
148
    /**
149
     * @param int $status
150
     *
151
     * @return void
152
     */
153 4
    public function shutdown($status)
154
    {
155 4
        $id = $this->getDisplayId();
156
157 4
        $message = sprintf(
158
            'keeping container id %s',
159 4
            (string)substr($id, 0, 12)
160
        );
161
162 4
        Containers::execShutdownContainer(
163 4
            $this->runner->getExec(),
164 4
            $this->runner->getStreams(),
165
            $id,
166
            $status,
167 4
            $this->runner->getFlags(),
168
            $message
169
        );
170
171 4
        $this->getServiceContainers()->shutdown($status);
172
    }
173
174
    /** docker run args mapping methods */
175
176
    /**
177
     * @return array
178
     */
179 3
    public function obtainLabelOptions()
180
    {
181 3
        $labels = LabelsBuilder::createFromRunner($this->runner);
182
183 3
        $labels->setRole('step');
184
185 3
        return ArgsBuilder::optMap('-l', $labels->toArray());
186
    }
187
188
    /**
189
     * @return array
190
     */
191 3
    public function obtainUserOptions()
192
    {
193 3
        $user = $this->runner->getRunOpts()->getUser();
194
195 3
        $userOpts = array();
196
197 3
        if (null === $user) {
198 3
            return $userOpts;
199
        }
200
201 1
        $userOpts = array('--user', $user);
202
203 1
        if (LibFs::isReadableFile('/etc/passwd') && LibFs::isReadableFile('/etc/group')) {
204 1
            $userOpts[] = '-v';
205 1
            $userOpts[] = '/etc/passwd:/etc/passwd:ro';
206 1
            $userOpts[] = '-v';
207 1
            $userOpts[] = '/etc/group:/etc/group:ro';
208
        }
209
210 1
        return $userOpts;
211
    }
212
213
    /**
214
     * @return string[]
215
     */
216 3
    public function obtainSshOptions()
217
    {
218 3
        $ssh = $this->runner->getRunOpts()->getSsh();
219 3
        $env = $this->runner->getEnv();
220
221 3
        $sshOpts = array();
222
        if (
223 3
            null === $ssh
224 1
            || (null === $sshAuthSock = $env->getInheritValue('SSH_AUTH_SOCK'))
225 1
            || '' === trim($sshAuthSock)
226 3
            || !is_writable($sshAuthSock)
227
        ) {
228 3
            return $sshOpts;
229
        }
230
231 1
        $sshOpts = array(
232
            '-v',
233 1
            LibFsPath::gateAbsolutePortable($sshAuthSock) . ':/var/run/ssh-auth.sock:ro',
234
            '-e',
235
            'SSH_AUTH_SOCK=/var/run/ssh-auth.sock',
236
        );
237
238 1
        return $sshOpts;
239
    }
240
}
241