Browse code

Make Builder.Build return the builded image

Guillaume J. Charmes authored on 2013/04/26 03:20:45
Showing 3 changed files
... ...
@@ -120,7 +120,7 @@ func (builder *Builder) clearTmp(containers, images map[string]struct{}) {
120 120
 	}
121 121
 }
122 122
 
123
-func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
123
+func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) (*Image, error) {
124 124
 	var (
125 125
 		image, base   *Image
126 126
 		tmpContainers map[string]struct{} = make(map[string]struct{})
... ...
@@ -135,7 +135,7 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
135 135
 			if err == io.EOF {
136 136
 				break
137 137
 			}
138
-			return err
138
+			return nil, err
139 139
 		}
140 140
 		line = strings.TrimSpace(line)
141 141
 		// Skip comments and empty line
... ...
@@ -144,45 +144,45 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
144 144
 		}
145 145
 		tmp := strings.SplitN(line, "	", 2)
146 146
 		if len(tmp) != 2 {
147
-			return fmt.Errorf("Invalid Dockerfile format")
147
+			return nil, fmt.Errorf("Invalid Dockerfile format")
148 148
 		}
149 149
 		switch tmp[0] {
150 150
 		case "from":
151 151
 			fmt.Fprintf(stdout, "FROM %s\n", tmp[1])
152 152
 			image, err = builder.runtime.repositories.LookupImage(tmp[1])
153 153
 			if err != nil {
154
-				return err
154
+				return nil, err
155 155
 			}
156 156
 			break
157 157
 		case "run":
158 158
 			fmt.Fprintf(stdout, "RUN %s\n", tmp[1])
159 159
 			if image == nil {
160
-				return fmt.Errorf("Please provide a source image with `from` prior to run")
160
+				return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
161 161
 			}
162 162
 			config, err := ParseRun([]string{image.Id, "/bin/sh", "-c", tmp[1]}, nil, builder.runtime.capabilities)
163 163
 			if err != nil {
164
-				return err
164
+				return nil, err
165 165
 			}
166 166
 
167 167
 			// Create the container and start it
168 168
 			c, err := builder.Create(config)
169 169
 			if err != nil {
170
-				return err
170
+				return nil, err
171 171
 			}
172 172
 			if err := c.Start(); err != nil {
173
-				return err
173
+				return nil, err
174 174
 			}
175 175
 			tmpContainers[c.Id] = struct{}{}
176 176
 
177 177
 			// Wait for it to finish
178 178
 			if result := c.Wait(); result != 0 {
179
-				return fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
179
+				return nil, fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
180 180
 			}
181 181
 
182 182
 			// Commit the container
183 183
 			base, err = builder.Commit(c, "", "", "", "")
184 184
 			if err != nil {
185
-				return err
185
+				return nil, err
186 186
 			}
187 187
 			tmpImages[base.Id] = struct{}{}
188 188
 
... ...
@@ -194,45 +194,45 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
194 194
 			break
195 195
 		case "copy":
196 196
 			if image == nil {
197
-				return fmt.Errorf("Please provide a source image with `from` prior to copy")
197
+				return nil, fmt.Errorf("Please provide a source image with `from` prior to copy")
198 198
 			}
199 199
 			tmp2 := strings.SplitN(tmp[1], " ", 2)
200 200
 			if len(tmp) != 2 {
201
-				return fmt.Errorf("Invalid COPY format")
201
+				return nil, fmt.Errorf("Invalid COPY format")
202 202
 			}
203 203
 			fmt.Fprintf(stdout, "COPY %s to %s in %s\n", tmp2[0], tmp2[1], base.ShortId())
204 204
 
205 205
 			file, err := Download(tmp2[0], stdout)
206 206
 			if err != nil {
207
-				return err
207
+				return nil, err
208 208
 			}
209 209
 			defer file.Body.Close()
210 210
 
211 211
 			config, err := ParseRun([]string{base.Id, "echo", "insert", tmp2[0], tmp2[1]}, nil, builder.runtime.capabilities)
212 212
 			if err != nil {
213
-				return err
213
+				return nil, err
214 214
 			}
215 215
 			c, err := builder.Create(config)
216 216
 			if err != nil {
217
-				return err
217
+				return nil, err
218 218
 			}
219 219
 
220 220
 			if err := c.Start(); err != nil {
221
-				return err
221
+				return nil, err
222 222
 			}
223 223
 
224 224
 			// Wait for echo to finish
225 225
 			if result := c.Wait(); result != 0 {
226
-				return fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
226
+				return nil, fmt.Errorf("!!! '%s' return non-zero exit code '%d'. Aborting.", tmp[1], result)
227 227
 			}
228 228
 
229 229
 			if err := c.Inject(file.Body, tmp2[1]); err != nil {
230
-				return err
230
+				return nil, err
231 231
 			}
232 232
 
233 233
 			base, err = builder.Commit(c, "", "", "", "")
234 234
 			if err != nil {
235
-				return err
235
+				return nil, err
236 236
 			}
237 237
 			fmt.Fprintf(stdout, "===> %s\n", base.ShortId())
238 238
 			break
... ...
@@ -252,5 +252,5 @@ func (builder *Builder) Build(dockerfile io.Reader, stdout io.Writer) error {
252 252
 	} else {
253 253
 		fmt.Fprintf(stdout, "An error occured during the build\n")
254 254
 	}
255
-	return nil
255
+	return base, nil
256 256
 }
... ...
@@ -136,7 +136,12 @@ func (srv *Server) CmdBuild(stdin io.ReadCloser, stdout rcli.DockerConn, args ..
136 136
 	} else {
137 137
 		file = stdin
138 138
 	}
139
-	return NewBuilder(srv.runtime).Build(file, stdout)
139
+	img, err := NewBuilder(srv.runtime).Build(file, stdout)
140
+	if err != nil {
141
+		return err
142
+	}
143
+	fmt.Fprintf(stdout, "%s\n", img.ShortId())
144
+	return nil
140 145
 }
141 146
 
142 147
 // 'docker login': login / register a user to registry service.
... ...
@@ -154,6 +154,13 @@ func SelfPath() string {
154 154
 	return path
155 155
 }
156 156
 
157
+type nopWriter struct {
158
+}
159
+
160
+func (w *nopWriter) Write(buf []byte) (int, error) {
161
+	return len(buf), nil
162
+}
163
+
157 164
 type nopWriteCloser struct {
158 165
 	io.Writer
159 166
 }