Passed
Push — master ( d8d9f2...800fb3 )
by Tom
02:30
created

StepContainer::shutdown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 1

Importance

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