Signed-off-by: Lei Jitang <leijitang@huawei.com>
Lei Jitang authored on 2016/02/04 11:31:47... | ... |
@@ -19,6 +19,7 @@ import ( |
19 | 19 |
func (cli *DockerCli) CmdLoad(args ...string) error { |
20 | 20 |
cmd := Cli.Subcmd("load", nil, Cli.DockerCommands["load"].Description, true) |
21 | 21 |
infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN") |
22 |
+ quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the load output") |
|
22 | 23 |
cmd.Require(flag.Exact, 0) |
23 | 24 |
cmd.ParseFlags(args, true) |
24 | 25 |
|
... | ... |
@@ -31,8 +32,10 @@ func (cli *DockerCli) CmdLoad(args ...string) error { |
31 | 31 |
defer file.Close() |
32 | 32 |
input = file |
33 | 33 |
} |
34 |
- |
|
35 |
- response, err := cli.client.ImageLoad(context.Background(), input, true) |
|
34 |
+ if !cli.isTerminalOut { |
|
35 |
+ *quiet = true |
|
36 |
+ } |
|
37 |
+ response, err := cli.client.ImageLoad(context.Background(), input, *quiet) |
|
36 | 38 |
if err != nil { |
37 | 39 |
return err |
38 | 40 |
} |
... | ... |
@@ -270,7 +270,12 @@ func (s *router) getImagesGet(ctx context.Context, w http.ResponseWriter, r *htt |
270 | 270 |
} |
271 | 271 |
|
272 | 272 |
func (s *router) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { |
273 |
- return s.daemon.LoadImage(r.Body, w) |
|
273 |
+ if err := httputils.ParseForm(r); err != nil { |
|
274 |
+ return err |
|
275 |
+ } |
|
276 |
+ quiet := httputils.BoolValueOrDefault(r, "quiet", true) |
|
277 |
+ w.Header().Set("Content-Type", "application/json") |
|
278 |
+ return s.daemon.LoadImage(r.Body, w, quiet) |
|
274 | 279 |
} |
275 | 280 |
|
276 | 281 |
func (s *router) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { |
... | ... |
@@ -1187,9 +1187,9 @@ func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) { |
1187 | 1187 |
// LoadImage uploads a set of images into the repository. This is the |
1188 | 1188 |
// complement of ImageExport. The input stream is an uncompressed tar |
1189 | 1189 |
// ball containing images and metadata. |
1190 |
-func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer) error { |
|
1190 |
+func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error { |
|
1191 | 1191 |
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore) |
1192 |
- return imageExporter.Load(inTar, outStream) |
|
1192 |
+ return imageExporter.Load(inTar, outStream, quiet) |
|
1193 | 1193 |
} |
1194 | 1194 |
|
1195 | 1195 |
// ImageHistory returns a slice of ImageHistory structures for the specified image |
... | ... |
@@ -116,7 +116,7 @@ type History struct { |
116 | 116 |
|
117 | 117 |
// Exporter provides interface for exporting and importing images |
118 | 118 |
type Exporter interface { |
119 |
- Load(io.ReadCloser, io.Writer) error |
|
119 |
+ Load(io.ReadCloser, io.Writer, bool) error |
|
120 | 120 |
// TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error |
121 | 121 |
Save([]string, io.Writer) error |
122 | 122 |
} |
... | ... |
@@ -14,11 +14,24 @@ import ( |
14 | 14 |
"github.com/docker/docker/layer" |
15 | 15 |
"github.com/docker/docker/pkg/archive" |
16 | 16 |
"github.com/docker/docker/pkg/chrootarchive" |
17 |
+ "github.com/docker/docker/pkg/progress" |
|
18 |
+ "github.com/docker/docker/pkg/streamformatter" |
|
19 |
+ "github.com/docker/docker/pkg/stringid" |
|
17 | 20 |
"github.com/docker/docker/pkg/symlink" |
18 | 21 |
"github.com/docker/docker/reference" |
19 | 22 |
) |
20 | 23 |
|
21 |
-func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error { |
|
24 |
+func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) error { |
|
25 |
+ var ( |
|
26 |
+ sf = streamformatter.NewJSONStreamFormatter() |
|
27 |
+ progressOutput progress.Output |
|
28 |
+ ) |
|
29 |
+ if !quiet { |
|
30 |
+ progressOutput = sf.NewProgressOutput(outStream, false) |
|
31 |
+ } else { |
|
32 |
+ progressOutput = nil |
|
33 |
+ } |
|
34 |
+ |
|
22 | 35 |
tmpDir, err := ioutil.TempDir("", "docker-import-") |
23 | 36 |
if err != nil { |
24 | 37 |
return err |
... | ... |
@@ -36,7 +49,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error { |
36 | 36 |
manifestFile, err := os.Open(manifestPath) |
37 | 37 |
if err != nil { |
38 | 38 |
if os.IsNotExist(err) { |
39 |
- return l.legacyLoad(tmpDir, outStream) |
|
39 |
+ return l.legacyLoad(tmpDir, outStream, progressOutput) |
|
40 | 40 |
} |
41 | 41 |
return manifestFile.Close() |
42 | 42 |
} |
... | ... |
@@ -77,7 +90,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error { |
77 | 77 |
r.Append(diffID) |
78 | 78 |
newLayer, err := l.ls.Get(r.ChainID()) |
79 | 79 |
if err != nil { |
80 |
- newLayer, err = l.loadLayer(layerPath, rootFS) |
|
80 |
+ newLayer, err = l.loadLayer(layerPath, rootFS, diffID.String(), progressOutput) |
|
81 | 81 |
if err != nil { |
82 | 82 |
return err |
83 | 83 |
} |
... | ... |
@@ -111,7 +124,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error { |
111 | 111 |
return nil |
112 | 112 |
} |
113 | 113 |
|
114 |
-func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS) (layer.Layer, error) { |
|
114 |
+func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string, progressOutput progress.Output) (layer.Layer, error) { |
|
115 | 115 |
rawTar, err := os.Open(filename) |
116 | 116 |
if err != nil { |
117 | 117 |
logrus.Debugf("Error reading embedded tar: %v", err) |
... | ... |
@@ -125,6 +138,17 @@ func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS) (layer.Lay |
125 | 125 |
} |
126 | 126 |
defer inflatedLayerData.Close() |
127 | 127 |
|
128 |
+ if progressOutput != nil { |
|
129 |
+ fileInfo, err := os.Stat(filename) |
|
130 |
+ if err != nil { |
|
131 |
+ logrus.Debugf("Error statting file: %v", err) |
|
132 |
+ return nil, err |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ progressReader := progress.NewProgressReader(inflatedLayerData, progressOutput, fileInfo.Size(), stringid.TruncateID(id), "Loading layer") |
|
136 |
+ |
|
137 |
+ return l.ls.Register(progressReader, rootFS.ChainID()) |
|
138 |
+ } |
|
128 | 139 |
return l.ls.Register(inflatedLayerData, rootFS.ChainID()) |
129 | 140 |
} |
130 | 141 |
|
... | ... |
@@ -139,7 +163,7 @@ func (l *tarexporter) setLoadedTag(ref reference.NamedTagged, imgID image.ID, ou |
139 | 139 |
return nil |
140 | 140 |
} |
141 | 141 |
|
142 |
-func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error { |
|
142 |
+func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer, progressOutput progress.Output) error { |
|
143 | 143 |
legacyLoadedMap := make(map[string]image.ID) |
144 | 144 |
|
145 | 145 |
dirs, err := ioutil.ReadDir(tmpDir) |
... | ... |
@@ -150,7 +174,7 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error { |
150 | 150 |
// every dir represents an image |
151 | 151 |
for _, d := range dirs { |
152 | 152 |
if d.IsDir() { |
153 |
- if err := l.legacyLoadImage(d.Name(), tmpDir, legacyLoadedMap); err != nil { |
|
153 |
+ if err := l.legacyLoadImage(d.Name(), tmpDir, legacyLoadedMap, progressOutput); err != nil { |
|
154 | 154 |
return err |
155 | 155 |
} |
156 | 156 |
} |
... | ... |
@@ -196,7 +220,7 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error { |
196 | 196 |
return nil |
197 | 197 |
} |
198 | 198 |
|
199 |
-func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[string]image.ID) error { |
|
199 |
+func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[string]image.ID, progressOutput progress.Output) error { |
|
200 | 200 |
if _, loaded := loadedMap[oldID]; loaded { |
201 | 201 |
return nil |
202 | 202 |
} |
... | ... |
@@ -220,7 +244,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str |
220 | 220 |
for { |
221 | 221 |
var loaded bool |
222 | 222 |
if parentID, loaded = loadedMap[img.Parent]; !loaded { |
223 |
- if err := l.legacyLoadImage(img.Parent, sourceDir, loadedMap); err != nil { |
|
223 |
+ if err := l.legacyLoadImage(img.Parent, sourceDir, loadedMap, progressOutput); err != nil { |
|
224 | 224 |
return err |
225 | 225 |
} |
226 | 226 |
} else { |
... | ... |
@@ -247,7 +271,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str |
247 | 247 |
if err != nil { |
248 | 248 |
return err |
249 | 249 |
} |
250 |
- newLayer, err := l.loadLayer(layerPath, *rootFS) |
|
250 |
+ newLayer, err := l.loadLayer(layerPath, *rootFS, oldID, progressOutput) |
|
251 | 251 |
if err != nil { |
252 | 252 |
return err |
253 | 253 |
} |