github.com/adxhyt/docker@v1.4.2-0.20150117221845-467b7c821390/graph/load.go (about)

     1  // +build linux
     2  
     3  package graph
     4  
     5  import (
     6  	"encoding/json"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"path"
    11  
    12  	log "github.com/Sirupsen/logrus"
    13  	"github.com/docker/docker/engine"
    14  	"github.com/docker/docker/image"
    15  	"github.com/docker/docker/pkg/archive"
    16  	"github.com/docker/docker/pkg/chrootarchive"
    17  	"github.com/docker/docker/utils"
    18  )
    19  
    20  // Loads a set of images into the repository. This is the complementary of ImageExport.
    21  // The input stream is an uncompressed tar ball containing images and metadata.
    22  func (s *TagStore) CmdLoad(job *engine.Job) engine.Status {
    23  	tmpImageDir, err := ioutil.TempDir("", "docker-import-")
    24  	if err != nil {
    25  		return job.Error(err)
    26  	}
    27  	defer os.RemoveAll(tmpImageDir)
    28  
    29  	var (
    30  		repoTarFile = path.Join(tmpImageDir, "repo.tar")
    31  		repoDir     = path.Join(tmpImageDir, "repo")
    32  	)
    33  
    34  	tarFile, err := os.Create(repoTarFile)
    35  	if err != nil {
    36  		return job.Error(err)
    37  	}
    38  	if _, err := io.Copy(tarFile, job.Stdin); err != nil {
    39  		return job.Error(err)
    40  	}
    41  	tarFile.Close()
    42  
    43  	repoFile, err := os.Open(repoTarFile)
    44  	if err != nil {
    45  		return job.Error(err)
    46  	}
    47  	if err := os.Mkdir(repoDir, os.ModeDir); err != nil {
    48  		return job.Error(err)
    49  	}
    50  	images, err := s.graph.Map()
    51  	if err != nil {
    52  		return job.Error(err)
    53  	}
    54  	excludes := make([]string, len(images))
    55  	i := 0
    56  	for k := range images {
    57  		excludes[i] = k
    58  		i++
    59  	}
    60  	if err := chrootarchive.Untar(repoFile, repoDir, &archive.TarOptions{ExcludePatterns: excludes}); err != nil {
    61  		return job.Error(err)
    62  	}
    63  
    64  	dirs, err := ioutil.ReadDir(repoDir)
    65  	if err != nil {
    66  		return job.Error(err)
    67  	}
    68  
    69  	for _, d := range dirs {
    70  		if d.IsDir() {
    71  			if err := s.recursiveLoad(job.Eng, d.Name(), tmpImageDir); err != nil {
    72  				return job.Error(err)
    73  			}
    74  		}
    75  	}
    76  
    77  	repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
    78  	if err == nil {
    79  		repositories := map[string]Repository{}
    80  		if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
    81  			return job.Error(err)
    82  		}
    83  
    84  		for imageName, tagMap := range repositories {
    85  			for tag, address := range tagMap {
    86  				if err := s.Set(imageName, tag, address, true); err != nil {
    87  					return job.Error(err)
    88  				}
    89  			}
    90  		}
    91  	} else if !os.IsNotExist(err) {
    92  		return job.Error(err)
    93  	}
    94  
    95  	return engine.StatusOK
    96  }
    97  
    98  func (s *TagStore) recursiveLoad(eng *engine.Engine, address, tmpImageDir string) error {
    99  	if err := eng.Job("image_get", address).Run(); err != nil {
   100  		log.Debugf("Loading %s", address)
   101  
   102  		imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json"))
   103  		if err != nil {
   104  			log.Debugf("Error reading json", err)
   105  			return err
   106  		}
   107  
   108  		layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar"))
   109  		if err != nil {
   110  			log.Debugf("Error reading embedded tar", err)
   111  			return err
   112  		}
   113  		img, err := image.NewImgJSON(imageJson)
   114  		if err != nil {
   115  			log.Debugf("Error unmarshalling json", err)
   116  			return err
   117  		}
   118  		if err := utils.ValidateID(img.ID); err != nil {
   119  			log.Debugf("Error validating ID: %s", err)
   120  			return err
   121  		}
   122  		if img.Parent != "" {
   123  			if !s.graph.Exists(img.Parent) {
   124  				if err := s.recursiveLoad(eng, img.Parent, tmpImageDir); err != nil {
   125  					return err
   126  				}
   127  			}
   128  		}
   129  		if err := s.graph.Register(img, layer); err != nil {
   130  			return err
   131  		}
   132  	}
   133  	log.Debugf("Completed processing %s", address)
   134  
   135  	return nil
   136  }