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 }