Ver código fonte

Validate docker-load receives a tar file

To load an image from a tar file, you can specify
the tar file in the -i/--input option:
docker load -i image_1.tar

or using stdin:

docker load < image_1.tar
cat image_1.tat | docker load

If the image file isn't given the `docker load`
command gets stuck.

To avoid that, the load makes sure the CLI input is
not a terminal or the `--input` option was set.
If not then an error message is shown.

Signed-off-by: Boaz Shuster <ripcurld.github@gmail.com>
Boaz Shuster 8 anos atrás
pai
commit
4426189b35

+ 8 - 0
cli/command/image/load.go

@@ -1,6 +1,7 @@
 package image
 package image
 
 
 import (
 import (
+	"fmt"
 	"io"
 	"io"
 	"os"
 	"os"
 
 
@@ -49,6 +50,13 @@ func runLoad(dockerCli *command.DockerCli, opts loadOptions) error {
 		defer file.Close()
 		defer file.Close()
 		input = file
 		input = file
 	}
 	}
+
+	// To avoid getting stuck, verify that a tar file is given either in
+	// the input flag or through stdin and if not display an error message and exit.
+	if opts.input == "" && dockerCli.In().IsTerminal() {
+		return fmt.Errorf("requested load from stdin, but stdin is empty")
+	}
+
 	if !dockerCli.Out().IsTerminal() {
 	if !dockerCli.Out().IsTerminal() {
 		opts.quiet = true
 		opts.quiet = true
 	}
 	}

+ 21 - 0
integration-cli/docker_cli_save_load_unix_test.go

@@ -3,11 +3,13 @@
 package main
 package main
 
 
 import (
 import (
+	"context"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"strings"
 	"strings"
+	"time"
 
 
 	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/docker/docker/pkg/integration/checker"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
@@ -86,3 +88,22 @@ func (s *DockerSuite) TestSaveAndLoadWithProgressBar(c *check.C) {
 	expected := fmt.Sprintf("The image %s:latest already exists, renaming the old one with ID", name)
 	expected := fmt.Sprintf("The image %s:latest already exists, renaming the old one with ID", name)
 	c.Assert(out, checker.Contains, expected)
 	c.Assert(out, checker.Contains, expected)
 }
 }
+
+// fail because load didn't receive data from stdin
+func (s *DockerSuite) TestLoadNoStdinFail(c *check.C) {
+	pty, tty, err := pty.Open()
+	c.Assert(err, check.IsNil)
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+	cmd := exec.CommandContext(ctx, dockerBinary, "load")
+	cmd.Stdin = tty
+	cmd.Stdout = tty
+	cmd.Stderr = tty
+	c.Assert(cmd.Run(), check.NotNil) // docker-load should fail
+
+	buf := make([]byte, 1024)
+
+	n, err := pty.Read(buf)
+	c.Assert(err, check.IsNil) //could not read tty output
+	c.Assert(string(buf[:n]), checker.Contains, "requested load from stdin, but stdin is empty")
+}