Passed
Push — master ( 800fb3...1ce7d0 )
by Tom
04:22
created

StepContainer::obtainLabelOptions()   A

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 null|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 15
    public function __construct($name, Step $step, Runner $runner)
55
    {
56 15
        $this->name = $name;
57 15
        $this->step = $step;
58 15
        $this->runner = $runner;
59 15
    }
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 null|string name of the container, 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
        return $this->serviceContainers
96 4
            = $this->serviceContainers ?: new StepServiceContainers($this->step, $this->runner);
97
    }
98
99
    /**
100
     * @param null|bool $keep a container on true, kill on false (if it exists)
101
     *
102
     * @return null|string
103
     */
104 7
    public function keepOrKill($keep = null)
105
    {
106 7
        $keep = null === $keep ? $this->runner->getFlags()->reuseContainer() : $keep;
107
108 7
        $name = $this->name;
109 7
        if (null === $name) {
110 1
            throw new \BadMethodCallException('Container has no name yet');
111
        }
112
113 6
        $processManager = Docker::create($this->runner->getExec())->getProcessManager();
114
115 6
        if (false === $keep) {
116 2
            $processManager->zapContainersByName($name);
117
118 2
            return $this->id = null;
119
        }
120
121 5
        return $this->id = $processManager->findContainerIdByName($name);
122
    }
123
124
    /**
125
     * @param bool $kill
126
     * @param bool $remove
127
     *
128
     * @return void
129
     */
130 2
    public function killAndRemove($kill, $remove)
131
    {
132 2
        $id = $this->getDisplayId();
133
134 2
        Containers::execKillAndRemove($this->runner->getExec(), $id, $kill, $remove);
135 2
    }
136
137
    /**
138
     * @param array $args
139
     *
140
     * @return array array(int $status, string $out, string $err)
141
     */
142 4
    public function run(array $args)
143
    {
144 4
        $execRun = Containers::execRun($this->runner->getExec(), $args);
145 4
        $this->id = array_pop($execRun);
146
147 4
        return $execRun;
148
    }
149
150
    /**
151
     * @param int $status
152
     *
153
     * @return void
154
     */
155 4
    public function shutdown($status)
156
    {
157 4
        $id = $this->getDisplayId();
158
159 4
        $message = sprintf(
160 4
            'keeping container id %s',
161 4
            (string)substr($id, 0, 12)
162
        );
163
164 4
        Containers::execShutdownContainer(
165 4
            $this->runner->getExec(),
166 4
            $this->runner->getStreams(),
167 4
            $id,
168 4
            $status,
169 4
            $this->runner->getFlags(),
170 4
            $message
171
        );
172
173 4
        $this->getServiceContainers()->shutdown($status);
174 4
    }
175
176
    /** docker run args mapping methods */
177
178
    /**
179
     * @return array
180
     */
181 1
    public function obtainLabelOptions()
182
    {
183 1
        $labels = new LabelsBuilder();
184
185 1
        $labels->setRole('step');
186
187 1
        return ArgsBuilder::optMap('-l', $labels->toArray());
188
    }
189
190
    /**
191
     * @return array
192
     */
193 3
    public function obtainUserOptions()
194
    {
195 3
        $user = $this->runner->getRunOpts()->getUser();
196
197 3
        $userOpts = array();
198
199 3
        if (null === $user) {
200 3
            return $userOpts;
201
        }
202
203 1
        $userOpts = array('--user', $user);
204
205 1
        if (LibFs::isReadableFile('/etc/passwd') && LibFs::isReadableFile('/etc/group')) {
206 1
            $userOpts[] = '-v';
207 1
            $userOpts[] = '/etc/passwd:/etc/passwd:ro';
208 1
            $userOpts[] = '-v';
209 1
            $userOpts[] = '/etc/group:/etc/group:ro';
210
        }
211
212 1
        return $userOpts;
213
    }
214
215 3
    public function obtainSshOptions()
216
    {
217 3
        $ssh = $this->runner->getRunOpts()->getSsh();
218 3
        $env = $this->runner->getEnv();
219
220 3
        $sshOpts = array();
221
        if (
222 3
            null === $ssh
223 1
            || (null === $sshAuthSock = $env->getInheritValue('SSH_AUTH_SOCK'))
224 1
            || '' === trim($sshAuthSock)
225 3
            || !is_writable($sshAuthSock)
226
        ) {
227 3
            return $sshOpts;
228
        }
229
230
        $sshOpts = array(
231 1
            '-v',
232 1
            LibFsPath::gateAbsolutePortable($sshAuthSock) . ':/var/run/ssh-auth.sock:ro',
233 1
            '-e',
234 1
            'SSH_AUTH_SOCK=/var/run/ssh-auth.sock',
235
        );
236
237 1
        return $sshOpts;
238
    }
239
}
240