@@ -185,25 +185,14 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
185185
186186// build runs the Dockerfile builder from a context and a docker object that allows to make calls
187187// to Docker.
188- //
189- // This will (barring errors):
190- //
191- // * read the dockerfile from context
192- // * parse the dockerfile if not already parsed
193- // * walk the AST and execute it by dispatching to handlers. If Remove
194- // or ForceRemove is set, additional cleanup around containers happens after
195- // processing.
196- // * Tag image, if applicable.
197- // * Print a happy message and return the image ID.
198- //
199188func (b * Builder ) build (stdout io.Writer , stderr io.Writer , out io.Writer ) (string , error ) {
200189 defer b .imageContexts .unmount ()
201190
202191 b .Stdout = stdout
203192 b .Stderr = stderr
204193 b .Output = out
205194
206- dockerfile , err := b .readDockerfile ()
195+ dockerfile , err := b .readAndParseDockerfile ()
207196 if err != nil {
208197 return "" , err
209198 }
@@ -215,14 +204,37 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
215204
216205 addNodesForLabelOption (dockerfile , b .options .Labels )
217206
218- var shortImgID string
219- total := len (dockerfile .Children )
220- for _ , n := range dockerfile .Children {
221- if err := b .checkDispatch (n , false ); err != nil {
222- return "" , errors .Wrapf (err , "Dockerfile parse error line %d" , n .StartLine )
207+ if err := checkDispatchDockerfile (dockerfile ); err != nil {
208+ return "" , err
209+ }
210+
211+ shortImageID , err := b .dispatchDockerfileWithCancellation (dockerfile )
212+ if err != nil {
213+ return "" , err
214+ }
215+
216+ b .warnOnUnusedBuildArgs ()
217+
218+ if b .image == "" {
219+ return "" , errors .New ("No image was generated. Is your Dockerfile empty?" )
220+ }
221+
222+ if b .options .Squash {
223+ if err := b .squashBuild (); err != nil {
224+ return "" , err
223225 }
224226 }
225227
228+ fmt .Fprintf (b .Stdout , "Successfully built %s\n " , shortImageID )
229+ if err := b .tagImages (repoAndTags ); err != nil {
230+ return "" , err
231+ }
232+ return b .image , nil
233+ }
234+
235+ func (b * Builder ) dispatchDockerfileWithCancellation (dockerfile * parser.Node ) (string , error ) {
236+ total := len (dockerfile .Children )
237+ var shortImgID string
226238 for i , n := range dockerfile .Children {
227239 select {
228240 case <- b .clientCtx .Done ():
@@ -255,34 +267,20 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
255267 return "" , errors .Errorf ("failed to reach build target %s in Dockerfile" , b .options .Target )
256268 }
257269
258- b .warnOnUnusedBuildArgs ()
259-
260- if b .image == "" {
261- return "" , errors .New ("No image was generated. Is your Dockerfile empty?" )
262- }
270+ return shortImgID , nil
271+ }
263272
264- if b .options .Squash {
265- var fromID string
266- if b .from != nil {
267- fromID = b .from .ImageID ()
268- }
269- b .image , err = b .docker .SquashImage (b .image , fromID )
270- if err != nil {
271- return "" , errors .Wrap (err , "error squashing image" )
272- }
273+ func (b * Builder ) squashBuild () error {
274+ var fromID string
275+ var err error
276+ if b .from != nil {
277+ fromID = b .from .ImageID ()
273278 }
274-
275- fmt .Fprintf (b .Stdout , "Successfully built %s\n " , shortImgID )
276-
277- imageID := image .ID (b .image )
278- for _ , rt := range repoAndTags {
279- if err := b .docker .TagImageWithReference (imageID , rt ); err != nil {
280- return "" , err
281- }
282- fmt .Fprintf (b .Stdout , "Successfully tagged %s\n " , reference .FamiliarString (rt ))
279+ b .image , err = b .docker .SquashImage (b .image , fromID )
280+ if err != nil {
281+ return errors .Wrap (err , "error squashing image" )
283282 }
284-
285- return b .image , nil
283+ return nil
286284}
287285
288286func addNodesForLabelOption (dockerfile * parser.Node , labels map [string ]string ) {
@@ -303,6 +301,17 @@ func (b *Builder) warnOnUnusedBuildArgs() {
303301 }
304302}
305303
304+ func (b * Builder ) tagImages (repoAndTags []reference.Named ) error {
305+ imageID := image .ID (b .image )
306+ for _ , rt := range repoAndTags {
307+ if err := b .docker .TagImageWithReference (imageID , rt ); err != nil {
308+ return err
309+ }
310+ fmt .Fprintf (b .Stdout , "Successfully tagged %s\n " , reference .FamiliarString (rt ))
311+ }
312+ return nil
313+ }
314+
306315// hasFromImage returns true if the builder has processed a `FROM <image>` line
307316func (b * Builder ) hasFromImage () bool {
308317 return b .image != "" || b .noBaseImage
@@ -345,18 +354,31 @@ func BuildFromConfig(config *container.Config, changes []string) (*container.Con
345354 b .Stderr = ioutil .Discard
346355 b .disableCommit = true
347356
348- total := len (ast .Children )
349- for _ , n := range ast .Children {
350- if err := b .checkDispatch (n , false ); err != nil {
351- return nil , err
357+ if err := checkDispatchDockerfile (ast ); err != nil {
358+ return nil , err
359+ }
360+
361+ if err := dispatchFromDockerfile (b , ast ); err != nil {
362+ return nil , err
363+ }
364+ return b .runConfig , nil
365+ }
366+
367+ func checkDispatchDockerfile (dockerfile * parser.Node ) error {
368+ for _ , n := range dockerfile .Children {
369+ if err := checkDispatch (n ); err != nil {
370+ return errors .Wrapf (err , "Dockerfile parse error line %d" , n .StartLine )
352371 }
353372 }
373+ return nil
374+ }
354375
376+ func dispatchFromDockerfile (b * Builder , ast * parser.Node ) error {
377+ total := len (ast .Children )
355378 for i , n := range ast .Children {
356379 if err := b .dispatch (i , total , n ); err != nil {
357- return nil , err
380+ return err
358381 }
359382 }
360-
361- return b .runConfig , nil
383+ return nil
362384}
0 commit comments