dockerfile: allow building dockerfiles from git

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-18.09
Tonis Tiigi 2017-11-06 16:25:46 -08:00
parent dfb786a292
commit a6b1e4e399
3 changed files with 49 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 {