Browse code

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 authored on 2016/10/31 21:12:10
Showing 2 changed files
... ...
@@ -1,6 +1,7 @@
1 1
 package image
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"io"
5 6
 	"os"
6 7
 
... ...
@@ -49,6 +50,13 @@ func runLoad(dockerCli *command.DockerCli, opts loadOptions) error {
49 49
 		defer file.Close()
50 50
 		input = file
51 51
 	}
52
+
53
+	// To avoid getting stuck, verify that a tar file is given either in
54
+	// the input flag or through stdin and if not display an error message and exit.
55
+	if opts.input == "" && dockerCli.In().IsTerminal() {
56
+		return fmt.Errorf("requested load from stdin, but stdin is empty")
57
+	}
58
+
52 59
 	if !dockerCli.Out().IsTerminal() {
53 60
 		opts.quiet = true
54 61
 	}
... ...
@@ -3,11 +3,13 @@
3 3
 package main
4 4
 
5 5
 import (
6
+	"context"
6 7
 	"fmt"
7 8
 	"io/ioutil"
8 9
 	"os"
9 10
 	"os/exec"
10 11
 	"strings"
12
+	"time"
11 13
 
12 14
 	"github.com/docker/docker/pkg/integration/checker"
13 15
 	"github.com/go-check/check"
... ...
@@ -86,3 +88,22 @@ func (s *DockerSuite) TestSaveAndLoadWithProgressBar(c *check.C) {
86 86
 	expected := fmt.Sprintf("The image %s:latest already exists, renaming the old one with ID", name)
87 87
 	c.Assert(out, checker.Contains, expected)
88 88
 }
89
+
90
+// fail because load didn't receive data from stdin
91
+func (s *DockerSuite) TestLoadNoStdinFail(c *check.C) {
92
+	pty, tty, err := pty.Open()
93
+	c.Assert(err, check.IsNil)
94
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
95
+	defer cancel()
96
+	cmd := exec.CommandContext(ctx, dockerBinary, "load")
97
+	cmd.Stdin = tty
98
+	cmd.Stdout = tty
99
+	cmd.Stderr = tty
100
+	c.Assert(cmd.Run(), check.NotNil) // docker-load should fail
101
+
102
+	buf := make([]byte, 1024)
103
+
104
+	n, err := pty.Read(buf)
105
+	c.Assert(err, check.IsNil) //could not read tty output
106
+	c.Assert(string(buf[:n]), checker.Contains, "requested load from stdin, but stdin is empty")
107
+}