Completed
Push — master ( d3a073...5737c8 )
by Greg
02:21
created

src/Task/Docker/Run.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Robo\Task\Docker;
3
4
use Robo\Common\CommandReceiver;
5
6
/**
7
 * Performs `docker run` on a container.
8
 *
9
 * ```php
10
 * <?php
11
 * $this->taskDockerRun('mysql')->run();
12
 *
13
 * $result = $this->taskDockerRun('my_db_image')
14
 *      ->env('DB', 'database_name')
15
 *      ->volume('/path/to/data', '/data')
16
 *      ->detached()
17
 *      ->publish(3306)
18
 *      ->name('my_mysql')
19
 *      ->run();
20
 *
21
 * // retrieve container's cid:
22
 * $this->say("Running container ".$result->getCid());
23
 *
24
 * // execute script inside container
25
 * $result = $this->taskDockerRun('db')
26
 *      ->exec('prepare_test_data.sh')
27
 *      ->run();
28
 *
29
 * $this->taskDockerCommit($result)
30
 *      ->name('test_db')
31
 *      ->run();
32
 *
33
 * // link containers
34
 * $mysql = $this->taskDockerRun('mysql')
35
 *      ->name('wp_db') // important to set name for linked container
36
 *      ->env('MYSQL_ROOT_PASSWORD', '123456')
37
 *      ->run();
38
 *
39
 * $this->taskDockerRun('wordpress')
40
 *      ->link($mysql)
41
 *      ->publish(80, 8080)
42
 *      ->detached()
43
 *      ->run();
44
 *
45
 * ?>
46
 * ```
47
 *
48
 */
49
class Run extends Base
50
{
51
    use CommandReceiver;
52
53
    /**
54
     * @var string
55
     */
56
    protected $image = '';
57
58
    /**
59
     * @var string
60
     */
61
    protected $run = '';
62
63
    /**
64
     * @var string
65
     */
66
    protected $cidFile;
67
68
    /**
69
     * @var string
70
     */
71
    protected $name;
72
73
    /**
74
     * @var string
75
     */
76
    protected $dir;
77
78
    /**
79
     * @param string $image
80
     */
81
    public function __construct($image)
82
    {
83
        $this->image = $image;
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function getPrinted()
90
    {
91
        return $this->isPrinted;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function getCommand()
98
    {
99
        if ($this->isPrinted) {
100
            $this->option('-i');
101
        }
102
        if ($this->cidFile) {
103
            $this->option('cidfile', $this->cidFile);
104
        }
105
        return trim('docker run ' . $this->arguments . ' ' . $this->image . ' ' . $this->run);
106
    }
107
108
    /**
109
     * @return $this
110
     */
111
    public function detached()
112
    {
113
        $this->option('-d');
114
        return $this;
115
    }
116
117
    /**
118
     * {@inheritdoc)}
119
     */
120
    public function interactive($interactive = true)
121
    {
122
        if ($interactive) {
123
            $this->option('-i');
124
        }
125
        return parent::interactive($interactive);
126
    }
127
128
    /**
129
     * @param string|\Robo\Contract\CommandInterface $run
130
     *
131
     * @return $this
132
     */
133
    public function exec($run)
134
    {
135
        $this->run = $this->receiveCommand($run);
136
        return $this;
137
    }
138
139
    /**
140
     * @param string $from
141
     * @param null|string $to
142
     *
143
     * @return $this
144
     */
145
    public function volume($from, $to = null)
146
    {
147
        $volume = $to ? "$from:$to" : $from;
148
        $this->option('-v', $volume);
149
        return $this;
150
    }
151
152
    /**
153
     * Set environment variables.
154
     * n.b. $this->env($variable, $value) also available here,
155
     * inherited from ExecTrait.
156
     *
157
     * @param array $env
158
     * @return type
159
     */
160
    public function envVars(array $env)
161
    {
162
        foreach ($env as $variable => $value) {
163
            $this->setDockerEnv($variable, $value);
164
        }
165
        return $this;
166
    }
167
168
    /**
169
     * @param string $variable
170
     * @param null|string $value
171
     *
172
     * @return $this
173
     */
174
    protected function setDockerEnv($variable, $value = null)
175
    {
176
        $env = $value ? "$variable=$value" : $variable;
177
        return $this->option("-e", $env);
178
    }
179
180
    /**
181
     * @param null|int $port
182
     * @param null|int $portTo
183
     *
184
     * @return $this
185
     */
186
    public function publish($port = null, $portTo = null)
187
    {
188
        if (!$port) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $port of type null|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
189
            return $this->option('-P');
190
        }
191
        if ($portTo) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $portTo of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
192
            $port = "$port:$portTo";
193
        }
194
        return $this->option('-p', $port);
195
    }
196
197
    /**
198
     * @param string $dir
199
     *
200
     * @return $this
201
     */
202
    public function containerWorkdir($dir)
203
    {
204
        return $this->option('-w', $dir);
205
    }
206
207
    /**
208
     * @param string $user
209
     *
210
     * @return $this
211
     */
212
    public function user($user)
213
    {
214
        return $this->option('-u', $user);
215
    }
216
217
    /**
218
     * @return $this
219
     */
220
    public function privileged()
221
    {
222
        return $this->option('--privileged');
223
    }
224
225
    /**
226
     * @param string $name
227
     *
228
     * @return $this
229
     */
230
    public function name($name)
231
    {
232
        $this->name = $name;
233
        return $this->option('name', $name);
234
    }
235
236
    /**
237
     * @param string|\Robo\Task\Docker\Result $name
238
     * @param string $alias
239
     *
240
     * @return $this
241
     */
242
    public function link($name, $alias)
243
    {
244
        if ($name instanceof Result) {
245
            $name = $name->getContainerName();
246
        }
247
        $this->option('link', "$name:$alias");
248
        return $this;
249
    }
250
251
    /**
252
     * @param string $dir
253
     *
254
     * @return $this
255
     */
256
    public function tmpDir($dir)
257
    {
258
        $this->dir = $dir;
259
        return $this;
260
    }
261
262
    /**
263
     * @return string
264
     */
265
    public function getTmpDir()
266
    {
267
        return $this->dir ? $this->dir : sys_get_temp_dir();
268
    }
269
270
    /**
271
     * @return string
272
     */
273
    public function getUniqId()
274
    {
275
        return uniqid();
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281
    public function run()
282
    {
283
        $this->cidFile = $this->getTmpDir() . '/docker_' . $this->getUniqId() . '.cid';
284
        $result = parent::run();
285
        $result['cid'] = $this->getCid();
286
        return $result;
287
    }
288
289
    /**
290
     * @return null|string
291
     */
292
    protected function getCid()
293
    {
294
        if (!$this->cidFile || !file_exists($this->cidFile)) {
295
            return null;
296
        }
297
        $cid = trim(file_get_contents($this->cidFile));
298
        @unlink($this->cidFile);
299
        return $cid;
300
    }
301
}
302