Passed
Push — test ( 52bb81...4c4f16 )
by Tom
02:50
created

Docker::hostConfigBind()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

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