From 260a835cb4a6f904d7b0547df6a9bc80f8ad308c Mon Sep 17 00:00:00 2001
From: Lei Jitang <leijitang@huawei.com>
Date: Tue, 12 Apr 2016 22:45:42 -0400
Subject: [PATCH] Fix docker load progressbar, fixes #21957

Signed-off-by: Lei Jitang <leijitang@huawei.com>
(cherry picked from commit 96d7db665b06cc0bbede22d818c69dc5f6921f66)
---
 api/client/load.go                            |  2 +-
 api/server/router/image/image_routes.go       | 12 ++++++++++-
 image/tarexport/load.go                       |  1 +
 .../docker_cli_save_load_unix_test.go         | 20 +++++++++++++++++++
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/api/client/load.go b/api/client/load.go
index 059d151704..820fdc0ef6 100644
--- a/api/client/load.go
+++ b/api/client/load.go
@@ -41,7 +41,7 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
 	}
 	defer response.Body.Close()
 
-	if response.JSON {
+	if response.Body != nil && response.JSON {
 		return jsonmessage.DisplayJSONMessagesStream(response.Body, cli.out, cli.outFd, cli.isTerminalOut, nil)
 	}
 
diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go
index bd51abf3ba..0ead075df8 100644
--- a/api/server/router/image/image_routes.go
+++ b/api/server/router/image/image_routes.go
@@ -269,7 +269,17 @@ func (s *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter,
 		return err
 	}
 	quiet := httputils.BoolValueOrDefault(r, "quiet", true)
-	w.Header().Set("Content-Type", "application/json")
+
+	if !quiet {
+		w.Header().Set("Content-Type", "application/json")
+
+		output := ioutils.NewWriteFlusher(w)
+		defer output.Close()
+		if err := s.backend.LoadImage(r.Body, output, quiet); err != nil {
+			output.Write(streamformatter.NewJSONStreamFormatter().FormatError(err))
+		}
+		return nil
+	}
 	return s.backend.LoadImage(r.Body, w, quiet)
 }
 
diff --git a/image/tarexport/load.go b/image/tarexport/load.go
index 6a90385faa..42eaa40b2e 100644
--- a/image/tarexport/load.go
+++ b/image/tarexport/load.go
@@ -29,6 +29,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
 	)
 	if !quiet {
 		progressOutput = sf.NewProgressOutput(outStream, false)
+		outStream = &streamformatter.StdoutFormatter{Writer: outStream, StreamFormatter: streamformatter.NewJSONStreamFormatter()}
 	}
 
 	tmpDir, err := ioutil.TempDir("", "docker-import-")
diff --git a/integration-cli/docker_cli_save_load_unix_test.go b/integration-cli/docker_cli_save_load_unix_test.go
index 86dea914f0..d9dd95f126 100644
--- a/integration-cli/docker_cli_save_load_unix_test.go
+++ b/integration-cli/docker_cli_save_load_unix_test.go
@@ -3,6 +3,7 @@
 package main
 
 import (
+	"fmt"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -65,3 +66,22 @@ func (s *DockerSuite) TestSaveAndLoadRepoStdout(c *check.C) {
 	c.Assert(err, check.IsNil) //could not read tty output
 	c.Assert(string(buf[:n]), checker.Contains, "Cowardly refusing", check.Commentf("help output is not being yielded", out))
 }
+
+func (s *DockerSuite) TestSaveAndLoadWithProgressBar(c *check.C) {
+	name := "test-load"
+	_, err := buildImage(name, `
+	FROM busybox
+	RUN touch aa
+	`, true)
+	c.Assert(err, check.IsNil)
+
+	tmptar := name + ".tar"
+	dockerCmd(c, "save", "-o", tmptar, name)
+	defer os.Remove(tmptar)
+
+	dockerCmd(c, "rmi", name)
+	dockerCmd(c, "tag", "busybox", name)
+	out, _ := dockerCmd(c, "load", "-i", tmptar)
+	expected := fmt.Sprintf("The image %s:latest already exists, renaming the old one with ID", name)
+	c.Assert(out, checker.Contains, expected)
+}