Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions examples/exec.php → examples/exec-inspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,32 @@

use React\EventLoop\Factory as LoopFactory;
use Clue\React\Docker\Factory;
use Clue\React\Docker\ExecHelper;
use React\Stream\Stream;
use Clue\React\Buzz\Message\ResponseException;

$container = isset($argv[1]) ? $argv[1] : 'asd';
$container = 'asd';
//$cmd = array('echo', 'hello world');
//$cmd = array('sleep', '2');
$cmd = array('sh', '-c', 'echo -n hello && sleep 1 && echo world && sleep 1 && env');
//$cmd = array('cat', 'invalid-path');

if (isset($argv[1])) {
$container = $argv[1];
$cmd = array_slice($argv, 2);
}

$loop = LoopFactory::create();

$factory = new Factory($loop);
$client = $factory->createClient();

$client->execCreate($container, array('Cmd' => array('sleep', '2'), 'AttachStdout' => true))->then(function ($info) use ($client) {
$client->execCreate($container, array('Cmd' => $cmd, 'AttachStdout' => true, 'AttachStderr' => true, 'Tty' => true))->then(function ($info) use ($client) {
echo 'Created with info: ' . json_encode($info) . PHP_EOL;

return $client->execInspect($info['Id']);
})->then(function ($info) use ($client) {
echo 'Inspected after creation: ' . json_encode($info, JSON_PRETTY_PRINT) . PHP_EOL;

return $client->execStart($info['ID'], array())->then(function ($out) use ($client, $info) {
return $client->execStart($info['ID'], array('Tty' => true))->then(function ($out) use ($client, $info) {
echo 'Starting returned: ';
var_dump($out);

Expand Down
11 changes: 8 additions & 3 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -903,15 +903,20 @@ public function execCreate($container, $config)
/**
* Starts a previously set up exec instance id.
*
* This resolves with a string of the command output, i.e. STDOUT and STDERR
* as set up in the `execCreate()` call.
*
* Keep in mind that this means the whole string has to be kept in memory.
*
* If detach is true, this API returns after starting the exec command.
* Otherwise, this API sets up an interactive session with the exec command.
*
* @param string $exec exec ID
* @param array $config (see link)
* @return PromiseInterface Promise<array> stream of message objects
* @return PromiseInterface Promise<string> buffered exec data
* @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#exec-start
*/
public function execStart($exec, $config)
public function execStart($exec, $config = array())
{
return $this->postJson(
$this->uri->expand(
Expand All @@ -921,7 +926,7 @@ public function execStart($exec, $config)
)
),
$config
)->then(array($this->parser, 'expectJson'));
)->then(array($this->parser, 'expectPlain'));
}

/**
Expand Down
6 changes: 3 additions & 3 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,11 @@ public function testExecCreate()

public function testExecStart()
{
$json = array();
$data = 'hello world';
$config = array();
$this->expectRequestFlow('post', '/exec/123/start', $this->createResponseJson($json), 'expectJson');
$this->expectRequestFlow('post', '/exec/123/start', $this->createResponse($data), 'expectPlain');

$this->expectPromiseResolveWith($json, $this->client->execStart(123, $config));
$this->expectPromiseResolveWith($data, $this->client->execStart(123, $config));
}

public function testExecResize()
Expand Down
97 changes: 97 additions & 0 deletions tests/FunctionalClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,103 @@ public function testCreateStartAndRemoveContainer()
$this->assertEquals('destroy', $ret[3]['status']);
}

public function testStartRunning()
{
$config = array(
'Image' => 'busybox',
'Tty' => true,
'Cmd' => array('sleep', '10')
);

$promise = $this->client->containerCreate($config);
$container = Block\await($promise, $this->loop);

$this->assertNotNull($container['Id']);
$this->assertNull($container['Warnings']);

$start = microtime(true);

$promise = $this->client->containerStart($container['Id']);
$ret = Block\await($promise, $this->loop);

$this->assertEquals('', $ret);

return $container['Id'];
}

/**
* @depends testStartRunning
* @param string $container
* @return string
*/
public function testExecCreateWhileRunning($container)
{
$promise = $this->client->execCreate($container, array(
'Cmd' => array('echo', '-n', 'hello', 'world'),
'AttachStdout' => true,
'AttachStderr' => true,
'Tty' => true
));
$exec = Block\await($promise, $this->loop);

$this->assertTrue(is_array($exec));
$this->assertTrue(is_string($exec['Id']));

return $exec['Id'];
}

/**
* @depends testExecCreateWhileRunning
* @param string $exec
*/
public function testExecInspectBeforeRunning($exec)
{
$promise = $this->client->execInspect($exec);
$info = Block\await($promise, $this->loop);

$this->assertTrue(is_array($info));
$this->assertFalse($info['Running']);
$this->assertEquals(null, $info['ExitCode']);
}

/**
* @depends testExecCreateWhileRunning
* @param string $exec
*/
public function testExecStartWhileRunning($exec)
{
$promise = $this->client->execStart($exec, array('Tty' => true));
$output = Block\await($promise, $this->loop);

$this->assertEquals('hello world', $output);
}

/**
* @depends testExecCreateWhileRunning
* @param string $exec
*/
public function testExecInspectAfterRunning($exec)
{
$promise = $this->client->execInspect($exec);
$info = Block\await($promise, $this->loop);

$this->assertTrue(is_array($info));
$this->assertFalse($info['Running']);
$this->assertEquals(0, $info['ExitCode']);
}

/**
* @depends testStartRunning
* @param string $container
*/
public function testRemoveRunning($container)
{
$promise = $this->client->containerRemove($container, true, true);
$ret = Block\await($promise, $this->loop);

$this->assertEquals('', $ret);
}

/**
* @expectedException RuntimeException
*/
Expand Down