Merge pull request #156 from tonistiigi/dockerfile-git

dockerfile: allow building from git
docker-18.09
Akihiro Suda 2017-11-07 10:50:31 +09:00 committed by GitHub
commit 2898b24cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 3 deletions

View File

@ -20,6 +20,8 @@ const (
defaultDockerfileName = "Dockerfile"
localNameDockerfile = "dockerfile"
buildArgPrefix = "build-arg:"
localNameContext = "context"
gitPrefix = "git://"
)
func main() {
@ -51,6 +53,11 @@ func run() error {
llb.IncludePatterns([]string{filename}),
llb.SessionID(c.SessionID()),
)
var buildContext *llb.State
if strings.HasPrefix(opts[localNameContext], gitPrefix) {
src = parseGitSource(opts[localNameContext])
buildContext = &src
}
def, err := src.Marshal()
if err != nil {
return err
@ -71,6 +78,7 @@ func run() error {
MetaResolver: c,
BuildArgs: filterBuildArgs(opts),
SessionID: c.SessionID(),
BuildContext: buildContext,
})
if err != nil {
@ -105,3 +113,13 @@ func filterBuildArgs(opt map[string]string) map[string]string {
}
return m
}
func parseGitSource(ref string) llb.State {
ref = strings.TrimPrefix(ref, gitPrefix)
parts := strings.SplitN(ref, "#", 2)
branch := ""
if len(parts) > 1 {
branch = parts[1]
}
return llb.Git(parts[0], branch)
}

View File

@ -24,6 +24,8 @@ const (
defaultDockerfileName = "Dockerfile"
localNameDockerfile = "dockerfile"
buildArgPrefix = "build-arg:"
localNameContext = "context"
gitPrefix = "git://"
)
func NewDockerfileFrontend() frontend.Frontend {
@ -33,7 +35,6 @@ func NewDockerfileFrontend() frontend.Frontend {
type dfFrontend struct{}
func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBridge, opts map[string]string) (retRef cache.ImmutableRef, exporterAttr map[string][]byte, retErr error) {
filename := opts[keyFilename]
if filename == "" {
filename = defaultDockerfileName
@ -48,6 +49,13 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
llb.IncludePatterns([]string{filename}),
llb.SessionID(sid),
)
var buildContext *llb.State
if strings.HasPrefix(opts[localNameContext], gitPrefix) {
src = parseGitSource(opts[localNameContext])
buildContext = &src
}
def, err := src.Marshal()
if err != nil {
return nil, nil, err
@ -104,6 +112,7 @@ func (f *dfFrontend) Solve(ctx context.Context, llbBridge frontend.FrontendLLBBr
MetaResolver: llbBridge,
BuildArgs: filterBuildArgs(opts),
SessionID: sid,
BuildContext: buildContext,
})
if err != nil {
@ -140,3 +149,13 @@ func filterBuildArgs(opt map[string]string) map[string]string {
}
return m
}
func parseGitSource(ref string) llb.State {
ref = strings.TrimPrefix(ref, gitPrefix)
parts := strings.SplitN(ref, "#", 2)
branch := ""
if len(parts) > 1 {
branch = parts[1]
}
return llb.Git(parts[0], branch)
}

View File

@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"path"
"path/filepath"
"strconv"
"strings"
@ -29,6 +30,7 @@ type ConvertOpt struct {
MetaResolver llb.ImageMetaResolver
BuildArgs map[string]string
SessionID string
BuildContext *llb.State
}
func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, *Image, error) {
@ -124,6 +126,11 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
return nil, nil, err
}
buildContext := llb.Local(localNameContext, llb.SessionID(opt.SessionID))
if opt.BuildContext != nil {
buildContext = *opt.BuildContext
}
for _, d := range allDispatchStates {
if d.base != nil {
d.state = d.base.state
@ -159,6 +166,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
buildArgValues: opt.BuildArgs,
shlex: shlex,
sessionID: opt.SessionID,
buildContext: buildContext,
}
if err = dispatchOnBuild(d, d.image.Config.OnBuild, opt); err != nil {
@ -190,6 +198,7 @@ type dispatchOpt struct {
buildArgValues map[string]string
shlex *ShellLex
sessionID string
buildContext llb.State
}
func dispatch(d *dispatchState, cmd instructions.Command, opt dispatchOpt) error {
@ -211,7 +220,7 @@ func dispatch(d *dispatchState, cmd instructions.Command, opt dispatchOpt) error
case *instructions.WorkdirCommand:
err = dispatchWorkdir(d, c)
case *instructions.AddCommand:
err = dispatchCopy(d, c.SourcesAndDest, llb.Local(localNameContext, llb.SessionID(opt.sessionID)))
err = dispatchCopy(d, c.SourcesAndDest, opt.buildContext)
case *instructions.LabelCommand:
err = dispatchLabel(d, c)
case *instructions.OnbuildCommand:
@ -235,7 +244,7 @@ func dispatch(d *dispatchState, cmd instructions.Command, opt dispatchOpt) error
case *instructions.ArgCommand:
err = dispatchArg(d, c, opt.metaArgs, opt.buildArgValues)
case *instructions.CopyCommand:
l := llb.Local(localNameContext, llb.SessionID(opt.sessionID))
l := opt.buildContext
if c.From != "" {
index, err := strconv.Atoi(c.From)
if err != nil {
@ -324,6 +333,9 @@ func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState l
img := llb.Image("tonistiigi/copy@sha256:260a4355be76e0609518ebd7c0e026831c80b8908d4afd3f8e8c942645b1e5cf")
dest := path.Join("/dest", pathRelativeToWorkingDir(d.state, c.Dest()))
if c.Dest() == "." || c.Dest()[len(c.Dest())-1] == filepath.Separator {
dest += string(filepath.Separator)
}
args := []string{"copy"}
mounts := make([]llb.RunOption, 0, len(c.Sources()))
for i, src := range c.Sources() {