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

Add named context support

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2017-03-20 10:28:21 -07:00
parent fe4d7db1ec
commit 87512bbc84
4 changed files with 74 additions and 19 deletions

View file

@ -189,15 +189,20 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
var contextID *int
if flFrom.IsUsed() {
var err error
context, err := strconv.Atoi(flFrom.Value)
if err != nil {
return errors.Wrap(err, "from expects an integer value corresponding to the context number")
flFrom.Value = strings.ToLower(flFrom.Value)
if context, ok := b.imageContexts.byName[flFrom.Value]; ok {
contextID = &context
} else {
var err error
context, err := strconv.Atoi(flFrom.Value)
if err != nil {
return errors.Wrap(err, "from expects an integer value corresponding to the context number")
}
if err := b.imageContexts.validate(context); err != nil {
return err
}
contextID = &context
}
if err := b.imageContexts.validate(context); err != nil {
return err
}
contextID = &context
}
return b.runContextCommand(args, false, false, "COPY", contextID)
@ -208,7 +213,13 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
// This sets the image the dockerfile will build on top of.
//
func from(b *Builder, args []string, attributes map[string]bool, original string) error {
if len(args) != 1 {
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 errExactlyOneArgument("FROM")
}
@ -221,7 +232,9 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
var image builder.Image
b.resetImageCache()
b.imageContexts.new()
if err := b.imageContexts.new(ctxName); err != nil {
return err
}
// Windows cannot support a container with no base image.
if name == api.NoBaseImageSpecifier {

View file

@ -12,9 +12,10 @@ import (
// imageContexts is a helper for stacking up built image rootfs and reusing
// them as contexts
type imageContexts struct {
b *Builder
list []*imageMount
cache *pathCache
b *Builder
list []*imageMount
byName map[string]int
cache *pathCache
}
type imageMount struct {
@ -23,8 +24,18 @@ type imageMount struct {
release func() error
}
func (ic *imageContexts) new() {
func (ic *imageContexts) new(name string) error {
if len(name) > 0 {
if ic.byName == nil {
ic.byName = make(map[string]int)
}
if _, ok := ic.byName[name]; ok {
return errors.Errorf("duplicate name %s", name)
}
ic.byName[name] = len(ic.list)
}
ic.list = append(ic.list, &imageMount{})
return nil
}
func (ic *imageContexts) update(imageID string) {

View file

@ -80,7 +80,7 @@ func init() {
command.Entrypoint: parseMaybeJSON,
command.Env: parseEnv,
command.Expose: parseStringsWhitespaceDelimited,
command.From: parseString,
command.From: parseStringsWhitespaceDelimited,
command.Healthcheck: parseHealthConfig,
command.Label: parseLabel,
command.Maintainer: parseString,

View file

@ -5752,7 +5752,7 @@ func (s *DockerSuite) TestBuildContChar(c *check.C) {
func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) {
dockerfile := `
FROM busybox
FROM busybox AS first
COPY foo bar
FROM busybox
%s
@ -5762,7 +5762,8 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFS(c *check.C) {
COPY bar /
COPY --from=1 baz sub/
COPY --from=0 bar baz
COPY --from=0 bar bay`
COPY --from=first bar bay`
ctx := fakeContext(c, fmt.Sprintf(dockerfile, ""), map[string]string{
"Dockerfile": dockerfile,
"foo": "abc",
@ -5847,6 +5848,36 @@ func (s *DockerSuite) TestBuildCopyFromPreviousRootFSErrors(c *check.C) {
ExitCode: 1,
Err: "invalid from flag value 0 refers current build block",
})
dockerfile = `
FROM busybox AS foo
COPY --from=bar foo bar`
ctx = fakeContext(c, dockerfile, map[string]string{
"Dockerfile": dockerfile,
"foo": "abc",
})
defer ctx.Close()
buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{
ExitCode: 1,
Err: "invalid context value bar",
})
dockerfile = `
FROM busybox AS 1
COPY --from=1 foo bar`
ctx = fakeContext(c, dockerfile, map[string]string{
"Dockerfile": dockerfile,
"foo": "abc",
})
defer ctx.Close()
buildImage("build1", withExternalBuildContext(ctx)).Assert(c, icmd.Expected{
ExitCode: 1,
Err: "invalid name for build stage",
})
}
func (s *DockerSuite) TestBuildCopyFromPreviousFrom(c *check.C) {
@ -5863,9 +5894,9 @@ func (s *DockerSuite) TestBuildCopyFromPreviousFrom(c *check.C) {
result.Assert(c, icmd.Success)
dockerfile = `
FROM build1:latest
FROM build1:latest AS foo
FROM busybox
COPY --from=0 bar /
COPY --from=foo bar /
COPY foo /`
ctx = fakeContext(c, dockerfile, map[string]string{
"Dockerfile": dockerfile,