Add progress bar to docker load
Signed-off-by: Lei Jitang <leijitang@huawei.com>
This commit is contained in:
parent
98aa1d24a3
commit
fae09e2569
5 changed files with 47 additions and 15 deletions
|
@ -19,6 +19,7 @@ import (
|
|||
func (cli *DockerCli) CmdLoad(args ...string) error {
|
||||
cmd := Cli.Subcmd("load", nil, Cli.DockerCommands["load"].Description, true)
|
||||
infile := cmd.String([]string{"i", "-input"}, "", "Read from a tar archive file, instead of STDIN")
|
||||
quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Suppress the load output")
|
||||
cmd.Require(flag.Exact, 0)
|
||||
cmd.ParseFlags(args, true)
|
||||
|
||||
|
@ -31,8 +32,10 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
|
|||
defer file.Close()
|
||||
input = file
|
||||
}
|
||||
|
||||
response, err := cli.client.ImageLoad(context.Background(), input, true)
|
||||
if !cli.isTerminalOut {
|
||||
*quiet = true
|
||||
}
|
||||
response, err := cli.client.ImageLoad(context.Background(), input, *quiet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -270,7 +270,12 @@ func (s *router) getImagesGet(ctx context.Context, w http.ResponseWriter, r *htt
|
|||
}
|
||||
|
||||
func (s *router) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
return s.daemon.LoadImage(r.Body, w)
|
||||
if err := httputils.ParseForm(r); err != nil {
|
||||
return err
|
||||
}
|
||||
quiet := httputils.BoolValueOrDefault(r, "quiet", true)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
return s.daemon.LoadImage(r.Body, w, quiet)
|
||||
}
|
||||
|
||||
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) {
|
|||
// LoadImage uploads a set of images into the repository. This is the
|
||||
// complement of ImageExport. The input stream is an uncompressed tar
|
||||
// ball containing images and metadata.
|
||||
func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer) error {
|
||||
func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
|
||||
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore)
|
||||
return imageExporter.Load(inTar, outStream)
|
||||
return imageExporter.Load(inTar, outStream, quiet)
|
||||
}
|
||||
|
||||
// ImageHistory returns a slice of ImageHistory structures for the specified image
|
||||
|
|
|
@ -116,7 +116,7 @@ type History struct {
|
|||
|
||||
// Exporter provides interface for exporting and importing images
|
||||
type Exporter interface {
|
||||
Load(io.ReadCloser, io.Writer) error
|
||||
Load(io.ReadCloser, io.Writer, bool) error
|
||||
// TODO: Load(net.Context, io.ReadCloser, <- chan StatusMessage) error
|
||||
Save([]string, io.Writer) error
|
||||
}
|
||||
|
|
|
@ -14,11 +14,24 @@ import (
|
|||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/progress"
|
||||
"github.com/docker/docker/pkg/streamformatter"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/docker/docker/reference"
|
||||
)
|
||||
|
||||
func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
||||
func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
|
||||
var (
|
||||
sf = streamformatter.NewJSONStreamFormatter()
|
||||
progressOutput progress.Output
|
||||
)
|
||||
if !quiet {
|
||||
progressOutput = sf.NewProgressOutput(outStream, false)
|
||||
} else {
|
||||
progressOutput = nil
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "docker-import-")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -36,7 +49,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
|||
manifestFile, err := os.Open(manifestPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return l.legacyLoad(tmpDir, outStream)
|
||||
return l.legacyLoad(tmpDir, outStream, progressOutput)
|
||||
}
|
||||
return manifestFile.Close()
|
||||
}
|
||||
|
@ -77,7 +90,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
|||
r.Append(diffID)
|
||||
newLayer, err := l.ls.Get(r.ChainID())
|
||||
if err != nil {
|
||||
newLayer, err = l.loadLayer(layerPath, rootFS)
|
||||
newLayer, err = l.loadLayer(layerPath, rootFS, diffID.String(), progressOutput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -111,7 +124,7 @@ func (l *tarexporter) Load(inTar io.ReadCloser, outStream io.Writer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS) (layer.Layer, error) {
|
||||
func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS, id string, progressOutput progress.Output) (layer.Layer, error) {
|
||||
rawTar, err := os.Open(filename)
|
||||
if err != nil {
|
||||
logrus.Debugf("Error reading embedded tar: %v", err)
|
||||
|
@ -125,6 +138,17 @@ func (l *tarexporter) loadLayer(filename string, rootFS image.RootFS) (layer.Lay
|
|||
}
|
||||
defer inflatedLayerData.Close()
|
||||
|
||||
if progressOutput != nil {
|
||||
fileInfo, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
logrus.Debugf("Error statting file: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
progressReader := progress.NewProgressReader(inflatedLayerData, progressOutput, fileInfo.Size(), stringid.TruncateID(id), "Loading layer")
|
||||
|
||||
return l.ls.Register(progressReader, rootFS.ChainID())
|
||||
}
|
||||
return l.ls.Register(inflatedLayerData, rootFS.ChainID())
|
||||
}
|
||||
|
||||
|
@ -139,7 +163,7 @@ func (l *tarexporter) setLoadedTag(ref reference.NamedTagged, imgID image.ID, ou
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error {
|
||||
func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer, progressOutput progress.Output) error {
|
||||
legacyLoadedMap := make(map[string]image.ID)
|
||||
|
||||
dirs, err := ioutil.ReadDir(tmpDir)
|
||||
|
@ -150,7 +174,7 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error {
|
|||
// every dir represents an image
|
||||
for _, d := range dirs {
|
||||
if d.IsDir() {
|
||||
if err := l.legacyLoadImage(d.Name(), tmpDir, legacyLoadedMap); err != nil {
|
||||
if err := l.legacyLoadImage(d.Name(), tmpDir, legacyLoadedMap, progressOutput); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +220,7 @@ func (l *tarexporter) legacyLoad(tmpDir string, outStream io.Writer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[string]image.ID) error {
|
||||
func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[string]image.ID, progressOutput progress.Output) error {
|
||||
if _, loaded := loadedMap[oldID]; loaded {
|
||||
return nil
|
||||
}
|
||||
|
@ -220,7 +244,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str
|
|||
for {
|
||||
var loaded bool
|
||||
if parentID, loaded = loadedMap[img.Parent]; !loaded {
|
||||
if err := l.legacyLoadImage(img.Parent, sourceDir, loadedMap); err != nil {
|
||||
if err := l.legacyLoadImage(img.Parent, sourceDir, loadedMap, progressOutput); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
@ -247,7 +271,7 @@ func (l *tarexporter) legacyLoadImage(oldID, sourceDir string, loadedMap map[str
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newLayer, err := l.loadLayer(layerPath, *rootFS)
|
||||
newLayer, err := l.loadLayer(layerPath, *rootFS, oldID, progressOutput)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue