Skip to content

Commit 3beb8d9

Browse files
authored
Merge pull request moby#32500 from dnephin/refactor-from-dispatcher
Refactor from dispatcher
2 parents 8cb9d7e + aafd7fa commit 3beb8d9

File tree

2 files changed

+60
-51
lines changed

2 files changed

+60
-51
lines changed

builder/dockerfile/dispatchers.go

+54-47
Original file line numberDiff line numberDiff line change
@@ -176,69 +176,80 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
176176
return b.runContextCommand(args, false, false, "COPY", im)
177177
}
178178

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]
182180
//
181+
// from sets the base image
183182
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
192186
}
193187

194188
if err := b.flags.Parse(); err != nil {
195189
return err
196190
}
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
201194
}
202195

203-
name, err := ProcessWord(args[0], substituionArgs, b.escapeToken)
196+
image, err := b.getFromImage(args[0])
204197
if err != nil {
205198
return err
206199
}
200+
if image != nil {
201+
b.imageContexts.update(image.ImageID(), image.RunConfig())
202+
}
203+
b.from = image
207204

208-
var image builder.Image
205+
b.buildArgs.ResetAllowed()
206+
return b.processImageFrom(image)
207+
}
209208

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
213233
}
214234

215235
if im, ok := b.imageContexts.byName[name]; ok {
216236
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
233238
}
239+
// FROM scratch does not have an ImageID
240+
return nil, nil
234241
}
235-
if image != nil {
236-
b.imageContexts.update(image.ImageID(), image.RunConfig())
237-
}
238-
b.from = image
239242

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)
242253
}
243254

244255
// ONBUILD RUN echo yo
@@ -835,11 +846,7 @@ func mountByRef(b *Builder, name string) (*imageMount, error) {
835846
if err != nil {
836847
return nil, err
837848
}
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())
843850
return im, nil
844851
}
845852

builder/dockerfile/imagecontext.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ type imageContexts struct {
2222
currentName string
2323
}
2424

25-
func (ic *imageContexts) new(name string, increment bool) (*imageMount, error) {
25+
func (ic *imageContexts) newImageMount(id string) *imageMount {
26+
return &imageMount{ic: ic, id: id}
27+
}
28+
29+
func (ic *imageContexts) add(name string) (*imageMount, error) {
2630
im := &imageMount{ic: ic}
2731
if len(name) > 0 {
2832
if ic.byName == nil {
@@ -33,10 +37,8 @@ func (ic *imageContexts) new(name string, increment bool) (*imageMount, error) {
3337
}
3438
ic.byName[name] = im
3539
}
36-
if increment {
37-
ic.list = append(ic.list, im)
38-
}
3940
ic.currentName = name
41+
ic.list = append(ic.list, im)
4042
return im, nil
4143
}
4244

0 commit comments

Comments
 (0)