123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // +build linux
- package graph
- import (
- "encoding/json"
- "io"
- "io/ioutil"
- "os"
- "path"
- log "github.com/Sirupsen/logrus"
- "github.com/docker/docker/engine"
- "github.com/docker/docker/image"
- "github.com/docker/docker/pkg/archive"
- "github.com/docker/docker/pkg/chrootarchive"
- "github.com/docker/docker/utils"
- )
- // Loads a set of images into the repository. This is the complementary of ImageExport.
- // The input stream is an uncompressed tar ball containing images and metadata.
- func (s *TagStore) CmdLoad(job *engine.Job) engine.Status {
- tmpImageDir, err := ioutil.TempDir("", "docker-import-")
- if err != nil {
- return job.Error(err)
- }
- defer os.RemoveAll(tmpImageDir)
- var (
- repoTarFile = path.Join(tmpImageDir, "repo.tar")
- repoDir = path.Join(tmpImageDir, "repo")
- )
- tarFile, err := os.Create(repoTarFile)
- if err != nil {
- return job.Error(err)
- }
- if _, err := io.Copy(tarFile, job.Stdin); err != nil {
- return job.Error(err)
- }
- tarFile.Close()
- repoFile, err := os.Open(repoTarFile)
- if err != nil {
- return job.Error(err)
- }
- if err := os.Mkdir(repoDir, os.ModeDir); err != nil {
- return job.Error(err)
- }
- images, err := s.graph.Map()
- if err != nil {
- return job.Error(err)
- }
- excludes := make([]string, len(images))
- i := 0
- for k := range images {
- excludes[i] = k
- i++
- }
- if err := chrootarchive.Untar(repoFile, repoDir, &archive.TarOptions{ExcludePatterns: excludes}); err != nil {
- return job.Error(err)
- }
- dirs, err := ioutil.ReadDir(repoDir)
- if err != nil {
- return job.Error(err)
- }
- for _, d := range dirs {
- if d.IsDir() {
- if err := s.recursiveLoad(job.Eng, d.Name(), tmpImageDir); err != nil {
- return job.Error(err)
- }
- }
- }
- repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
- if err == nil {
- repositories := map[string]Repository{}
- if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
- return job.Error(err)
- }
- for imageName, tagMap := range repositories {
- for tag, address := range tagMap {
- if err := s.Set(imageName, tag, address, true); err != nil {
- return job.Error(err)
- }
- }
- }
- } else if !os.IsNotExist(err) {
- return job.Error(err)
- }
- return engine.StatusOK
- }
- func (s *TagStore) recursiveLoad(eng *engine.Engine, address, tmpImageDir string) error {
- if err := eng.Job("image_get", address).Run(); err != nil {
- log.Debugf("Loading %s", address)
- imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json"))
- if err != nil {
- log.Debugf("Error reading json", err)
- return err
- }
- layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar"))
- if err != nil {
- log.Debugf("Error reading embedded tar", err)
- return err
- }
- img, err := image.NewImgJSON(imageJson)
- if err != nil {
- log.Debugf("Error unmarshalling json", err)
- return err
- }
- if err := utils.ValidateID(img.ID); err != nil {
- log.Debugf("Error validating ID: %s", err)
- return err
- }
- if img.Parent != "" {
- if !s.graph.Exists(img.Parent) {
- if err := s.recursiveLoad(eng, img.Parent, tmpImageDir); err != nil {
- return err
- }
- }
- }
- if err := s.graph.Register(img, layer); err != nil {
- return err
- }
- }
- log.Debugf("Completed processing %s", address)
- return nil
- }
|