@@ -176,69 +176,80 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
176
176
return b .runContextCommand (args , false , false , "COPY" , im )
177
177
}
178
178
179
- // FROM imagename
180
- //
181
- // This sets the image the dockerfile will build on top of.
179
+ // FROM imagename[:tag | @digest] [AS build-stage-name]
182
180
//
181
+ // from sets the base image
183
182
func from (b * Builder , args []string , attributes map [string ]bool , original string ) error {
184
- ctxName := ""
185
- if len (args ) == 3 && strings .EqualFold (args [1 ], "as" ) {
186
- ctxName = strings .ToLower (args [2 ])
187
- if ok , _ := regexp .MatchString ("^[a-z][a-z0-9-_\\ .]*$" , ctxName ); ! ok {
188
- return errors .Errorf ("invalid name for build stage: %q, name can't start with a number or contain symbols" , ctxName )
189
- }
190
- } else if len (args ) != 1 {
191
- return errors .New ("FROM requires either one or three arguments" )
183
+ ctxName , err := parseBuildStageName (args )
184
+ if err != nil {
185
+ return err
192
186
}
193
187
194
188
if err := b .flags .Parse (); err != nil {
195
189
return err
196
190
}
197
-
198
- substituionArgs := []string {}
199
- for key , value := range b .buildArgs .GetAllMeta () {
200
- substituionArgs = append (substituionArgs , key + "=" + value )
191
+ b .resetImageCache ()
192
+ if _ , err := b .imageContexts .add (ctxName ); err != nil {
193
+ return err
201
194
}
202
195
203
- name , err := ProcessWord (args [0 ], substituionArgs , b . escapeToken )
196
+ image , err := b . getFromImage (args [0 ])
204
197
if err != nil {
205
198
return err
206
199
}
200
+ if image != nil {
201
+ b .imageContexts .update (image .ImageID (), image .RunConfig ())
202
+ }
203
+ b .from = image
207
204
208
- var image builder.Image
205
+ b .buildArgs .ResetAllowed ()
206
+ return b .processImageFrom (image )
207
+ }
209
208
210
- b .resetImageCache ()
211
- if _ , err := b .imageContexts .new (ctxName , true ); err != nil {
212
- return err
209
+ func parseBuildStageName (args []string ) (string , error ) {
210
+ stageName := ""
211
+ switch {
212
+ case len (args ) == 3 && strings .EqualFold (args [1 ], "as" ):
213
+ stageName = strings .ToLower (args [2 ])
214
+ if ok , _ := regexp .MatchString ("^[a-z][a-z0-9-_\\ .]*$" , stageName ); ! ok {
215
+ return "" , errors .Errorf ("invalid name for build stage: %q, name can't start with a number or contain symbols" , stageName )
216
+ }
217
+ case len (args ) != 1 :
218
+ return "" , errors .New ("FROM requires either one or three arguments" )
219
+ }
220
+
221
+ return stageName , nil
222
+ }
223
+
224
+ func (b * Builder ) getFromImage (name string ) (builder.Image , error ) {
225
+ substitutionArgs := []string {}
226
+ for key , value := range b .buildArgs .GetAllMeta () {
227
+ substitutionArgs = append (substitutionArgs , key + "=" + value )
228
+ }
229
+
230
+ name , err := ProcessWord (name , substitutionArgs , b .escapeToken )
231
+ if err != nil {
232
+ return nil , err
213
233
}
214
234
215
235
if im , ok := b .imageContexts .byName [name ]; ok {
216
236
if len (im .ImageID ()) > 0 {
217
- image = im
218
- }
219
- } else {
220
- // Windows cannot support a container with no base image.
221
- if name == api .NoBaseImageSpecifier {
222
- if runtime .GOOS == "windows" {
223
- return errors .New ("Windows does not support FROM scratch" )
224
- }
225
- b .image = ""
226
- b .noBaseImage = true
227
- } else {
228
- var err error
229
- image , err = pullOrGetImage (b , name )
230
- if err != nil {
231
- return err
232
- }
237
+ return im , nil
233
238
}
239
+ // FROM scratch does not have an ImageID
240
+ return nil , nil
234
241
}
235
- if image != nil {
236
- b .imageContexts .update (image .ImageID (), image .RunConfig ())
237
- }
238
- b .from = image
239
242
240
- b .buildArgs .ResetAllowed ()
241
- return b .processImageFrom (image )
243
+ // Windows cannot support a container with no base image.
244
+ if name == api .NoBaseImageSpecifier {
245
+ if runtime .GOOS == "windows" {
246
+ return nil , errors .New ("Windows does not support FROM scratch" )
247
+ }
248
+ b .image = ""
249
+ b .noBaseImage = true
250
+ return nil , nil
251
+ }
252
+ return pullOrGetImage (b , name )
242
253
}
243
254
244
255
// ONBUILD RUN echo yo
@@ -835,11 +846,7 @@ func mountByRef(b *Builder, name string) (*imageMount, error) {
835
846
if err != nil {
836
847
return nil , err
837
848
}
838
- im , err := b .imageContexts .new ("" , false )
839
- if err != nil {
840
- return nil , err
841
- }
842
- im .id = image .ImageID ()
849
+ im := b .imageContexts .newImageMount (image .ImageID ())
843
850
return im , nil
844
851
}
845
852
0 commit comments