Completed
Push — master ( 767252...f8efe9 )
by Tom
06:09 queued 01:44
created

Docker::hostConfigBind()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 15
nc 5
nop 2
dl 0
loc 26
ccs 16
cts 16
cp 1
crap 5
rs 9.4555
c 1
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
    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
        foreach ($binds as $bind) {
121 2
            $pattern = sprintf('(^([^:]+):%s(?::ro)?$)', preg_quote($mountPoint, '()'));
122 2
            if (preg_match($pattern, $bind, $matches)) {
123 1
                return $matches[1];
124
            }
125
        }
126
127 1
        return null;
128
    }
129
130
    /**
131
     * inspect a container for a mount on $mountPoint on the host system and
132
     * return it (the "device").
133
     *
134
     * @param string $container name or id to inspect
135
     * @param string $mountPoint absolute path to search for a host mount for
136
     *
137
     * @return bool|string
138
     */
139 4
    public function hostDevice($container, $mountPoint)
140
    {
141 4
        $result = $this->hostConfigBind($container, $mountPoint);
142 4
        if (null === $result) {
143 3
            return $mountPoint;
144
        }
145
146 1
        return $result;
147
    }
148
149
    /**
150
     * @return Docker\ProcessManager
151
     */
152 1
    public function getProcessManager()
153
    {
154 1
        return new Docker\ProcessManager($this->exec);
155
    }
156
}
157