Skip to content

Commit f2feea8

Browse files
authored
Merge pull request #1609 from crazy-max/0.10.3_cherry_picks
[v0.10] cherry-picks for v0.10.3
2 parents 00ed17d + a73d07f commit f2feea8

11 files changed

Lines changed: 135 additions & 95 deletions

File tree

bake/compose.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ func ParseCompose(cfgs []compose.ConfigFile, envs map[string]string) (*Config, e
7878
// compose does not support nil values for labels
7979
labels := map[string]*string{}
8080
for k, v := range s.Build.Labels {
81+
v := v
8182
labels[k] = &v
8283
}
8384

bake/hcl_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,24 @@ func TestJSONFunctions(t *testing.T) {
670670
require.Equal(t, ptrstr("pre-<FOO-abc>"), c.Targets[0].Args["v1"])
671671
}
672672

673+
func TestJSONInvalidFunctions(t *testing.T) {
674+
dt := []byte(`{
675+
"target": {
676+
"app": {
677+
"args": {
678+
"v1": "myfunc(\"foo\")"
679+
}
680+
}
681+
}}`)
682+
683+
c, err := ParseFile(dt, "docker-bake.json")
684+
require.NoError(t, err)
685+
686+
require.Equal(t, 1, len(c.Targets))
687+
require.Equal(t, c.Targets[0].Name, "app")
688+
require.Equal(t, ptrstr(`myfunc("foo")`), c.Targets[0].Args["v1"])
689+
}
690+
673691
func TestHCLFunctionInAttr(t *testing.T) {
674692
dt := []byte(`
675693
function "brace" {

bake/hclparser/expr.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,7 @@ func funcCalls(exp hcl.Expression) ([]string, hcl.Diagnostics) {
1414
if !ok {
1515
fns, err := jsonFuncCallsRecursive(exp)
1616
if err != nil {
17-
return nil, hcl.Diagnostics{
18-
&hcl.Diagnostic{
19-
Severity: hcl.DiagError,
20-
Summary: "Invalid expression",
21-
Detail: err.Error(),
22-
Subject: exp.Range().Ptr(),
23-
Context: exp.Range().Ptr(),
24-
},
25-
}
17+
return nil, wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
2618
}
2719
return fns, nil
2820
}

bake/hclparser/hclparser.go

Lines changed: 43 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,20 @@ type parser struct {
6262
doneB map[*hcl.Block]map[string]struct{}
6363
}
6464

65-
func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}) hcl.Diagnostics {
65+
var errUndefined = errors.New("undefined")
66+
67+
func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}, allowMissing bool) hcl.Diagnostics {
6668
fns, hcldiags := funcCalls(exp)
6769
if hcldiags.HasErrors() {
6870
return hcldiags
6971
}
7072

7173
for _, fn := range fns {
7274
if err := p.resolveFunction(fn); err != nil {
73-
return hcl.Diagnostics{
74-
&hcl.Diagnostic{
75-
Severity: hcl.DiagError,
76-
Summary: "Invalid expression",
77-
Detail: err.Error(),
78-
Subject: exp.Range().Ptr(),
79-
Context: exp.Range().Ptr(),
80-
},
75+
if allowMissing && errors.Is(err, errUndefined) {
76+
continue
8177
}
78+
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
8279
}
8380
}
8481

@@ -128,27 +125,17 @@ func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}) hcl.D
128125
}
129126
}
130127
if err := p.resolveBlock(blocks[0], target); err != nil {
131-
return hcl.Diagnostics{
132-
&hcl.Diagnostic{
133-
Severity: hcl.DiagError,
134-
Summary: "Invalid expression",
135-
Detail: err.Error(),
136-
Subject: v.SourceRange().Ptr(),
137-
Context: v.SourceRange().Ptr(),
138-
},
128+
if allowMissing && errors.Is(err, errUndefined) {
129+
continue
139130
}
131+
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
140132
}
141133
} else {
142134
if err := p.resolveValue(v.RootName()); err != nil {
143-
return hcl.Diagnostics{
144-
&hcl.Diagnostic{
145-
Severity: hcl.DiagError,
146-
Summary: "Invalid expression",
147-
Detail: err.Error(),
148-
Subject: v.SourceRange().Ptr(),
149-
Context: v.SourceRange().Ptr(),
150-
},
135+
if allowMissing && errors.Is(err, errUndefined) {
136+
continue
151137
}
138+
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
152139
}
153140
}
154141
}
@@ -167,7 +154,7 @@ func (p *parser) resolveFunction(name string) error {
167154
if _, ok := p.ectx.Functions[name]; ok {
168155
return nil
169156
}
170-
return errors.Errorf("undefined function %s", name)
157+
return errors.Wrapf(errUndefined, "function %q does not exit", name)
171158
}
172159
if _, ok := p.progressF[name]; ok {
173160
return errors.Errorf("function cycle not allowed for %s", name)
@@ -217,7 +204,7 @@ func (p *parser) resolveFunction(name string) error {
217204
return diags
218205
}
219206

220-
if diags := p.loadDeps(f.Result.Expr, params); diags.HasErrors() {
207+
if diags := p.loadDeps(f.Result.Expr, params, false); diags.HasErrors() {
221208
return diags
222209
}
223210

@@ -255,7 +242,7 @@ func (p *parser) resolveValue(name string) (err error) {
255242
if _, builtin := p.opt.Vars[name]; !ok && !builtin {
256243
vr, ok := p.vars[name]
257244
if !ok {
258-
return errors.Errorf("undefined variable %q", name)
245+
return errors.Wrapf(errUndefined, "variable %q does not exit", name)
259246
}
260247
def = vr.Default
261248
}
@@ -270,7 +257,7 @@ func (p *parser) resolveValue(name string) (err error) {
270257
return
271258
}
272259

273-
if diags := p.loadDeps(def.Expr, nil); diags.HasErrors() {
260+
if diags := p.loadDeps(def.Expr, nil, true); diags.HasErrors() {
274261
return diags
275262
}
276263
vv, diags := def.Expr.Value(p.ectx)
@@ -314,14 +301,7 @@ func (p *parser) resolveValue(name string) (err error) {
314301
func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err error) {
315302
name := block.Labels[0]
316303
if err := p.opt.ValidateLabel(name); err != nil {
317-
return hcl.Diagnostics{
318-
&hcl.Diagnostic{
319-
Severity: hcl.DiagError,
320-
Summary: "Invalid name",
321-
Detail: err.Error(),
322-
Subject: &block.LabelRanges[0],
323-
},
324-
}
304+
return wrapErrorDiagnostic("Invalid name", err, &block.LabelRanges[0], &block.LabelRanges[0])
325305
}
326306

327307
if _, ok := p.doneB[block]; !ok {
@@ -395,7 +375,7 @@ func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err err
395375
return diag
396376
}
397377
for _, a := range content.Attributes {
398-
diag := p.loadDeps(a.Expr, nil)
378+
diag := p.loadDeps(a.Expr, nil, true)
399379
if diag.HasErrors() {
400380
return diag
401381
}
@@ -573,15 +553,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
573553
return diags
574554
}
575555
r := p.vars[k].Body.MissingItemRange()
576-
return hcl.Diagnostics{
577-
&hcl.Diagnostic{
578-
Severity: hcl.DiagError,
579-
Summary: "Invalid value",
580-
Detail: err.Error(),
581-
Subject: &r,
582-
Context: &r,
583-
},
584-
}
556+
return wrapErrorDiagnostic("Invalid value", err, &r, &r)
585557
}
586558
}
587559

@@ -604,15 +576,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
604576
}
605577
}
606578
}
607-
return hcl.Diagnostics{
608-
&hcl.Diagnostic{
609-
Severity: hcl.DiagError,
610-
Summary: "Invalid function",
611-
Detail: err.Error(),
612-
Subject: subject,
613-
Context: context,
614-
},
615-
}
579+
return wrapErrorDiagnostic("Invalid function", err, subject, context)
616580
}
617581
}
618582

@@ -673,15 +637,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
673637
continue
674638
}
675639
} else {
676-
return hcl.Diagnostics{
677-
&hcl.Diagnostic{
678-
Severity: hcl.DiagError,
679-
Summary: "Invalid attribute",
680-
Detail: err.Error(),
681-
Subject: &b.LabelRanges[0],
682-
Context: &b.DefRange,
683-
},
684-
}
640+
return wrapErrorDiagnostic("Invalid block", err, &b.LabelRanges[0], &b.DefRange)
685641
}
686642
}
687643

@@ -726,21 +682,34 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
726682
if diags, ok := err.(hcl.Diagnostics); ok {
727683
return diags
728684
}
729-
return hcl.Diagnostics{
730-
&hcl.Diagnostic{
731-
Severity: hcl.DiagError,
732-
Summary: "Invalid attribute",
733-
Detail: err.Error(),
734-
Subject: &p.attrs[k].Range,
735-
Context: &p.attrs[k].Range,
736-
},
737-
}
685+
return wrapErrorDiagnostic("Invalid attribute", err, &p.attrs[k].Range, &p.attrs[k].Range)
738686
}
739687
}
740688

741689
return nil
742690
}
743691

692+
// wrapErrorDiagnostic wraps an error into a hcl.Diagnostics object.
693+
// If the error is already an hcl.Diagnostics object, it is returned as is.
694+
func wrapErrorDiagnostic(message string, err error, subject *hcl.Range, context *hcl.Range) hcl.Diagnostics {
695+
switch err := err.(type) {
696+
case *hcl.Diagnostic:
697+
return hcl.Diagnostics{err}
698+
case hcl.Diagnostics:
699+
return err
700+
default:
701+
return hcl.Diagnostics{
702+
&hcl.Diagnostic{
703+
Severity: hcl.DiagError,
704+
Summary: message,
705+
Detail: err.Error(),
706+
Subject: subject,
707+
Context: context,
708+
},
709+
}
710+
}
711+
}
712+
744713
func setLabel(v reflect.Value, lbl string) int {
745714
// cache field index?
746715
numFields := v.Elem().Type().NumField()

bake/remote.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, name
3434
var files []File
3535

3636
var node *builder.Node
37-
for _, n := range nodes {
37+
for i, n := range nodes {
3838
if n.Err == nil {
39-
node = &n
39+
node = &nodes[i]
4040
continue
4141
}
4242
}

build/git.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
6464
return res, nil
6565
}
6666

67-
if sha, err := gitc.FullCommit(); err != nil {
67+
if sha, err := gitc.FullCommit(); err != nil && !gitutil.IsUnknownRevision(err) {
6868
return res, errors.Wrapf(err, "buildx: failed to get git commit")
6969
} else if sha != "" {
7070
if gitc.IsDirty() {

docs/reference/buildx_build.md

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ BuildKit currently supports:
8888
Use `--attest=type=provenance` to generate provenance for an image at
8989
build-time. Alternatively, you can use the [`--provenance` shorthand](#provenance).
9090

91+
By default, a minimal provenance attestation will be created for the build
92+
result, which will only be attached for images pushed to registries.
93+
9194
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
9295

9396
### <a name="allow"></a> Allow extra privileged entitlement (--allow)
@@ -477,8 +480,20 @@ $ docker buildx build --load --progress=plain .
477480
478481
### <a name="provenance"></a> Create provenance attestations (--provenance)
479482

480-
Shorthand for [`--attest=type=provenance`](#attest). Enables provenance
481-
attestations for the build result.
483+
Shorthand for [`--attest=type=provenance`](#attest), used to configure
484+
provenance attestations for the build result. For example,
485+
`--provenance=mode=max` can be used as an abbreviation for
486+
`--attest=type=provenance,mode=max`.
487+
488+
Additionally, `--provenance` can be used with boolean values to broadly enable
489+
or disable provenance attestations. For example, `--provenance=false` can be
490+
used to disable all provenance attestations, while `--provenance=true` can be
491+
used to enable all provenance attestations.
492+
493+
By default, a minimal provenance attestation will be created for the build
494+
result, which will only be attached for images pushed to registries.
495+
496+
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
482497

483498
### <a name="push"></a> Push the build result to a registry (--push)
484499

@@ -487,8 +502,16 @@ build result to registry.
487502

488503
### <a name="sbom"></a> Create SBOM attestations (--sbom)
489504

490-
Shorthand for [`--attest=type=sbom`](#attest). Enables SBOM attestations for
491-
the build result.
505+
Shorthand for [`--attest=type=sbom`](#attest), used to configure SBOM
506+
attestations for the build result. For example,
507+
`--sbom=generator=<user>/<generator-image>` can be used as an abbreviation for
508+
`--attest=type=sbom,generator=<user>/<generator-image>`.
509+
510+
Additionally, `--sbom` can be used with boolean values to broadly enable or
511+
disable SBOM attestations. For example, `--sbom=false` can be used to disable
512+
all SBOM attestations.
513+
514+
For more information, see [here](https://docs.docker.com/build/attestations/sbom/).
492515

493516
### <a name="secret"></a> Secret to expose to the build (--secret)
494517

store/storeutil/storeutil.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ func GetNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.No
9393
Endpoint: name,
9494
},
9595
},
96+
DockerContext: true,
9697
}
9798
if ng.LastActivity, err = txn.GetLastActivity(ng); err != nil {
9899
return nil, err

util/gitutil/gitutil.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package gitutil
33
import (
44
"bytes"
55
"context"
6+
"os"
67
"os/exec"
78
"strings"
89

@@ -116,6 +117,9 @@ func (c *Git) run(args ...string) (string, error) {
116117
cmd.Dir = c.wd
117118
}
118119

120+
// Override the locale to ensure consistent output
121+
cmd.Env = append(os.Environ(), "LC_ALL=C")
122+
119123
stdout := bytes.Buffer{}
120124
stderr := bytes.Buffer{}
121125
cmd.Stdout = &stdout
@@ -134,3 +138,12 @@ func (c *Git) clean(out string, err error) (string, error) {
134138
}
135139
return out, err
136140
}
141+
142+
func IsUnknownRevision(err error) bool {
143+
if err == nil {
144+
return false
145+
}
146+
// https://github.com/git/git/blob/a6a323b31e2bcbac2518bddec71ea7ad558870eb/setup.c#L204
147+
errMsg := strings.ToLower(err.Error())
148+
return strings.Contains(errMsg, "unknown revision or path not in the working tree") || strings.Contains(errMsg, "bad revision")
149+
}

0 commit comments

Comments
 (0)