Completed
Push — master ( 8b8afe...5f2bbe )
by Greg
02:21
created

src/Task/Docker/Run.php (1 issue)

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) {
189
            return $this->option('-P');
190
        }
191
        if ($portTo) {
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);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
299
        return $cid;
300
    }
301
}
302