mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
26184de8ab
The argument specified the json data to save to disk when registering a new image into the image graph. If it is nil, then the given image is serialized to json and that is written by default. This default behavior is sufficient if the given image was originally deserialzed from this jsonData to begin with which has always been the case. Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
128 lines
3 KiB
Go
128 lines
3 KiB
Go
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"
|
|
)
|
|
|
|
// 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 := archive.Untar(repoFile, repoDir, &archive.TarOptions{Excludes: 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 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
|
|
}
|