Skip to content

Commit 9155e3a

Browse files
committed
initial commit
1 parent c8bfce0 commit 9155e3a

File tree

4 files changed

+427
-1
lines changed

4 files changed

+427
-1
lines changed

Container.php

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace SoftBricks\Docker;
4+
5+
class Container
6+
{
7+
public $id;
8+
public $image;
9+
public $command;
10+
public $createdAt;
11+
public $runningFor;
12+
public $ports;
13+
public $status;
14+
public $size;
15+
public $names;
16+
public $labels;
17+
public $mounts;
18+
public $networks;
19+
20+
/**
21+
* @return mixed
22+
*/
23+
public function getId()
24+
{
25+
return $this->id;
26+
}
27+
28+
/**
29+
* @return mixed
30+
*/
31+
public function getImage()
32+
{
33+
return $this->image;
34+
}
35+
36+
/**
37+
* @return mixed
38+
*/
39+
public function getCommand()
40+
{
41+
return $this->command;
42+
}
43+
44+
/**
45+
* @return mixed
46+
*/
47+
public function getCreatedAt()
48+
{
49+
return $this->createdAt;
50+
}
51+
52+
/**
53+
* @return mixed
54+
*/
55+
public function getRunningFor()
56+
{
57+
return $this->runningFor;
58+
}
59+
60+
/**
61+
* @return string[]
62+
*/
63+
public function getPorts()
64+
{
65+
return explode(',', $this->ports);
66+
}
67+
68+
/**
69+
* @return mixed
70+
*/
71+
public function getStatus()
72+
{
73+
return $this->status;
74+
}
75+
76+
/**
77+
* @return mixed
78+
*/
79+
public function getSize()
80+
{
81+
return $this->size;
82+
}
83+
84+
/**
85+
* @return string[]
86+
*/
87+
public function getLabels()
88+
{
89+
return explode(',', $this->labels);
90+
}
91+
92+
/**
93+
* @return string[]
94+
*/
95+
public function getMounts()
96+
{
97+
return explode(',', $this->mounts);
98+
}
99+
100+
/**
101+
* @return string[]
102+
*/
103+
public function getNetworks()
104+
{
105+
return explode(',', $this->networks);
106+
}
107+
108+
/**
109+
* @return string[]
110+
*/
111+
public function getNames()
112+
{
113+
return explode(',', $this->names);
114+
}
115+
}

Docker.php

+269
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
<?php
2+
3+
namespace SoftBricks\Docker;
4+
5+
class Docker
6+
{
7+
/**
8+
* Checks if given output array contains given string
9+
*
10+
* @param $output
11+
* @param $string
12+
* @return bool
13+
*/
14+
private function outputContains($output, $string)
15+
{
16+
foreach($output as $line) {
17+
if (strpos($line, $string) !== false) {
18+
return true;
19+
}
20+
}
21+
return false;
22+
}
23+
24+
/**
25+
* Executes docker command with given args
26+
*
27+
* @param array|string $args
28+
* @return array
29+
*/
30+
public function executeCommand($args = [])
31+
{
32+
// we needs the "args" argument to be an array
33+
if (!is_array($args)) {
34+
$args = [ $args ];
35+
}
36+
$outputBuffer = [];
37+
exec('docker ' . implode(' ', $args), $outputBuffer);
38+
return $outputBuffer;
39+
}
40+
41+
/**
42+
* Returns list of available docker container
43+
*
44+
* @param bool $all
45+
* @return Container[]
46+
*/
47+
public function ps($all = false)
48+
{
49+
$fieldMap = [
50+
'id' => '{{.ID}}',
51+
'image' => '{{.Image}}',
52+
'command' => '{{.Command}}',
53+
'createdAt' => '{{.CreatedAt}}',
54+
'runningFor' => '{{.RunningFor}}',
55+
'ports' => '{{.Ports}}',
56+
'status' => '{{.Status}}',
57+
'size' => '{{.Size}}',
58+
'names' => '{{.Names}}',
59+
'labels' => '{{.Labels}}',
60+
'mounts' => '{{.Mounts}}',
61+
'networks' => '{{.Networks}}',
62+
];
63+
64+
// run docker ps to receive list of docker container.
65+
// we do this
66+
$cellGlue = '##---##';
67+
$format = "table " . implode($cellGlue, $fieldMap);
68+
$containerRaw = $this->executeCommand([
69+
'ps',
70+
($all ? ' --all' : ''),
71+
'--format "' . $format . '"',
72+
]);
73+
74+
// first line ouf output is just table header
75+
$containerList = [];
76+
if (count($containerRaw) > 1) {
77+
$containerFields = array_keys($fieldMap);
78+
for ($index = 1; $index < count($containerRaw); $index++) {
79+
$line = $containerRaw[$index];
80+
$parsedOutputLine = explode($cellGlue, $line);
81+
82+
// fill container object using analysed output line
83+
$container = new Container();
84+
foreach($parsedOutputLine as $key => $value) {
85+
$container->{$containerFields[$key]} = $value;
86+
}
87+
88+
// we return this generated container object later
89+
$containerList[] = $container;
90+
}
91+
}
92+
93+
return $containerList;
94+
}
95+
96+
/**
97+
* Checks if there is a container running under the given name
98+
*
99+
* @param $name
100+
* @return bool
101+
*/
102+
public function isContainerRunning($name)
103+
{
104+
foreach($this->ps() as $container) {
105+
if (in_array($name, $container->getNames())) {
106+
return true;
107+
}
108+
}
109+
return false;
110+
}
111+
112+
/**
113+
* Checks if there is a container existing under the given name
114+
*
115+
* @param $name
116+
* @return bool
117+
*/
118+
public function isContainerExisting($name)
119+
{
120+
foreach($this->ps(true) as $container) {
121+
if (in_array($name, $container->getNames())) {
122+
return true;
123+
}
124+
}
125+
return false;
126+
}
127+
128+
/**
129+
* Returns container object for given container name
130+
*
131+
* @param $name
132+
* @return null|Container
133+
*/
134+
public function getContainerInfo($name)
135+
{
136+
foreach($this->ps(true) as $container) {
137+
if (in_array($name, $container->getNames())) {
138+
return $container;
139+
}
140+
}
141+
142+
return null;
143+
}
144+
145+
/**
146+
* Starts container with given name. Return if container could be started or not.
147+
* Will return true if container is already running.
148+
*
149+
* @param $name
150+
* @return bool
151+
*/
152+
public function start($name)
153+
{
154+
if (!$this->isContainerRunning($name)) {
155+
$output = $this->executeCommand([
156+
'start',
157+
$name
158+
]);
159+
return $output[0] === $name;
160+
}
161+
162+
return true;
163+
}
164+
165+
/**
166+
* Stops container with given name. Returns if container could be stopped or not.
167+
* Will return true if container is not running.
168+
*
169+
* @param $name
170+
* @return bool
171+
*/
172+
public function stop($name)
173+
{
174+
if ($this->isContainerRunning($name)) {
175+
$output = $this->executeCommand([
176+
'stop',
177+
$name
178+
]);
179+
return $output[0] === $name;
180+
}
181+
182+
return true;
183+
}
184+
185+
/**
186+
* Kills existing docker container. Returns if container could be killed.
187+
* Will return true if docker is not running.
188+
*
189+
* @param $name
190+
* @return bool
191+
*/
192+
public function kill($name)
193+
{
194+
if ($this->isContainerRunning($name)) {
195+
$this->executeCommand([
196+
'kill',
197+
$name
198+
]);
199+
return $this->isContainerRunning($name);
200+
}
201+
202+
return true;
203+
}
204+
205+
/**
206+
* Removes container with given name. Returns if container could be removed.
207+
* Will return true if container is not existing.
208+
*
209+
* @param $name
210+
* @param bool $killIfRunning
211+
* @return bool
212+
*/
213+
public function remove($name, $killIfRunning = true)
214+
{
215+
if ($this->isContainerExisting($name)) {
216+
217+
// running container can not be removed
218+
if ($this->isContainerRunning($name) && !$killIfRunning) {
219+
return false;
220+
}
221+
$this->kill($name);
222+
$this->executeCommand([
223+
'rm',
224+
$name,
225+
]);
226+
return !$this->isContainerExisting($name);
227+
}
228+
229+
return true;
230+
}
231+
232+
/**
233+
* Runs container under given name with given arguments. Returns if container could be run.
234+
* Returns false if container is already running.
235+
*
236+
* @param $name
237+
* @param array $args
238+
* @return bool
239+
*/
240+
public function run($name, $args = [])
241+
{
242+
if (!$this->isContainerExisting($name)) {
243+
$this->executeCommand(array_merge(
244+
[
245+
'run',
246+
'--name '.$name,
247+
],
248+
$args
249+
));
250+
return $this->isContainerRunning($name);
251+
}
252+
253+
return false;
254+
}
255+
256+
/**
257+
* Checks if docker is installed correctly or not
258+
* (needs to be available over PATH)
259+
*
260+
* @return bool
261+
*/
262+
public function isInstalled()
263+
{
264+
return $this->outputContains(
265+
$this->executeCommand('--version'),
266+
'Docker version'
267+
);
268+
}
269+
}

0 commit comments

Comments
 (0)