mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	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…
	
	Add table
		Add a link
		
	
		Reference in a new issue