diff --git a/graph/load.go b/graph/load.go new file mode 100644 index 0000000000..5d84b82c28 --- /dev/null +++ b/graph/load.go @@ -0,0 +1,118 @@ +package graph + +import ( + "encoding/json" + "io" + "io/ioutil" + "os" + "path" + + "github.com/docker/docker/archive" + "github.com/docker/docker/engine" + "github.com/docker/docker/image" + "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) + } + if err := archive.Untar(repoFile, repoDir, nil); 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 { + utils.Debugf("Loading %s", address) + + imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json")) + if err != nil { + utils.Debugf("Error reading json", err) + return err + } + + layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar")) + if err != nil { + utils.Debugf("Error reading embedded tar", err) + return err + } + img, err := image.NewImgJSON(imageJson) + if err != nil { + utils.Debugf("Error unmarshalling json", 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(imageJson, layer, img); err != nil { + return err + } + } + utils.Debugf("Completed processing %s", address) + + return nil +} diff --git a/graph/service.go b/graph/service.go index 8e6c4108c4..8c61296b1e 100644 --- a/graph/service.go +++ b/graph/service.go @@ -19,6 +19,7 @@ func (s *TagStore) Install(eng *engine.Engine) error { eng.Register("history", s.CmdHistory) eng.Register("images", s.CmdImages) eng.Register("viz", s.CmdViz) + eng.Register("load", s.CmdLoad) return nil } diff --git a/server/image.go b/server/image.go index 957b33e76b..8fdc71dc11 100644 --- a/server/image.go +++ b/server/image.go @@ -5,7 +5,6 @@ package server import ( - "encoding/json" "fmt" "io" "io/ioutil" @@ -108,110 +107,6 @@ func (srv *Server) Build(job *engine.Job) engine.Status { return engine.StatusOK } -// 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 (srv *Server) ImageLoad(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) - } - if err := archive.Untar(repoFile, repoDir, nil); 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 := srv.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]graph.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 := srv.daemon.Repositories().Set(imageName, tag, address, true); err != nil { - return job.Error(err) - } - } - } - } else if !os.IsNotExist(err) { - return job.Error(err) - } - - return engine.StatusOK -} - -func (srv *Server) recursiveLoad(eng *engine.Engine, address, tmpImageDir string) error { - if err := eng.Job("image_get", address).Run(); err != nil { - utils.Debugf("Loading %s", address) - - imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json")) - if err != nil { - utils.Debugf("Error reading json", err) - return err - } - - layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar")) - if err != nil { - utils.Debugf("Error reading embedded tar", err) - return err - } - img, err := image.NewImgJSON(imageJson) - if err != nil { - utils.Debugf("Error unmarshalling json", err) - return err - } - if img.Parent != "" { - if !srv.daemon.Graph().Exists(img.Parent) { - if err := srv.recursiveLoad(eng, img.Parent, tmpImageDir); err != nil { - return err - } - } - } - if err := srv.daemon.Graph().Register(imageJson, layer, img); err != nil { - return err - } - } - utils.Debugf("Completed processing %s", address) - - return nil -} - func (srv *Server) ImageTag(job *engine.Job) engine.Status { if len(job.Args) != 2 && len(job.Args) != 3 { return job.Errorf("Usage: %s IMAGE REPOSITORY [TAG]\n", job.Name) diff --git a/server/init.go b/server/init.go index 34696f7272..20d7088839 100644 --- a/server/init.go +++ b/server/init.go @@ -89,7 +89,6 @@ func InitServer(job *engine.Job) engine.Status { "tag": srv.ImageTag, // FIXME merge with "image_tag" "info": srv.DockerInfo, "log": srv.Log, - "load": srv.ImageLoad, "build": srv.Build, "pull": srv.ImagePull, "import": srv.ImageImport,