Merge e16151f7c8 into 687feca9e8
This commit is contained in:
163
bake/bake.go
163
bake/bake.go
@@ -17,12 +17,8 @@ import (
|
||||
"github.com/docker/buildx/build"
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/docker/buildx/util/platformutil"
|
||||
|
||||
"github.com/docker/cli/cli/config"
|
||||
hcl "github.com/hashicorp/hcl/v2"
|
||||
"github.com/moby/buildkit/client/llb"
|
||||
"github.com/moby/buildkit/session/auth/authprovider"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
@@ -911,26 +907,26 @@ func (t *Target) GetName(ectx *hcl.EvalContext, block *hcl.Block, loadDeps func(
|
||||
return value.AsString(), nil
|
||||
}
|
||||
|
||||
func TargetsToBuildOpt(m map[string]*Target, inp *Input) (map[string]build.Options, error) {
|
||||
m2 := make(map[string]build.Options, len(m))
|
||||
func TargetsToControllerOptions(m map[string]*Target, inp *Input) (map[string]controllerapi.BuildOptions, error) {
|
||||
m2 := make(map[string]controllerapi.BuildOptions, len(m))
|
||||
for k, v := range m {
|
||||
bo, err := toBuildOpt(v, inp)
|
||||
opts, err := toControllerOpt(v, inp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m2[k] = *bo
|
||||
m2[k] = *opts
|
||||
}
|
||||
return m2, nil
|
||||
}
|
||||
|
||||
func updateContext(t *build.Inputs, inp *Input) {
|
||||
func updateContext(t *controllerapi.Inputs, inp *Input) error {
|
||||
if inp == nil || inp.State == nil {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
for k, v := range t.NamedContexts {
|
||||
if v.Path == "." {
|
||||
t.NamedContexts[k] = build.NamedContext{Path: inp.URL}
|
||||
t.NamedContexts[k] = &controllerapi.NamedContext{Path: inp.URL}
|
||||
}
|
||||
if strings.HasPrefix(v.Path, "cwd://") || strings.HasPrefix(v.Path, "target:") || strings.HasPrefix(v.Path, "docker-image:") {
|
||||
continue
|
||||
@@ -939,18 +935,22 @@ func updateContext(t *build.Inputs, inp *Input) {
|
||||
continue
|
||||
}
|
||||
st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/"), llb.WithCustomNamef("set context %s to %s", k, v.Path))
|
||||
t.NamedContexts[k] = build.NamedContext{State: &st}
|
||||
def, err := st.Marshal(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.NamedContexts[k] = &controllerapi.NamedContext{Definition: def.ToPB()}
|
||||
}
|
||||
|
||||
if t.ContextPath == "." {
|
||||
t.ContextPath = inp.URL
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if strings.HasPrefix(t.ContextPath, "cwd://") {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
if build.IsRemoteURL(t.ContextPath) {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
st := llb.Scratch().File(
|
||||
llb.Copy(*inp.State, t.ContextPath, "/", &llb.CopyInfo{
|
||||
@@ -958,13 +958,18 @@ func updateContext(t *build.Inputs, inp *Input) {
|
||||
}),
|
||||
llb.WithCustomNamef("set context to %s", t.ContextPath),
|
||||
)
|
||||
t.ContextState = &st
|
||||
def, err := st.Marshal(context.TODO())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.ContextDefinition = def.ToPB()
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateContextsEntitlements is a basic check to ensure contexts do not
|
||||
// escape local directories when loaded from remote sources. This is to be
|
||||
// replaced with proper entitlements support in the future.
|
||||
func validateContextsEntitlements(t build.Inputs, inp *Input) error {
|
||||
func validateContextsEntitlements(t controllerapi.Inputs, inp *Input) error {
|
||||
if inp == nil || inp.State == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -973,13 +978,13 @@ func validateContextsEntitlements(t build.Inputs, inp *Input) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if t.ContextState == nil {
|
||||
if t.ContextDefinition == nil {
|
||||
if err := checkPath(t.ContextPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, v := range t.NamedContexts {
|
||||
if v.State != nil {
|
||||
if v.Definition != nil {
|
||||
continue
|
||||
}
|
||||
if err := checkPath(v.Path); err != nil {
|
||||
@@ -1019,7 +1024,9 @@ func checkPath(p string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
|
||||
func toControllerOpt(t *Target, inp *Input) (*controllerapi.BuildOptions, error) {
|
||||
var err error
|
||||
|
||||
if v := t.Context; v != nil && *v == "-" {
|
||||
return nil, errors.Errorf("context from stdin not allowed in bake")
|
||||
}
|
||||
@@ -1039,24 +1046,24 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
|
||||
dockerfilePath = *t.Dockerfile
|
||||
}
|
||||
|
||||
bi := build.Inputs{
|
||||
bi := controllerapi.Inputs{
|
||||
ContextPath: contextPath,
|
||||
DockerfilePath: dockerfilePath,
|
||||
DockerfileName: dockerfilePath,
|
||||
NamedContexts: toNamedContexts(t.Contexts),
|
||||
}
|
||||
if t.DockerfileInline != nil {
|
||||
bi.DockerfileInline = *t.DockerfileInline
|
||||
}
|
||||
updateContext(&bi, inp)
|
||||
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextState == nil && !path.IsAbs(bi.DockerfilePath) {
|
||||
bi.DockerfilePath = path.Join(bi.ContextPath, bi.DockerfilePath)
|
||||
if !build.IsRemoteURL(bi.ContextPath) && bi.ContextDefinition == nil && !path.IsAbs(bi.DockerfileName) {
|
||||
bi.DockerfileName = path.Join(bi.ContextPath, bi.DockerfileName)
|
||||
}
|
||||
if strings.HasPrefix(bi.ContextPath, "cwd://") {
|
||||
bi.ContextPath = path.Clean(strings.TrimPrefix(bi.ContextPath, "cwd://"))
|
||||
}
|
||||
for k, v := range bi.NamedContexts {
|
||||
if strings.HasPrefix(v.Path, "cwd://") {
|
||||
bi.NamedContexts[k] = build.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))}
|
||||
bi.NamedContexts[k] = &controllerapi.NamedContext{Path: path.Clean(strings.TrimPrefix(v.Path, "cwd://"))}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1095,87 +1102,61 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) {
|
||||
networkMode = *t.NetworkMode
|
||||
}
|
||||
|
||||
bo := &build.Options{
|
||||
Inputs: bi,
|
||||
opts := &controllerapi.BuildOptions{
|
||||
Inputs: &bi,
|
||||
Opts: &controllerapi.CommonOptions{
|
||||
NoCache: noCache,
|
||||
Pull: pull,
|
||||
Linked: t.linked,
|
||||
},
|
||||
Tags: t.Tags,
|
||||
BuildArgs: args,
|
||||
Labels: labels,
|
||||
NoCache: noCache,
|
||||
NoCacheFilter: t.NoCacheFilter,
|
||||
Pull: pull,
|
||||
NetworkMode: networkMode,
|
||||
Linked: t.linked,
|
||||
Platforms: t.Platforms,
|
||||
}
|
||||
|
||||
platforms, err := platformutil.Parse(t.Platforms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.Platforms = platforms
|
||||
|
||||
dockerConfig := config.LoadDefaultConfigFile(os.Stderr)
|
||||
bo.Session = append(bo.Session, authprovider.NewDockerAuthProvider(dockerConfig))
|
||||
|
||||
secrets, err := buildflags.ParseSecretSpecs(t.Secrets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secretAttachment, err := controllerapi.CreateSecrets(secrets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.Session = append(bo.Session, secretAttachment)
|
||||
|
||||
sshSpecs, err := buildflags.ParseSSHSpecs(t.SSH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(sshSpecs) == 0 && (buildflags.IsGitSSH(bi.ContextPath) || (inp != nil && buildflags.IsGitSSH(inp.URL))) {
|
||||
sshSpecs = append(sshSpecs, &controllerapi.SSH{ID: "default"})
|
||||
}
|
||||
sshAttachment, err := controllerapi.CreateSSH(sshSpecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.Session = append(bo.Session, sshAttachment)
|
||||
|
||||
if t.Target != nil {
|
||||
bo.Target = *t.Target
|
||||
opts.Target = *t.Target
|
||||
}
|
||||
|
||||
cacheImports, err := buildflags.ParseCacheEntry(t.CacheFrom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.CacheFrom = controllerapi.CreateCaches(cacheImports)
|
||||
|
||||
cacheExports, err := buildflags.ParseCacheEntry(t.CacheTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.CacheTo = controllerapi.CreateCaches(cacheExports)
|
||||
|
||||
outputs, err := buildflags.ParseExports(t.Outputs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.Exports, err = controllerapi.CreateExports(outputs)
|
||||
opts.Secrets, err = buildflags.ParseSecretSpecs(t.Secrets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attests, err := buildflags.ParseAttests(t.Attest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bo.Attests = controllerapi.CreateAttestations(attests)
|
||||
|
||||
bo.SourcePolicy, err = build.ReadSourcePolicy()
|
||||
opts.SSH, err = buildflags.ParseSSHSpecs(t.SSH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return bo, nil
|
||||
opts.CacheFrom, err = buildflags.ParseCacheEntry(t.CacheFrom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts.CacheTo, err = buildflags.ParseCacheEntry(t.CacheTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts.Exports, err = buildflags.ParseExports(t.Outputs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts.Attests, err = buildflags.ParseAttests(t.Attest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opts.SourcePolicy, err = build.ReadSourcePolicy()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func defaultTarget() *Target {
|
||||
@@ -1264,10 +1245,10 @@ func sliceEqual(s1, s2 []string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func toNamedContexts(m map[string]string) map[string]build.NamedContext {
|
||||
m2 := make(map[string]build.NamedContext, len(m))
|
||||
func toNamedContexts(m map[string]string) map[string]*controllerapi.NamedContext {
|
||||
m2 := make(map[string]*controllerapi.NamedContext, len(m))
|
||||
for k, v := range m {
|
||||
m2[k] = build.NamedContext{Path: v}
|
||||
m2[k] = &controllerapi.NamedContext{Path: v}
|
||||
}
|
||||
return m2
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/controller/pb"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
@@ -390,7 +391,7 @@ func TestHCLCwdPrefix(t *testing.T) {
|
||||
_, ok := m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
_, err = TargetsToBuildOpt(m, &Input{})
|
||||
_, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "test", *m["app"].Dockerfile)
|
||||
@@ -421,7 +422,7 @@ func TestOverrideMerge(t *testing.T) {
|
||||
_, ok := m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
_, err = TargetsToBuildOpt(m, &Input{})
|
||||
_, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, []string{"linux/arm", "linux/ppc64le"}, m["app"].Platforms)
|
||||
@@ -456,7 +457,7 @@ func TestReadContexts(t *testing.T) {
|
||||
_, ok := m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
bo, err := TargetsToBuildOpt(m, &Input{})
|
||||
bo, err := TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ctxs := bo["app"].Inputs.NamedContexts
|
||||
@@ -472,7 +473,7 @@ func TestReadContexts(t *testing.T) {
|
||||
_, ok = m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
bo, err = TargetsToBuildOpt(m, &Input{})
|
||||
bo, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ctxs = bo["app"].Inputs.NamedContexts
|
||||
@@ -490,7 +491,7 @@ func TestReadContexts(t *testing.T) {
|
||||
_, ok = m["app"]
|
||||
require.True(t, ok)
|
||||
|
||||
bo, err = TargetsToBuildOpt(m, &Input{})
|
||||
bo, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
|
||||
ctxs = bo["app"].Inputs.NamedContexts
|
||||
@@ -1325,7 +1326,7 @@ func TestHCLNullVars(t *testing.T) {
|
||||
_, ok := m["default"]
|
||||
require.True(t, ok)
|
||||
|
||||
_, err = TargetsToBuildOpt(m, &Input{})
|
||||
_, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, m["default"].Args)
|
||||
require.Equal(t, map[string]*string{"com.docker.app.baz": ptrstr("foo")}, m["default"].Labels)
|
||||
@@ -1360,7 +1361,7 @@ func TestJSONNullVars(t *testing.T) {
|
||||
_, ok := m["default"]
|
||||
require.True(t, ok)
|
||||
|
||||
_, err = TargetsToBuildOpt(m, &Input{})
|
||||
_, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, m["default"].Args)
|
||||
}
|
||||
@@ -1432,21 +1433,34 @@ func TestAttestDuplicates(t *testing.T) {
|
||||
require.Equal(t, []string{"type=sbom,foo=bar", "type=provenance,mode=max"}, m["default"].Attest)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts, err := TargetsToBuildOpt(m, &Input{})
|
||||
opts, err := TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{
|
||||
"sbom": ptrstr("type=sbom,foo=bar"),
|
||||
"provenance": ptrstr("type=provenance,mode=max"),
|
||||
require.Equal(t, []*pb.Attest{
|
||||
{
|
||||
Type: "sbom",
|
||||
Attrs: "type=sbom,foo=bar",
|
||||
},
|
||||
{
|
||||
Type: "provenance",
|
||||
Attrs: "type=provenance,mode=max",
|
||||
},
|
||||
}, opts["default"].Attests)
|
||||
|
||||
m, _, err = ReadTargets(ctx, []File{fp}, []string{"default"}, []string{"*.attest=type=sbom,disabled=true"}, nil)
|
||||
require.Equal(t, []string{"type=sbom,disabled=true", "type=provenance,mode=max"}, m["default"].Attest)
|
||||
require.NoError(t, err)
|
||||
|
||||
opts, err = TargetsToBuildOpt(m, &Input{})
|
||||
opts, err = TargetsToControllerOptions(m, &Input{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, map[string]*string{
|
||||
"sbom": nil,
|
||||
"provenance": ptrstr("type=provenance,mode=max"),
|
||||
require.Equal(t, []*pb.Attest{
|
||||
{
|
||||
Type: "sbom",
|
||||
Disabled: true,
|
||||
Attrs: "type=sbom,disabled=true",
|
||||
},
|
||||
{
|
||||
Type: "provenance",
|
||||
Attrs: "type=provenance,mode=max",
|
||||
},
|
||||
}, opts["default"].Attests)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user