diff --git a/cluster/engine.go b/cluster/engine.go index 1bfcc701fd..46ae22011e 100644 --- a/cluster/engine.go +++ b/cluster/engine.go @@ -1017,12 +1017,28 @@ func (e *Engine) Pull(image string, authConfig *types.AuthConfig) error { // Load an image on the engine func (e *Engine) Load(reader io.Reader) error { - err := e.client.LoadImage(reader) + loadResponse, err := e.apiClient.ImageLoad(context.TODO(), reader, false) e.CheckConnectionErr(err) if err != nil { return err } + // wait until the image load is finished + dec := json.NewDecoder(loadResponse.Body) + m := map[string]interface{}{} + for { + if err := dec.Decode(&m); err != nil { + if err == io.EOF { + break + } + return err + } + } + // if the final stream object contained an error, return it + if errMsg, ok := m["error"]; ok { + return fmt.Errorf("%v", errMsg) + } + // force fresh images e.RefreshImages() @@ -1031,7 +1047,13 @@ func (e *Engine) Load(reader io.Reader) error { // Import image func (e *Engine) Import(source string, repository string, tag string, imageReader io.Reader) error { - _, err := e.client.ImportImage(source, repository, tag, imageReader) + opts := types.ImageImportOptions{ + SourceName: source, + RepositoryName: repository, + Tag: tag, + Source: imageReader, + } + _, err := e.apiClient.ImageImport(context.TODO(), opts) e.CheckConnectionErr(err) if err != nil { return err @@ -1249,7 +1271,13 @@ func (e *Engine) BuildImage(buildImage *types.ImageBuildOptions) (io.ReadCloser, // TagImage tags an image func (e *Engine) TagImage(IDOrName string, repo string, tag string, force bool) error { // send tag request to docker engine - err := e.client.TagImage(IDOrName, repo, tag, force) + opts := types.ImageTagOptions{ + ImageID: IDOrName, + RepositoryName: repo, + Tag: tag, + Force: force, + } + err := e.apiClient.ImageTag(context.TODO(), opts) e.CheckConnectionErr(err) if err != nil { return err diff --git a/cluster/swarm/cluster_test.go b/cluster/swarm/cluster_test.go index a82c8f55be..0c5acd506c 100644 --- a/cluster/swarm/cluster_test.go +++ b/cluster/swarm/cluster_test.go @@ -155,7 +155,7 @@ func TestImportImage(t *testing.T) { // import success readCloser := nopCloser{bytes.NewBufferString("ok")} - client.On("ImportImage", mock.Anything, mock.Anything, mock.Anything, mock.AnythingOfType("*io.PipeReader")).Return(readCloser, nil).Once() + apiClient.On("ImageImport", mock.Anything, mock.AnythingOfType("types.ImageImportOptions")).Return(readCloser, nil).Once() callback := func(what, status string, err error) { // import success @@ -166,7 +166,7 @@ func TestImportImage(t *testing.T) { // import error readCloser = nopCloser{bytes.NewBufferString("error")} err := fmt.Errorf("Import error") - client.On("ImportImage", mock.Anything, mock.Anything, mock.Anything, mock.AnythingOfType("*io.PipeReader")).Return(readCloser, err).Once() + apiClient.On("ImageImport", mock.Anything, mock.AnythingOfType("types.ImageImportOptions")).Return(readCloser, err).Once() callback = func(what, status string, err error) { // import error @@ -207,7 +207,8 @@ func TestLoadImage(t *testing.T) { c.engines[engine.ID] = engine // load success - client.On("LoadImage", mock.AnythingOfType("*io.PipeReader")).Return(nil).Once() + readCloser := nopCloser{bytes.NewBufferString("")} + apiClient.On("ImageLoad", mock.Anything, mock.AnythingOfType("*io.PipeReader"), false).Return(types.ImageLoadResponse{Body: readCloser}, nil).Once() callback := func(what, status string, err error) { //if load OK, err will be nil assert.Nil(t, err) @@ -216,7 +217,7 @@ func TestLoadImage(t *testing.T) { // load error err := fmt.Errorf("Load error") - client.On("LoadImage", mock.AnythingOfType("*io.PipeReader")).Return(err).Once() + apiClient.On("ImageLoad", mock.Anything, mock.AnythingOfType("*io.PipeReader"), false).Return(types.ImageLoadResponse{}, err).Once() callback = func(what, status string, err error) { // load error, err is not nil assert.NotNil(t, err) @@ -263,7 +264,7 @@ func TestTagImage(t *testing.T) { c.engines[engine.ID] = engine // tag image - client.On("TagImage", mock.Anything, mock.Anything, mock.Anything, false).Return(nil).Once() + apiClient.On("ImageTag", mock.Anything, mock.AnythingOfType("types.ImageTagOptions")).Return(nil).Once() assert.Nil(t, c.TagImage("busybox", "test_busybox", "latest", false)) assert.NotNil(t, c.TagImage("busybox_not_exists", "test_busybox", "latest", false)) } diff --git a/test/integration/api/load.bats b/test/integration/api/load.bats index c7f3ed8fae..41d725e4db 100644 --- a/test/integration/api/load.bats +++ b/test/integration/api/load.bats @@ -23,11 +23,11 @@ function teardown() { docker_swarm load -i $IMAGE_FILE - # and now swarm should have cought the image just loaded. + # and now swarm should have caught the image just loaded. run docker_swarm images -q [ "$status" -eq 0 ] [ "${#lines[@]}" -ge 1 ] - + # check node0 run docker -H ${HOSTS[0]} images [ "${#lines[@]}" -eq 2 ]