bake: local dockerfile support for remote definition

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
pull/2015/head
CrazyMax 1 year ago
parent 296832c90e
commit 2c9c05c42f
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7

@ -18,7 +18,6 @@ import (
controllerapi "github.com/docker/buildx/controller/pb" controllerapi "github.com/docker/buildx/controller/pb"
"github.com/docker/buildx/util/buildflags" "github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/platformutil" "github.com/docker/buildx/util/platformutil"
"github.com/docker/cli/cli/config" "github.com/docker/cli/cli/config"
hcl "github.com/hashicorp/hcl/v2" hcl "github.com/hashicorp/hcl/v2"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
@ -1038,6 +1037,9 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
if t.Dockerfile != nil { if t.Dockerfile != nil {
dockerfilePath = *t.Dockerfile dockerfilePath = *t.Dockerfile
} }
if !strings.HasPrefix(dockerfilePath, "cwd://") {
dockerfilePath = path.Clean(dockerfilePath)
}
bi := build.Inputs{ bi := build.Inputs{
ContextPath: contextPath, ContextPath: contextPath,
@ -1048,6 +1050,17 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
bi.DockerfileInline = *t.DockerfileInline bi.DockerfileInline = *t.DockerfileInline
} }
updateContext(&bi, inp) updateContext(&bi, inp)
if strings.HasPrefix(bi.DockerfilePath, "cwd://") {
bi.DockerfilePath = path.Clean(strings.TrimPrefix(bi.DockerfilePath, "cwd://"))
if err := checkPath(bi.DockerfilePath); err != nil {
return nil, err
}
var err error
bi.DockerfilePath, err = filepath.Abs(bi.DockerfilePath)
if err != nil {
return nil, err
}
}
if strings.HasPrefix(bi.ContextPath, "cwd://") { if strings.HasPrefix(bi.ContextPath, "cwd://") {
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://")) bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
} }

@ -3,10 +3,12 @@ package bake
import ( import (
"context" "context"
"os" "os"
"path/filepath"
"sort" "sort"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -379,7 +381,7 @@ services:
require.Equal(t, []string{"web_app"}, g["default"].Targets) require.Equal(t, []string{"web_app"}, g["default"].Targets)
} }
func TestHCLCwdPrefix(t *testing.T) { func TestHCLContextCwdPrefix(t *testing.T) {
fp := File{ fp := File{
Name: "docker-bake.hcl", Name: "docker-bake.hcl",
Data: []byte( Data: []byte(
@ -400,11 +402,41 @@ func TestHCLCwdPrefix(t *testing.T) {
require.Equal(t, 1, len(m)) require.Equal(t, 1, len(m))
require.Contains(t, m, "app") require.Contains(t, m, "app")
require.Equal(t, "test", *m["app"].Dockerfile) assert.Equal(t, "test", *m["app"].Dockerfile)
require.Equal(t, "foo", *m["app"].Context) assert.Equal(t, "foo", *m["app"].Context)
assert.Equal(t, "foo/test", bo["app"].Inputs.DockerfilePath)
assert.Equal(t, "foo", bo["app"].Inputs.ContextPath)
}
func TestHCLDockerfileCwdPrefix(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "app" {
context = "."
dockerfile = "cwd://Dockerfile.app"
}`),
}
ctx := context.TODO()
cwd, err := os.Getwd()
require.NoError(t, err)
require.Equal(t, "foo/test", bo["app"].Inputs.DockerfilePath) m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil)
require.Equal(t, "foo", bo["app"].Inputs.ContextPath) require.NoError(t, err)
bo, err := TargetsToBuildOpt(m, &Input{})
require.NoError(t, err)
require.Equal(t, 1, len(g))
require.Equal(t, []string{"app"}, g["default"].Targets)
require.Equal(t, 1, len(m))
require.Contains(t, m, "app")
assert.Equal(t, "cwd://Dockerfile.app", *m["app"].Dockerfile)
assert.Equal(t, ".", *m["app"].Context)
assert.Equal(t, filepath.Join(cwd, "Dockerfile.app"), bo["app"].Inputs.DockerfilePath)
assert.Equal(t, ".", bo["app"].Inputs.ContextPath)
} }
func TestOverrideMerge(t *testing.T) { func TestOverrideMerge(t *testing.T) {

@ -1328,6 +1328,10 @@ func LoadInputs(ctx context.Context, d *driver.DriverHandle, inp Inputs, pw prog
case IsRemoteURL(inp.ContextPath): case IsRemoteURL(inp.ContextPath):
if inp.DockerfilePath == "-" { if inp.DockerfilePath == "-" {
dockerfileReader = inp.InStream dockerfileReader = inp.InStream
} else if filepath.IsAbs(inp.DockerfilePath) {
dockerfileDir = filepath.Dir(inp.DockerfilePath)
dockerfileName = filepath.Base(inp.DockerfilePath)
target.FrontendAttrs["dockerfilekey"] = "dockerfile"
} }
target.FrontendAttrs["context"] = inp.ContextPath target.FrontendAttrs["context"] = inp.ContextPath
default: default:

@ -1,6 +1,7 @@
package tests package tests
import ( import (
"os"
"path/filepath" "path/filepath"
"testing" "testing"
@ -25,6 +26,7 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeRemoteContextSubdir, testBakeRemoteContextSubdir,
testBakeRemoteCmdContextEscapeRoot, testBakeRemoteCmdContextEscapeRoot,
testBakeRemoteCmdContextEscapeRelative, testBakeRemoteCmdContextEscapeRelative,
testBakeRemoteDockerfileCwd,
} }
func testBakeLocal(t *testing.T, sb integration.Sandbox) { func testBakeLocal(t *testing.T, sb integration.Sandbox) {
@ -287,3 +289,62 @@ EOT
require.NoError(t, err, out) require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "foo")) require.FileExists(t, filepath.Join(dirDest, "foo"))
} }
func testBakeRemoteDockerfileCwd(t *testing.T, sb integration.Sandbox) {
bakefile := []byte(`
target "default" {
context = "."
dockerfile = "cwd://Dockerfile.app"
}
`)
dockerfile := []byte(`
FROM scratch
COPY bar /bar
`)
dockerfileApp := []byte(`
FROM scratch
COPY foo /foo
`)
dirSpec := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateFile("Dockerfile", dockerfile, 0600),
fstest.CreateFile("foo", []byte("foo"), 0600),
fstest.CreateFile("bar", []byte("bar"), 0600),
)
dirSrc := tmpdir(
t,
fstest.CreateFile("Dockerfile.app", dockerfileApp, 0600),
)
dirDest := t.TempDir()
git, err := gitutil.New(gitutil.WithWorkingDir(dirSpec))
require.NoError(t, err)
gitutil.GitInit(git, t)
gitutil.GitAdd(git, t, "docker-bake.hcl")
gitutil.GitAdd(git, t, "Dockerfile")
gitutil.GitAdd(git, t, "foo")
gitutil.GitAdd(git, t, "bar")
gitutil.GitCommit(git, t, "initial commit")
addr := gitutil.GitServeHTTP(git, t)
out, err := bakeCmd(
sb,
withDir(dirSrc),
withArgs(addr, "--set", "*.output=type=local,dest="+dirDest),
)
require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "foo"))
err = os.Remove(filepath.Join(dirSrc, "Dockerfile.app"))
require.NoError(t, err)
out, err = bakeCmd(
sb,
withDir(dirSrc),
withArgs(addr, "--set", "*.output=type=cacheonly"),
)
require.Error(t, err, out)
}

Loading…
Cancel
Save