1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Extract two functions from the FROM dispatcher

This helps clarify the difference cases for parsing ctxName, and for
getting an image.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-03-27 17:51:42 -07:00
parent 700b4807c3
commit 4d62f67117

View file

@ -176,61 +176,26 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
return b.runContextCommand(args, false, false, "COPY", im)
}
// FROM imagename
//
// This sets the image the dockerfile will build on top of.
// FROM imagename[:tag | @digest] [AS build-stage-name]
//
// from sets the base image
func from(b *Builder, args []string, attributes map[string]bool, original string) error {
ctxName := ""
if len(args) == 3 && strings.EqualFold(args[1], "as") {
ctxName = strings.ToLower(args[2])
if ok, _ := regexp.MatchString("^[a-z][a-z0-9-_\\.]*$", ctxName); !ok {
return errors.Errorf("invalid name for build stage: %q, name can't start with a number or contain symbols", ctxName)
}
} else if len(args) != 1 {
return errors.New("FROM requires either one or three arguments")
ctxName, err := parseBuildStageName(args)
if err != nil {
return err
}
if err := b.flags.Parse(); err != nil {
return err
}
substituionArgs := []string{}
for key, value := range b.buildArgs.GetAllMeta() {
substituionArgs = append(substituionArgs, key+"="+value)
}
name, err := ProcessWord(args[0], substituionArgs, b.escapeToken)
if err != nil {
return err
}
var image builder.Image
b.resetImageCache()
if _, err := b.imageContexts.new(ctxName, true); err != nil {
return err
}
if im, ok := b.imageContexts.byName[name]; ok {
if len(im.ImageID()) > 0 {
image = im
}
} else {
// Windows cannot support a container with no base image.
if name == api.NoBaseImageSpecifier {
if runtime.GOOS == "windows" {
return errors.New("Windows does not support FROM scratch")
}
b.image = ""
b.noBaseImage = true
} else {
var err error
image, err = pullOrGetImage(b, name)
if err != nil {
return err
}
}
image, err := b.getFromImage(args[0])
if err != nil {
return err
}
if image != nil {
b.imageContexts.update(image.ImageID(), image.RunConfig())
@ -241,6 +206,52 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
return b.processImageFrom(image)
}
func parseBuildStageName(args []string) (string, error) {
stageName := ""
switch {
case len(args) == 3 && strings.EqualFold(args[1], "as"):
stageName = strings.ToLower(args[2])
if ok, _ := regexp.MatchString("^[a-z][a-z0-9-_\\.]*$", stageName); !ok {
return "", errors.Errorf("invalid name for build stage: %q, name can't start with a number or contain symbols", stageName)
}
case len(args) != 1:
return "", errors.New("FROM requires either one or three arguments")
}
return stageName, nil
}
func (b *Builder) getFromImage(name string) (builder.Image, error) {
substitutionArgs := []string{}
for key, value := range b.buildArgs.GetAllMeta() {
substitutionArgs = append(substitutionArgs, key+"="+value)
}
name, err := ProcessWord(name, substitutionArgs, b.escapeToken)
if err != nil {
return nil, err
}
if im, ok := b.imageContexts.byName[name]; ok {
if len(im.ImageID()) > 0 {
return im, nil
}
// FROM scratch does not have an ImageID
return nil, nil
}
// Windows cannot support a container with no base image.
if name == api.NoBaseImageSpecifier {
if runtime.GOOS == "windows" {
return nil, errors.New("Windows does not support FROM scratch")
}
b.image = ""
b.noBaseImage = true
return nil, nil
}
return pullOrGetImage(b, name)
}
// ONBUILD RUN echo yo
//
// ONBUILD triggers run when the image is used in a FROM statement.