Browse code

Add insert command in order to insert external files within an image

Guillaume J. Charmes authored on 2013/04/25 05:37:00
Showing 2 changed files
... ...
@@ -42,6 +42,7 @@ func (srv *Server) Help() string {
42 42
 		{"images", "List images"},
43 43
 		{"import", "Create a new filesystem image from the contents of a tarball"},
44 44
 		{"info", "Display system-wide information"},
45
+		{"insert", "Insert a file in an image"},
45 46
 		{"inspect", "Return low-level information on a container"},
46 47
 		{"kill", "Kill a running container"},
47 48
 		{"login", "Register or Login to the docker registry server"},
... ...
@@ -65,6 +66,48 @@ func (srv *Server) Help() string {
65 65
 	return help
66 66
 }
67 67
 
68
+func (srv *Server) CmdInsert(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
69
+	stdout.Flush()
70
+	cmd := rcli.Subcmd(stdout, "insert", "IMAGE URL PATH", "Insert a file from URL in the IMAGE at PATH")
71
+	if err := cmd.Parse(args); err != nil {
72
+		return nil
73
+	}
74
+	if cmd.NArg() != 3 {
75
+		cmd.Usage()
76
+		return nil
77
+	}
78
+	imageId := cmd.Arg(0)
79
+	url := cmd.Arg(1)
80
+	path := cmd.Arg(2)
81
+
82
+	img, err := srv.runtime.repositories.LookupImage(imageId)
83
+	if err != nil {
84
+		return err
85
+	}
86
+	file, err := Download(url, stdout)
87
+	if err != nil {
88
+		return err
89
+	}
90
+	defer file.Body.Close()
91
+
92
+	b := NewBuilder(srv.runtime)
93
+	c, err := b.Run(img, "echo", "insert", url, path)
94
+	if err != nil {
95
+		return err
96
+	}
97
+
98
+	if err := c.Inject(ProgressReader(file.Body, int(file.ContentLength), stdout, "Downloading %v/%v (%v)"), path); err != nil {
99
+		return err
100
+	}
101
+	// FIXME: Handle custom repo, tag comment, author
102
+	img, err = b.Commit(c, "", "", img.Comment, img.Author)
103
+	if err != nil {
104
+		return err
105
+	}
106
+	fmt.Fprintf(stdout, "%s\n", img)
107
+	return nil
108
+}
109
+
68 110
 func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
69 111
 	stdout.Flush()
70 112
 	cmd := rcli.Subcmd(stdout, "build", "[Dockerfile|-]", "Build a container from Dockerfile")
... ...
@@ -168,6 +168,18 @@ func (settings *NetworkSettings) PortMappingHuman() string {
168 168
 	return strings.Join(mapping, ", ")
169 169
 }
170 170
 
171
+// Inject the io.Reader at the given path. Note: do not close the reader
172
+func (container *Container) Inject(file io.Reader, pth string) error {
173
+	dest, err := os.Open(path.Join(container.rwPath(), pth))
174
+	if err != nil {
175
+		return err
176
+	}
177
+	if _, err := io.Copy(dest, file); err != nil {
178
+		return err
179
+	}
180
+	return nil
181
+}
182
+
171 183
 func (container *Container) Cmd() *exec.Cmd {
172 184
 	return container.cmd
173 185
 }