Test Failed
Push — master ( 5a8b85...1177ba )
by Zoilo
01:48
created

ControlGroups::extractContainerId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 13
rs 10
1
<?php
2
3
namespace ZoiloMora\ElasticAPM\Utils;
4
5
final class ControlGroups
6
{
7
    const PATH = '/proc/self/cgroup';
8
9
    /**
10
     * @var self
11
     */
12
    private static $instance;
13
14
    /**
15
     * @var string|null
16
     */
17
    private $podId = null;
18
19
    /**
20
     * @var string|null
21
     */
22
    private $containerId = null;
23
24
    /**
25
     * @return self
26
     */
27
    public static function instance()
28
    {
29
        if (null === self::$instance) {
30
            self::$instance = new self();
31
        }
32
33
        return self::$instance;
34
    }
35
36
    private function __construct()
37
    {
38
        if (false === $this->isAllowedOperatingSystem()) {
39
            return;
40
        }
41
42
        $cGroups = $this->deserialize();
43
        $this->extractInfo($cGroups);
44
    }
45
46
    /**
47
     * @return string|null
48
     */
49
    public function podId()
50
    {
51
        return $this->podId;
52
    }
53
54
    /**
55
     * @return string|null
56
     */
57
    public function containerId()
58
    {
59
        return $this->containerId;
60
    }
61
62
    /**
63
     * @return bool
64
     */
65
    private function isAllowedOperatingSystem()
66
    {
67
        return 'Linux' === PHP_OS;
68
    }
69
70
    /**
71
     * @return array
72
     */
73
    private function deserialize()
74
    {
75
        if (false === is_readable(self::PATH)) {
76
            return [];
77
        }
78
79
        $cGroup = file_get_contents(self::PATH);
80
        $lines = explode(PHP_EOL, $cGroup);
81
82
        $result = [];
83
        foreach ($lines as $line) {
84
            list($hierarchyId, $controller, $path) = explode(':', $line);
85
86
            $result[] = [
87
                'hierarchy_id' => $hierarchyId,
88
                'controller' => $controller,
89
                'path' => $path,
90
            ];
91
        }
92
93
        return $result;
94
    }
95
96
    /**
97
     * @param array $cGroups
98
     */
99
    private function extractInfo(array $cGroups)
100
    {
101
        foreach ($cGroups as $cGroup) {
102
            $path = $cGroup['path'];
103
104
            $dirname = $this->getDirname($path);
105
            $basename = $this->getBasename($path);
106
107
            $podId = $this->extractPodId($dirname);
108
            if (null !== $podId) {
109
                $this->podId = $podId;
110
                $this->containerId = $basename;
111
112
                break;
113
            }
114
115
            $containerId = $this->extractContainerId($basename);
116
            if (null !== $containerId) {
117
                $this->containerId = $containerId;
118
            }
119
        }
120
    }
121
122
    /**
123
     * @param string $path
124
     *
125
     * @return string
126
     */
127
    private function getDirname($path)
128
    {
129
        $position = 1 + strrpos($path, '/');
130
131
        return substr($path, 0, $position);
132
    }
133
134
    /**
135
     * @param string $path
136
     *
137
     * @return string
138
     */
139
    private function getBasename($path)
140
    {
141
        $position = 1 + strrpos($path, '/');
142
        $basename = substr($path, $position);
143
144
        if ('.scope' === substr($basename, -6)) {
145
            $basename = substr($basename, 0, -6);
146
        }
147
148
        return $basename;
149
    }
150
151
    /**
152
     * @param string $dirname
153
     *
154
     * @return string|null
155
     */
156
    private function extractPodId($dirname)
157
    {
158
        preg_match(
159
            '/(?:^\/kubepods\/[^\/]+\/pod([^\/]+)\/$)/',
160
            $dirname,
161
            $output
162
        );
163
164
        if (0 !== count($output)) {
165
            return $output[1];
166
        }
167
168
        preg_match(
169
            '/(?:^\/kubepods\.slice\/kubepods-[^\/]+\.slice\/kubepods-[^\/]+-pod([^\/]+)\.slice\/$)/',
170
            $dirname,
171
            $output
172
        );
173
174
        if (0 !== count($output)) {
175
            return $output[1];
176
        }
177
178
        return null;
179
    }
180
181
    /**
182
     * @param string $basename
183
     *
184
     * @return string|null
185
     */
186
    private function extractContainerId($basename)
187
    {
188
        preg_match(
189
            '/^[[:xdigit:]]{64}$/',
190
            $basename,
191
            $output_array
192
        );
193
194
        if (0 !== count($output_array)) {
195
            return $output_array[0];
196
        }
197
198
        return null;
199
    }
200
}
201