Browse code

Move "image_export" to graph/export.go

Signed-off-by: Solomon Hykes <solomon@docker.com>

Solomon Hykes authored on 2014/08/05 13:08:25
Showing 4 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,147 @@
0
+package graph
1
+
2
+import (
3
+	"encoding/json"
4
+	"io"
5
+	"io/ioutil"
6
+	"os"
7
+	"path"
8
+
9
+	"github.com/docker/docker/archive"
10
+	"github.com/docker/docker/engine"
11
+	"github.com/docker/docker/pkg/parsers"
12
+	"github.com/docker/docker/utils"
13
+)
14
+
15
+// CmdImageExport exports all images with the given tag. All versions
16
+// containing the same tag are exported. The resulting output is an
17
+// uncompressed tar ball.
18
+// name is the set of tags to export.
19
+// out is the writer where the images are written to.
20
+func (s *TagStore) CmdImageExport(job *engine.Job) engine.Status {
21
+	if len(job.Args) != 1 {
22
+		return job.Errorf("Usage: %s IMAGE\n", job.Name)
23
+	}
24
+	name := job.Args[0]
25
+	// get image json
26
+	tempdir, err := ioutil.TempDir("", "docker-export-")
27
+	if err != nil {
28
+		return job.Error(err)
29
+	}
30
+	defer os.RemoveAll(tempdir)
31
+
32
+	utils.Debugf("Serializing %s", name)
33
+
34
+	rootRepoMap := map[string]Repository{}
35
+	rootRepo, err := s.Get(name)
36
+	if err != nil {
37
+		return job.Error(err)
38
+	}
39
+	if rootRepo != nil {
40
+		// this is a base repo name, like 'busybox'
41
+
42
+		for _, id := range rootRepo {
43
+			if err := s.exportImage(job.Eng, id, tempdir); err != nil {
44
+				return job.Error(err)
45
+			}
46
+		}
47
+		rootRepoMap[name] = rootRepo
48
+	} else {
49
+		img, err := s.LookupImage(name)
50
+		if err != nil {
51
+			return job.Error(err)
52
+		}
53
+		if img != nil {
54
+			// This is a named image like 'busybox:latest'
55
+			repoName, repoTag := parsers.ParseRepositoryTag(name)
56
+			if err := s.exportImage(job.Eng, img.ID, tempdir); err != nil {
57
+				return job.Error(err)
58
+			}
59
+			// check this length, because a lookup of a truncated has will not have a tag
60
+			// and will not need to be added to this map
61
+			if len(repoTag) > 0 {
62
+				rootRepoMap[repoName] = Repository{repoTag: img.ID}
63
+			}
64
+		} else {
65
+			// this must be an ID that didn't get looked up just right?
66
+			if err := s.exportImage(job.Eng, name, tempdir); err != nil {
67
+				return job.Error(err)
68
+			}
69
+		}
70
+	}
71
+	// write repositories, if there is something to write
72
+	if len(rootRepoMap) > 0 {
73
+		rootRepoJson, _ := json.Marshal(rootRepoMap)
74
+
75
+		if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.FileMode(0644)); err != nil {
76
+			return job.Error(err)
77
+		}
78
+	} else {
79
+		utils.Debugf("There were no repositories to write")
80
+	}
81
+
82
+	fs, err := archive.Tar(tempdir, archive.Uncompressed)
83
+	if err != nil {
84
+		return job.Error(err)
85
+	}
86
+	defer fs.Close()
87
+
88
+	if _, err := io.Copy(job.Stdout, fs); err != nil {
89
+		return job.Error(err)
90
+	}
91
+	utils.Debugf("End Serializing %s", name)
92
+	return engine.StatusOK
93
+}
94
+
95
+// FIXME: this should be a top-level function, not a class method
96
+func (s *TagStore) exportImage(eng *engine.Engine, name, tempdir string) error {
97
+	for n := name; n != ""; {
98
+		// temporary directory
99
+		tmpImageDir := path.Join(tempdir, n)
100
+		if err := os.Mkdir(tmpImageDir, os.FileMode(0755)); err != nil {
101
+			if os.IsExist(err) {
102
+				return nil
103
+			}
104
+			return err
105
+		}
106
+
107
+		var version = "1.0"
108
+		var versionBuf = []byte(version)
109
+
110
+		if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.FileMode(0644)); err != nil {
111
+			return err
112
+		}
113
+
114
+		// serialize json
115
+		json, err := os.Create(path.Join(tmpImageDir, "json"))
116
+		if err != nil {
117
+			return err
118
+		}
119
+		job := eng.Job("image_inspect", n)
120
+		job.SetenvBool("raw", true)
121
+		job.Stdout.Add(json)
122
+		if err := job.Run(); err != nil {
123
+			return err
124
+		}
125
+
126
+		// serialize filesystem
127
+		fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
128
+		if err != nil {
129
+			return err
130
+		}
131
+		job = eng.Job("image_tarlayer", n)
132
+		job.Stdout.Add(fsTar)
133
+		if err := job.Run(); err != nil {
134
+			return err
135
+		}
136
+
137
+		// find parent
138
+		job = eng.Job("image_get", n)
139
+		info, _ := job.Stdout.AddEnv()
140
+		if err := job.Run(); err != nil {
141
+			return err
142
+		}
143
+		n = info.Get("Parent")
144
+	}
145
+	return nil
146
+}
... ...
@@ -15,6 +15,7 @@ func (s *TagStore) Install(eng *engine.Engine) error {
15 15
 	eng.Register("image_get", s.CmdGet)
16 16
 	eng.Register("image_inspect", s.CmdLookup)
17 17
 	eng.Register("image_tarlayer", s.CmdTarLayer)
18
+	eng.Register("image_export", s.CmdImageExport)
18 19
 	return nil
19 20
 }
20 21
 
... ...
@@ -30,138 +30,6 @@ import (
30 30
 	"github.com/docker/docker/utils"
31 31
 )
32 32
 
33
-// ImageExport exports all images with the given tag. All versions
34
-// containing the same tag are exported. The resulting output is an
35
-// uncompressed tar ball.
36
-// name is the set of tags to export.
37
-// out is the writer where the images are written to.
38
-func (srv *Server) ImageExport(job *engine.Job) engine.Status {
39
-	if len(job.Args) != 1 {
40
-		return job.Errorf("Usage: %s IMAGE\n", job.Name)
41
-	}
42
-	name := job.Args[0]
43
-	// get image json
44
-	tempdir, err := ioutil.TempDir("", "docker-export-")
45
-	if err != nil {
46
-		return job.Error(err)
47
-	}
48
-	defer os.RemoveAll(tempdir)
49
-
50
-	utils.Debugf("Serializing %s", name)
51
-
52
-	rootRepoMap := map[string]graph.Repository{}
53
-	rootRepo, err := srv.daemon.Repositories().Get(name)
54
-	if err != nil {
55
-		return job.Error(err)
56
-	}
57
-	if rootRepo != nil {
58
-		// this is a base repo name, like 'busybox'
59
-
60
-		for _, id := range rootRepo {
61
-			if err := srv.exportImage(job.Eng, id, tempdir); err != nil {
62
-				return job.Error(err)
63
-			}
64
-		}
65
-		rootRepoMap[name] = rootRepo
66
-	} else {
67
-		img, err := srv.daemon.Repositories().LookupImage(name)
68
-		if err != nil {
69
-			return job.Error(err)
70
-		}
71
-		if img != nil {
72
-			// This is a named image like 'busybox:latest'
73
-			repoName, repoTag := parsers.ParseRepositoryTag(name)
74
-			if err := srv.exportImage(job.Eng, img.ID, tempdir); err != nil {
75
-				return job.Error(err)
76
-			}
77
-			// check this length, because a lookup of a truncated has will not have a tag
78
-			// and will not need to be added to this map
79
-			if len(repoTag) > 0 {
80
-				rootRepoMap[repoName] = graph.Repository{repoTag: img.ID}
81
-			}
82
-		} else {
83
-			// this must be an ID that didn't get looked up just right?
84
-			if err := srv.exportImage(job.Eng, name, tempdir); err != nil {
85
-				return job.Error(err)
86
-			}
87
-		}
88
-	}
89
-	// write repositories, if there is something to write
90
-	if len(rootRepoMap) > 0 {
91
-		rootRepoJson, _ := json.Marshal(rootRepoMap)
92
-
93
-		if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.FileMode(0644)); err != nil {
94
-			return job.Error(err)
95
-		}
96
-	} else {
97
-		utils.Debugf("There were no repositories to write")
98
-	}
99
-
100
-	fs, err := archive.Tar(tempdir, archive.Uncompressed)
101
-	if err != nil {
102
-		return job.Error(err)
103
-	}
104
-	defer fs.Close()
105
-
106
-	if _, err := io.Copy(job.Stdout, fs); err != nil {
107
-		return job.Error(err)
108
-	}
109
-	utils.Debugf("End Serializing %s", name)
110
-	return engine.StatusOK
111
-}
112
-
113
-func (srv *Server) exportImage(eng *engine.Engine, name, tempdir string) error {
114
-	for n := name; n != ""; {
115
-		// temporary directory
116
-		tmpImageDir := path.Join(tempdir, n)
117
-		if err := os.Mkdir(tmpImageDir, os.FileMode(0755)); err != nil {
118
-			if os.IsExist(err) {
119
-				return nil
120
-			}
121
-			return err
122
-		}
123
-
124
-		var version = "1.0"
125
-		var versionBuf = []byte(version)
126
-
127
-		if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.FileMode(0644)); err != nil {
128
-			return err
129
-		}
130
-
131
-		// serialize json
132
-		json, err := os.Create(path.Join(tmpImageDir, "json"))
133
-		if err != nil {
134
-			return err
135
-		}
136
-		job := eng.Job("image_inspect", n)
137
-		job.SetenvBool("raw", true)
138
-		job.Stdout.Add(json)
139
-		if err := job.Run(); err != nil {
140
-			return err
141
-		}
142
-
143
-		// serialize filesystem
144
-		fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
145
-		if err != nil {
146
-			return err
147
-		}
148
-		job = eng.Job("image_tarlayer", n)
149
-		job.Stdout.Add(fsTar)
150
-		if err := job.Run(); err != nil {
151
-			return err
152
-		}
153
-
154
-		// find parent
155
-		job = eng.Job("image_get", n)
156
-		info, _ := job.Stdout.AddEnv()
157
-		if err := job.Run(); err != nil {
158
-			return err
159
-		}
160
-		n = info.Get("Parent")
161
-	}
162
-	return nil
163
-}
164
-
165 33
 func (srv *Server) Build(job *engine.Job) engine.Status {
166 34
 	if len(job.Args) != 0 {
167 35
 		return job.Errorf("Usage: %s\n", job.Name)
... ...
@@ -88,7 +88,6 @@ func InitServer(job *engine.Job) engine.Status {
88 88
 	for name, handler := range map[string]engine.Handler{
89 89
 		"tag":          srv.ImageTag, // FIXME merge with "image_tag"
90 90
 		"info":         srv.DockerInfo,
91
-		"image_export": srv.ImageExport,
92 91
 		"images":       srv.Images,
93 92
 		"history":      srv.ImageHistory,
94 93
 		"viz":          srv.ImagesViz,