Browse code

Say something useful during docker load

During a `docker load` there are times when nothing is printed
to the screen, leaving the user with no idea whether something happened.
When something *is* printed, often its just something like:
```
1834950e52ce: Loading layer 1.311 MB/1.311 MB
5f70bf18a086: Loading layer 1.024 kB/1.024 kB
```
which isn't necessarily the same as the image IDs.

This PR will either show:
- all of the tags for the image, or
- all of the image IDs if there are no tags

Sample output:
```
$ docker load -i busybox.tar
Loaded image: busybox:latest

$ docker load -i a.tar
Loaded image ID: sha256:47bcc53f74dc94b1920f0b34f6036096526296767650f223433fe65c35f149eb
```

IOW, show the human-friendly stuff first and then only if there are no tags
default back to the image IDs, so they have something to work with.

For me this this is needed because I have lots of images and after a
recent `docker load` I had no idea what image I just imported and had a
hard time figuring it out. This should fix that by telling the user
which images they just imported.

I'll add tests once there's agreement that we want this change.

Signed-off-by: Doug Davis <dug@us.ibm.com>

Doug Davis authored on 2016/05/26 10:25:12
Showing 2 changed files
... ...
@@ -62,6 +62,8 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
62 62
 	}
63 63
 
64 64
 	var parentLinks []parentLink
65
+	var imageIDsStr string
66
+	var imageRefCount int
65 67
 
66 68
 	for _, m := range manifest {
67 69
 		configPath, err := safePath(tmpDir, m.Config)
... ...
@@ -109,7 +111,9 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
109 109
 		if err != nil {
110 110
 			return err
111 111
 		}
112
+		imageIDsStr += fmt.Sprintf("Loaded image ID: %s\n", imgID)
112 113
 
114
+		imageRefCount = 0
113 115
 		for _, repoTag := range m.RepoTags {
114 116
 			named, err := reference.ParseNamed(repoTag)
115 117
 			if err != nil {
... ...
@@ -120,6 +124,8 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
120 120
 				return fmt.Errorf("invalid tag %q", repoTag)
121 121
 			}
122 122
 			l.setLoadedTag(ref, imgID, outStream)
123
+			outStream.Write([]byte(fmt.Sprintf("Loaded image: %s\n", ref)))
124
+			imageRefCount++
123 125
 		}
124 126
 
125 127
 		parentLinks = append(parentLinks, parentLink{imgID, m.Parent})
... ...
@@ -134,6 +140,10 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool)
134 134
 		}
135 135
 	}
136 136
 
137
+	if imageRefCount == 0 {
138
+		outStream.Write([]byte(imageIDsStr))
139
+	}
140
+
137 141
 	return nil
138 142
 }
139 143
 
... ...
@@ -350,3 +350,33 @@ func (s *DockerSuite) TestSaveLoadParents(c *check.C) {
350 350
 	inspectOut = inspectField(c, idFoo, "Parent")
351 351
 	c.Assert(inspectOut, checker.Equals, "")
352 352
 }
353
+
354
+func (s *DockerSuite) TestSaveLoadNoTag(c *check.C) {
355
+	testRequires(c, DaemonIsLinux)
356
+
357
+	name := "saveloadnotag"
358
+
359
+	_, err := buildImage(name, "FROM busybox\nENV foo=bar", true)
360
+	c.Assert(err, checker.IsNil, check.Commentf("%v", err))
361
+
362
+	id := inspectField(c, name, "Id")
363
+
364
+	// Test to make sure that save w/o name just shows imageID during load
365
+	out, _, err := runCommandPipelineWithOutput(
366
+		exec.Command(dockerBinary, "save", id),
367
+		exec.Command(dockerBinary, "load"))
368
+	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
369
+
370
+	// Should not show 'name' but should show the image ID during the load
371
+	c.Assert(out, checker.Not(checker.Contains), "Loaded image: ")
372
+	c.Assert(out, checker.Contains, "Loaded image ID:")
373
+	c.Assert(out, checker.Contains, id)
374
+
375
+	// Test to make sure that save by name shows that name during load
376
+	out, _, err = runCommandPipelineWithOutput(
377
+		exec.Command(dockerBinary, "save", name),
378
+		exec.Command(dockerBinary, "load"))
379
+	c.Assert(err, checker.IsNil, check.Commentf("failed to save and load repo: %s, %v", out, err))
380
+	c.Assert(out, checker.Contains, "Loaded image: "+name+":latest")
381
+	c.Assert(out, checker.Not(checker.Contains), "Loaded image ID:")
382
+}