Passed
Push — master ( 88d9d6...ec4c8d )
by Tom
04:42
created

Docker::getProcessManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Cli;
6
7
use UnexpectedValueException;
8
9
/**
10
 * Php wrapper for the Docker CLI
11
 */
12
class Docker
13
{
14
    /**
15
     * @var Exec
16
     */
17
    private $exec;
18
19
    /**
20
     * @var string
21
     */
22
    private $name = 'docker';
23
24
    /**
25
     * @param null|Exec $exec [optional]
26
     *
27
     * @return Docker
28
     */
29 1
    public static function create(Exec $exec = null)
30
    {
31 1
        if (null === $exec) {
32 1
            $exec = new Exec();
33
        }
34
35 1
        return new self($exec);
36
    }
37
38 6
    public function __construct(Exec $exec)
39
    {
40 6
        $this->exec = $exec;
41 6
    }
42
43
    /**
44
     * @throws \RuntimeException
45
     *
46
     * @return bool
47
     */
48 1
    public function hasCommand()
49
    {
50 1
        $status = $this->exec->capture(
51 1
            'command',
52 1
            array('-v', $this->name)
53
        );
54
55 1
        return 0 === $status;
56
    }
57
58
    /**
59
     * @throws \RuntimeException
60
     * @throws UnexpectedValueException
61
     *
62
     * @return null|string
63
     */
64 1
    public function getVersion()
65
    {
66 1
        $status = $this->exec->capture(
67 1
            $this->name,
68 1
            array('version', '--format', '{{.Server.Version}}'),
69
            $out
70
        );
71
72 1
        if (0 !== $status) {
73 1
            return null;
74
        }
75
76
        # parse version string
77 1
        $return = preg_match(
78 1
            '~^(\d+\\.\d+\\.\d+(?:-ce)?|master-dockerproject-20(?:19|[2-9]\d)-[01]\d-[0-3][1-9])\\n$~',
79
            $out,
80
            $matches
81
        );
82
83 1
        if (false === $return) {
84
            throw new UnexpectedValueException('Regex pattern failed'); // @codeCoverageIgnore
85
        }
86
87 1
        if (0 === $return) {
88 1
            trigger_error(
89 1
                sprintf('Failed to parse "%s" for Docker version', $out)
90
            );
91
92 1
            return '0.0.0-err';
93
        }
94
95 1
        return $matches[1];
96
    }
97
98
    /**
99
     * inspect a container for a mount on $mountPoint on the host system and
100
     * return it (the "device").
101
     *
102
     * @param string $container name or id to inspect
103
     * @param string $mountPoint absolute path in the container to search for a mount for
104
     *
105
     * @return null|string null if no such mount point in the container, path on host if
106
     */
107 4
    public function hostConfigBind($container, $mountPoint)
108
    {
109 4
        $exec = $this->exec;
110
111 4
        $status = $exec->capture('docker', array(
112 4
            'inspect', $container,
113
        ), $out);
114 4
        if (0 !== $status) {
115 1
            return null;
116
        }
117
118 3
        $data = json_decode($out, true);
119 3
        if (!isset($data[0]['HostConfig']['Binds'])) {
120 1
            return null;
121
        }
122
123 2
        $binds = $data[0]['HostConfig']['Binds'];
124
125 2
        foreach ($binds as $bind) {
126 2
            $pattern = sprintf('(^([^:]+):%s(?::ro)?$)', preg_quote($mountPoint, '()'));
127 2
            if (preg_match($pattern, $bind, $matches)) {
128 1
                return $matches[1];
129
            }
130
        }
131
132 1
        return null;
133
    }
134
135
    /**
136
     * inspect a container for a mount on $mountPoint on the host system and
137
     * return it (the "device").
138
     *
139
     * @param string $container name or id to inspect
140
     * @param string $mountPoint absolute path to search for a host mount for
141
     *
142
     * @return bool|string
143
     */
144 4
    public function hostDevice($container, $mountPoint)
145
    {
146 4
        $result = $this->hostConfigBind($container, $mountPoint);
147 4
        if (null === $result) {
148 3
            return $mountPoint;
149
        }
150
151 1
        return $result;
152
    }
153
154
    /**
155
     * @return Docker\ProcessManager
156
     */
157 1
    public function getProcessManager()
158
    {
159 1
        return new Docker\ProcessManager($this->exec);
160
    }
161
}
162