Skip to content

Commit 75cf394

Browse files
committed
Add imagePushStream()
Also serves as a basis for imagePush()
1 parent 46a7784 commit 75cf394

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

src/Client.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,9 @@ public function imageHistory($image)
414414
/**
415415
* Push the image name on the registry
416416
*
417+
* Will resolve with an array of all progress events. These can also be
418+
* accessed via the Promise progress handler.
419+
*
417420
* @param string $image image ID
418421
* @param string|null $tag (optional) the tag to associate with the image on the registry
419422
* @param string|null $registry (optional) the registry to push to (e.g. `registry.acme.com:5000`)
@@ -422,9 +425,37 @@ public function imageHistory($image)
422425
* @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#push-an-image-on-the-registry
423426
*/
424427
public function imagePush($image, $tag = null, $registry = null, $registryAuth = null)
428+
{
429+
$stream = $this->imagePushStream($image, $tag, $registry, $registryAuth);
430+
431+
return $this->streamingParser->deferredStream($stream, 'progress');
432+
}
433+
434+
/**
435+
* Push the image name on the registry
436+
*
437+
* The resulting stream will emit the following events:
438+
* - progress: for *each* element in the update stream
439+
* - error: once if an error occurs, will close() stream then
440+
* - close: once the stream ends (either finished or after "error")
441+
*
442+
* Please note that the resulting stream does not emit any "data" events, so
443+
* you will not be able to pipe() its events into another `WritableStream`.
444+
*
445+
* @param string $image image ID
446+
* @param string|null $tag (optional) the tag to associate with the image on the registry
447+
* @param string|null $registry (optional) the registry to push to (e.g. `registry.acme.com:5000`)
448+
* @param array|null $registryAuth (optional) AuthConfig object (to send as X-Registry-Auth header)
449+
* @return ReadableStreamInterface stream of image push messages
450+
* @link https://docs.docker.com/reference/api/docker_remote_api_v1.15/#push-an-image-on-the-registry
451+
*/
452+
public function imagePushStream($image, $tag = null, $registry = null, $registryAuth = null)
425453
{
426454
$path = '/images' . ($registry === null ? '' : ('/' . $registry)) . '/%s/push?tag=%s';
427-
return $this->browser->post($this->url($path, $image, $tag), $this->authHeaders($registryAuth))->then(array($this->parser, 'expectJson'));
455+
456+
return $this->streamingParser->parseJsonStream(
457+
$this->browser->post($this->url($path, $image, $tag), $this->authHeaders($registryAuth))
458+
);
428459
}
429460

430461
/**

tests/ClientTest.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,17 +244,35 @@ public function testImageHistory()
244244
public function testImagePush()
245245
{
246246
$json = array();
247-
$this->expectRequestFlow('post', '/images/123/push?tag=', $this->createResponseJson($json), 'expectJson');
247+
$stream = $this->getMock('React\Stream\ReadableStreamInterface');
248+
249+
$this->expectRequest('post', '/images/123/push?tag=', $this->createResponseJsonStream($json));
250+
$this->streamingParser->expects($this->once())->method('parseJsonStream')->will($this->returnValue($stream));
251+
$this->streamingParser->expects($this->once())->method('deferredStream')->with($this->equalTo($stream), $this->equalTo('progress'))->will($this->returnPromise($json));
248252

249253
$this->expectPromiseResolveWith($json, $this->client->imagePush('123'));
250254
}
251255

256+
public function testImagePushStream()
257+
{
258+
$stream = $this->getMock('React\Stream\ReadableStreamInterface');
259+
260+
$this->expectRequest('post', '/images/123/push?tag=', $this->createResponseJsonStream(array()));
261+
$this->streamingParser->expects($this->once())->method('parseJsonStream')->will($this->returnValue($stream));
262+
263+
$this->assertSame($stream, $this->client->imagePushStream('123'));
264+
}
265+
252266
public function testImagePushCustomRegistry()
253267
{
254268
// TODO: verify headers
255269
$auth = array();
256270
$json = array();
257-
$this->expectRequestFlow('post', '/images/demo.acme.com:5000/123/push?tag=test', $this->createResponseJson($json), 'expectJson');
271+
$stream = $this->getMock('React\Stream\ReadableStreamInterface');
272+
273+
$this->expectRequest('post', '/images/demo.acme.com:5000/123/push?tag=test', $this->createResponseJsonStream($json));
274+
$this->streamingParser->expects($this->once())->method('parseJsonStream')->will($this->returnValue($stream));
275+
$this->streamingParser->expects($this->once())->method('deferredStream')->with($this->equalTo($stream), $this->equalTo('progress'))->will($this->returnPromise($json));
258276

259277
$this->expectPromiseResolveWith($json, $this->client->imagePush('123', 'test', 'demo.acme.com:5000', $auth));
260278
}

0 commit comments

Comments
 (0)