mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-08-18 01:35:54 +08:00
Compare commits
20 Commits
v0.20.0-rc
...
v0.20.1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
245093b99a | ||
![]() |
e2ed15f0c9 | ||
![]() |
fd442f8e10 | ||
![]() |
1002e6fb42 | ||
![]() |
d5ad869033 | ||
![]() |
bd7090b981 | ||
![]() |
24f3a1df80 | ||
![]() |
8e30c4669c | ||
![]() |
cf74356afc | ||
![]() |
c1d3955fbe | ||
![]() |
d0b63e60e2 | ||
![]() |
e141c8fa71 | ||
![]() |
2ee156236b | ||
![]() |
1335264c9d | ||
![]() |
e74185aa6d | ||
![]() |
0224773102 | ||
![]() |
8c27b5c545 | ||
![]() |
f7594d484b | ||
![]() |
f118749cdc | ||
![]() |
0d92ad713c |
5
.github/labeler.yml
vendored
5
.github/labeler.yml
vendored
@@ -96,6 +96,11 @@ area/hack:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'hack/**'
|
||||
|
||||
# Add 'area/history' label to changes in history command
|
||||
area/history:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: 'commands/history/**'
|
||||
|
||||
# Add 'area/tests' label to changes in test files
|
||||
area/tests:
|
||||
- changed-files:
|
||||
|
2
.github/workflows/docs-upstream.yml
vendored
2
.github/workflows/docs-upstream.yml
vendored
@@ -65,7 +65,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
validate:
|
||||
uses: docker/docs/.github/workflows/validate-upstream.yml@6b73b05acb21edf7995cc5b3c6672d8e314cee7a # pin for artifact v4 support: https://github.com/docker/docs/pull/19220
|
||||
uses: docker/docs/.github/workflows/validate-upstream.yml@main
|
||||
needs:
|
||||
- docs-yaml
|
||||
with:
|
||||
|
43
bake/bake.go
43
bake/bake.go
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/moby/buildkit/session/auth/authprovider"
|
||||
"github.com/moby/buildkit/util/entitlements"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tonistiigi/go-csvvalue"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/convert"
|
||||
)
|
||||
@@ -556,6 +555,8 @@ func (c Config) newOverrides(v []string) (map[string]map[string]Override, error)
|
||||
|
||||
o := t[kk[1]]
|
||||
|
||||
// IMPORTANT: if you add more fields here, do not forget to update
|
||||
// docs/bake-reference.md and https://docs.docker.com/build/bake/overrides/
|
||||
switch keys[1] {
|
||||
case "output", "cache-to", "cache-from", "tags", "platform", "secrets", "ssh", "attest", "entitlements", "network":
|
||||
if len(parts) == 2 {
|
||||
@@ -861,6 +862,8 @@ func (t *Target) Merge(t2 *Target) {
|
||||
}
|
||||
|
||||
func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementConf) error {
|
||||
// IMPORTANT: if you add more fields here, do not forget to update
|
||||
// docs/bake-reference.md and https://docs.docker.com/build/bake/overrides/
|
||||
for key, o := range overrides {
|
||||
value := o.Value
|
||||
keys := strings.SplitN(key, ".", 2)
|
||||
@@ -896,7 +899,7 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
case "tags":
|
||||
t.Tags = o.ArrValue
|
||||
case "cache-from":
|
||||
cacheFrom, err := parseCacheArrValues(o.ArrValue)
|
||||
cacheFrom, err := buildflags.ParseCacheEntry(o.ArrValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -909,7 +912,7 @@ func (t *Target) AddOverrides(overrides map[string]Override, ent *EntitlementCon
|
||||
}
|
||||
}
|
||||
case "cache-to":
|
||||
cacheTo, err := parseCacheArrValues(o.ArrValue)
|
||||
cacheTo, err := buildflags.ParseCacheEntry(o.ArrValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1581,37 +1584,3 @@ func parseArrValue[T any, PT arrValue[T]](s []string) ([]*T, error) {
|
||||
}
|
||||
return outputs, nil
|
||||
}
|
||||
|
||||
func parseCacheArrValues(s []string) (buildflags.CacheOptions, error) {
|
||||
var outs buildflags.CacheOptions
|
||||
for _, in := range s {
|
||||
if in == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.Contains(in, "=") {
|
||||
// This is ref only format. Each field in the CSV is its own entry.
|
||||
fields, err := csvvalue.Fields(in, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
out := buildflags.CacheOptionsEntry{}
|
||||
if err := out.UnmarshalText([]byte(field)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outs = append(outs, &out)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Normal entry.
|
||||
out := buildflags.CacheOptionsEntry{}
|
||||
if err := out.UnmarshalText([]byte(in)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
outs = append(outs, &out)
|
||||
}
|
||||
return outs, nil
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/util/buildflags"
|
||||
"github.com/moby/buildkit/util/entitlements"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -1759,6 +1760,27 @@ func TestAnnotations(t *testing.T) {
|
||||
require.Equal(t, "bar", bo["app"].Exports[0].Attrs["annotation-manifest[linux/amd64].foo"])
|
||||
}
|
||||
|
||||
func TestRefOnlyCacheOptions(t *testing.T) {
|
||||
fp := File{
|
||||
Name: "docker-bake.hcl",
|
||||
Data: []byte(
|
||||
`target "app" {
|
||||
output = ["type=image,name=foo"]
|
||||
cache-from = ["ref1,ref2"]
|
||||
}`),
|
||||
}
|
||||
ctx := context.TODO()
|
||||
m, _, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil, &EntitlementConf{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, m, 1)
|
||||
require.Contains(t, m, "app")
|
||||
require.Equal(t, buildflags.CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "ref1"}},
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "ref2"}},
|
||||
}, m["app"].CacheFrom)
|
||||
}
|
||||
|
||||
func TestHCLEntitlements(t *testing.T) {
|
||||
fp := File{
|
||||
Name: "docker-bake.hcl",
|
||||
|
@@ -145,12 +145,12 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
|
||||
labels[k] = &v
|
||||
}
|
||||
|
||||
cacheFrom, err := parseCacheArrValues(s.Build.CacheFrom)
|
||||
cacheFrom, err := buildflags.ParseCacheEntry(s.Build.CacheFrom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cacheTo, err := parseCacheArrValues(s.Build.CacheTo)
|
||||
cacheTo, err := buildflags.ParseCacheEntry(s.Build.CacheTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -349,14 +349,14 @@ func (t *Target) composeExtTarget(exts map[string]interface{}) error {
|
||||
t.Tags = dedupSlice(append(t.Tags, xb.Tags...))
|
||||
}
|
||||
if len(xb.CacheFrom) > 0 {
|
||||
cacheFrom, err := parseCacheArrValues(xb.CacheFrom)
|
||||
cacheFrom, err := buildflags.ParseCacheEntry(xb.CacheFrom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.CacheFrom = t.CacheFrom.Merge(cacheFrom)
|
||||
}
|
||||
if len(xb.CacheTo) > 0 {
|
||||
cacheTo, err := parseCacheArrValues(xb.CacheTo)
|
||||
cacheTo, err := buildflags.ParseCacheEntry(xb.CacheTo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -183,14 +183,17 @@ func (o *buildOptions) toControllerOptions() (*controllerapi.BuildOptions, error
|
||||
}
|
||||
}
|
||||
|
||||
opts.CacheFrom, err = buildflags.ParseCacheEntry(o.cacheFrom)
|
||||
cacheFrom, err := buildflags.ParseCacheEntry(o.cacheFrom)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts.CacheTo, err = buildflags.ParseCacheEntry(o.cacheTo)
|
||||
opts.CacheFrom = cacheFrom.ToPB()
|
||||
|
||||
cacheTo, err := buildflags.ParseCacheEntry(o.cacheTo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts.CacheTo = cacheTo.ToPB()
|
||||
|
||||
opts.Secrets, err = buildflags.ParseSecretSpecs(o.secrets)
|
||||
if err != nil {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package history
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/json"
|
||||
@@ -24,16 +25,24 @@ import (
|
||||
"github.com/docker/buildx/util/confutil"
|
||||
"github.com/docker/buildx/util/desktop"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/debug"
|
||||
slsa "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
|
||||
slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
|
||||
controlapi "github.com/moby/buildkit/api/services/control"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/moby/buildkit/solver/errdefs"
|
||||
provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
|
||||
"github.com/moby/buildkit/util/grpcerrors"
|
||||
"github.com/moby/buildkit/util/stack"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tonistiigi/go-csvvalue"
|
||||
spb "google.golang.org/genproto/googleapis/rpc/status"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
proto "google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type inspectOptions struct {
|
||||
@@ -184,16 +193,16 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
|
||||
|
||||
tw = tabwriter.NewWriter(dockerCli.Out(), 1, 8, 1, '\t', 0)
|
||||
|
||||
fmt.Fprintf(tw, "Started:\t%s\n", rec.CreatedAt.AsTime().Format("2006-01-02 15:04:05"))
|
||||
fmt.Fprintf(tw, "Started:\t%s\n", rec.CreatedAt.AsTime().Local().Format("2006-01-02 15:04:05"))
|
||||
var duration time.Duration
|
||||
var status string
|
||||
var statusStr string
|
||||
if rec.CompletedAt != nil {
|
||||
duration = rec.CompletedAt.AsTime().Sub(rec.CreatedAt.AsTime())
|
||||
} else {
|
||||
duration = rec.currentTimestamp.Sub(rec.CreatedAt.AsTime())
|
||||
status = " (running)"
|
||||
statusStr = " (running)"
|
||||
}
|
||||
fmt.Fprintf(tw, "Duration:\t%s%s\n", formatDuration(duration), status)
|
||||
fmt.Fprintf(tw, "Duration:\t%s%s\n", formatDuration(duration), statusStr)
|
||||
if rec.Error != nil {
|
||||
if codes.Code(rec.Error.Code) == codes.Canceled {
|
||||
fmt.Fprintf(tw, "Status:\tCanceled\n")
|
||||
@@ -309,9 +318,51 @@ func runInspect(ctx context.Context, dockerCli command.Cli, opts inspectOptions)
|
||||
fmt.Fprintln(dockerCli.Out())
|
||||
}
|
||||
|
||||
if rec.ExternalError != nil {
|
||||
dt, err := content.ReadBlob(ctx, store, ociDesc(rec.ExternalError))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read external error %s", rec.ExternalError.Digest)
|
||||
}
|
||||
var st spb.Status
|
||||
if err := proto.Unmarshal(dt, &st); err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal external error %s", rec.ExternalError.Digest)
|
||||
}
|
||||
retErr := grpcerrors.FromGRPC(status.ErrorProto(&st))
|
||||
for _, s := range errdefs.Sources(retErr) {
|
||||
s.Print(dockerCli.Out())
|
||||
}
|
||||
fmt.Fprintln(dockerCli.Out())
|
||||
|
||||
var ve *errdefs.VertexError
|
||||
if errors.As(retErr, &ve) {
|
||||
dgst, err := digest.Parse(ve.Vertex.Digest)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to parse vertex digest %s", ve.Vertex.Digest)
|
||||
}
|
||||
name, logs, err := loadVertexLogs(ctx, c, rec.Ref, dgst, 16)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to load vertex logs %s", dgst)
|
||||
}
|
||||
if len(logs) > 0 {
|
||||
fmt.Fprintln(dockerCli.Out(), "Logs:")
|
||||
fmt.Fprintf(dockerCli.Out(), "> => %s:\n", name)
|
||||
for _, l := range logs {
|
||||
fmt.Fprintln(dockerCli.Out(), "> "+l)
|
||||
}
|
||||
fmt.Fprintln(dockerCli.Out())
|
||||
}
|
||||
}
|
||||
|
||||
if debug.IsEnabled() {
|
||||
fmt.Fprintf(dockerCli.Out(), "\n%+v\n", stack.Formatter(retErr))
|
||||
} else if len(stack.Traces(retErr)) > 0 {
|
||||
fmt.Fprintf(dockerCli.Out(), "Enable --debug to see stack traces for error\n")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(dockerCli.Out(), "Print build logs: docker buildx history logs %s\n", rec.Ref)
|
||||
|
||||
fmt.Fprintf(dockerCli.Out(), "View build in Docker Desktop: %s\n", desktop.BuildURL(rec.Ref))
|
||||
fmt.Fprintf(dockerCli.Out(), "View build in Docker Desktop: %s\n", desktop.BuildURL(fmt.Sprintf("%s/%s/%s", rec.node.Builder, rec.node.Name, rec.Ref)))
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -342,6 +393,73 @@ func inspectCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func loadVertexLogs(ctx context.Context, c *client.Client, ref string, dgst digest.Digest, limit int) (string, []string, error) {
|
||||
st, err := c.ControlClient().Status(ctx, &controlapi.StatusRequest{
|
||||
Ref: ref,
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
var name string
|
||||
var logs []string
|
||||
lastState := map[int]int{}
|
||||
|
||||
loop0:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
st.CloseSend()
|
||||
return "", nil, context.Cause(ctx)
|
||||
default:
|
||||
ev, err := st.Recv()
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
break loop0
|
||||
}
|
||||
return "", nil, err
|
||||
}
|
||||
ss := client.NewSolveStatus(ev)
|
||||
for _, v := range ss.Vertexes {
|
||||
if v.Digest == dgst {
|
||||
name = v.Name
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, l := range ss.Logs {
|
||||
if l.Vertex == dgst {
|
||||
parts := bytes.Split(l.Data, []byte("\n"))
|
||||
for i, p := range parts {
|
||||
var wrote bool
|
||||
if i == 0 {
|
||||
idx, ok := lastState[l.Stream]
|
||||
if ok && idx != -1 {
|
||||
logs[idx] = logs[idx] + string(p)
|
||||
wrote = true
|
||||
}
|
||||
}
|
||||
if !wrote {
|
||||
if len(p) > 0 {
|
||||
logs = append(logs, string(p))
|
||||
}
|
||||
lastState[l.Stream] = len(logs) - 1
|
||||
}
|
||||
if i == len(parts)-1 && len(p) == 0 {
|
||||
lastState[l.Stream] = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if limit > 0 && len(logs) > limit {
|
||||
logs = logs[len(logs)-limit:]
|
||||
}
|
||||
|
||||
return name, logs, nil
|
||||
}
|
||||
|
||||
type attachment struct {
|
||||
platform *ocispecs.Platform
|
||||
descr ocispecs.Descriptor
|
||||
|
@@ -221,8 +221,10 @@ The following table shows the complete list of attributes that you can assign to
|
||||
| [`attest`](#targetattest) | List | Build attestations |
|
||||
| [`cache-from`](#targetcache-from) | List | External cache sources |
|
||||
| [`cache-to`](#targetcache-to) | List | External cache destinations |
|
||||
| [`call`](#targetcall) | String | Specify the frontend method to call for the target. |
|
||||
| [`context`](#targetcontext) | String | Set of files located in the specified path or URL |
|
||||
| [`contexts`](#targetcontexts) | Map | Additional build contexts |
|
||||
| [`description`](#targetdescription) | String | Description of a target |
|
||||
| [`dockerfile-inline`](#targetdockerfile-inline) | String | Inline Dockerfile string |
|
||||
| [`dockerfile`](#targetdockerfile) | String | Dockerfile location |
|
||||
| [`inherits`](#targetinherits) | List | Inherit attributes from other targets |
|
||||
@@ -371,6 +373,13 @@ target "app" {
|
||||
}
|
||||
```
|
||||
|
||||
Supported values are:
|
||||
|
||||
- `build` builds the target (default)
|
||||
- `check`: evaluates [build checks](https://docs.docker.com/build/checks/) for the target
|
||||
- `outline`: displays the target's build arguments and their default values if available
|
||||
- `targets`: lists all Bake targets in the loaded definition, along with its [description](#targetdescription).
|
||||
|
||||
For more information about frontend methods, refer to the CLI reference for
|
||||
[`docker buildx build --call`](https://docs.docker.com/reference/cli/docker/buildx/build/#call).
|
||||
|
||||
@@ -481,6 +490,25 @@ FROM baseapp
|
||||
RUN echo "Hello world"
|
||||
```
|
||||
|
||||
### `target.description`
|
||||
|
||||
Defines a human-readable description for the target, clarifying its purpose or
|
||||
functionality.
|
||||
|
||||
```hcl
|
||||
target "lint" {
|
||||
description = "Runs golangci-lint to detect style errors"
|
||||
args = {
|
||||
GOLANGCI_LINT_VERSION = null
|
||||
}
|
||||
dockerfile = "lint.Dockerfile"
|
||||
}
|
||||
```
|
||||
|
||||
This attribute is useful when combined with the `docker buildx bake --list=targets`
|
||||
option, providing a more informative output when listing the available build
|
||||
targets in a Bake file.
|
||||
|
||||
### `target.dockerfile-inline`
|
||||
|
||||
Uses the string value as an inline Dockerfile for the build target.
|
||||
|
@@ -15,7 +15,7 @@ Build from a file
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------------------|:--------------|:--------|:-------------------------------------------------------------------------------------------------------------|
|
||||
| `--allow` | `stringArray` | | Allow build to access specified resources |
|
||||
| [`--allow`](#allow) | `stringArray` | | Allow build to access specified resources |
|
||||
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
|
||||
| [`--call`](#call) | `string` | `build` | Set method for evaluating build (`check`, `outline`, `targets`) |
|
||||
| [`--check`](#check) | `bool` | | Shorthand for `--call=check` |
|
||||
@@ -51,6 +51,80 @@ guide for introduction to writing bake files.
|
||||
|
||||
## Examples
|
||||
|
||||
### <a name="allow"></a> Allow extra privileged entitlement (--allow)
|
||||
|
||||
```text
|
||||
--allow=ENTITLEMENT[=VALUE]
|
||||
```
|
||||
|
||||
Entitlements are designed to provide controlled access to privileged
|
||||
operations. By default, Buildx and BuildKit operates with restricted
|
||||
permissions to protect users and their systems from unintended side effects or
|
||||
security risks. The `--allow` flag explicitly grants access to additional
|
||||
entitlements, making it clear when a build or bake operation requires elevated
|
||||
privileges.
|
||||
|
||||
In addition to BuildKit's `network.host` and `security.insecure` entitlements
|
||||
(see [`docker buildx build --allow`](https://docs.docker.com/reference/cli/docker/buildx/build/#allow),
|
||||
Bake supports file system entitlements that grant granular control over file
|
||||
system access. These are particularly useful when working with builds that need
|
||||
access to files outside the default working directory.
|
||||
|
||||
Bake supports the following filesystem entitlements:
|
||||
|
||||
- `--allow fs=<path|*>` - Grant read and write access to files outside of the
|
||||
working directory.
|
||||
- `--allow fs.read=<path|*>` - Grant read access to files outside of the
|
||||
working directory.
|
||||
- `--allow fs.write=<path|*>` - Grant write access to files outside of the
|
||||
working directory.
|
||||
|
||||
The `fs` entitlements take a path value (relative or absolute) to a directory
|
||||
on the filesystem. Alternatively, you can pass a wildcard (`*`) to allow Bake
|
||||
to access the entire filesystem.
|
||||
|
||||
### Example: fs.read
|
||||
|
||||
Given the following Bake configuration, Bake would need to access the parent
|
||||
directory, relative to the Bake file.
|
||||
|
||||
```hcl
|
||||
target "app" {
|
||||
context = "../src"
|
||||
}
|
||||
```
|
||||
|
||||
Assuming `docker buildx bake app` is executed in the same directory as the
|
||||
`docker-bake.hcl` file, you would need to explicitly allow Bake to read from
|
||||
the `../src` directory. In this case, the following invocations all work:
|
||||
|
||||
```console
|
||||
$ docker buildx bake --allow fs.read=* app
|
||||
$ docker buildx bake --allow fs.read=../src app
|
||||
$ docker buildx bake --allow fs=* app
|
||||
```
|
||||
|
||||
### Example: fs.write
|
||||
|
||||
The following `docker-bake.hcl` file requires write access to the `/tmp`
|
||||
directory.
|
||||
|
||||
```hcl
|
||||
target "app" {
|
||||
output = "/tmp"
|
||||
}
|
||||
```
|
||||
|
||||
Assuming `docker buildx bake app` is executed outside of the `/tmp` directory,
|
||||
you would need to allow the `fs.write` entitlement, either by specifying the
|
||||
path or using a wildcard:
|
||||
|
||||
```console
|
||||
$ docker buildx bake --allow fs=/tmp app
|
||||
$ docker buildx bake --allow fs.write=/tmp app
|
||||
$ docker buildx bake --allow fs.write=* app
|
||||
```
|
||||
|
||||
### <a name="builder"></a> Override the configured builder instance (--builder)
|
||||
|
||||
Same as [`buildx --builder`](buildx.md#builder).
|
||||
|
4
go.mod
4
go.mod
@@ -29,7 +29,7 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.23.0
|
||||
github.com/in-toto/in-toto-golang v0.5.0
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/moby/buildkit v0.19.0-rc2
|
||||
github.com/moby/buildkit v0.19.0
|
||||
github.com/moby/sys/mountinfo v0.7.2
|
||||
github.com/moby/sys/signal v0.7.1
|
||||
github.com/morikuni/aec v1.0.0
|
||||
@@ -57,6 +57,7 @@ require (
|
||||
golang.org/x/sys v0.28.0
|
||||
golang.org/x/term v0.27.0
|
||||
golang.org/x/text v0.21.0
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38
|
||||
google.golang.org/grpc v1.68.1
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
|
||||
google.golang.org/protobuf v1.35.2
|
||||
@@ -173,7 +174,6 @@ require (
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.25.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
|
4
go.sum
4
go.sum
@@ -297,8 +297,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
|
||||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/buildkit v0.19.0-rc2 h1:7sAuQ5bDNIbdfmc7UDbrWJ2UPOR5w9rNWgnrEoC5aoo=
|
||||
github.com/moby/buildkit v0.19.0-rc2/go.mod h1:4WYJLet/NI2p1o2rPQ6CIFpyyyvwvPz/TVISmwqqpHI=
|
||||
github.com/moby/buildkit v0.19.0 h1:w9G1p7sArvCGNkpWstAqJfRQTXBKukMyMK1bsah1HNo=
|
||||
github.com/moby/buildkit v0.19.0/go.mod h1:WiHBFTgWV8eB1AmPxIWsAlKjUACAwm3X/14xOV4VWew=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
|
@@ -91,7 +91,7 @@ func (a *Attest) ToPB() *controllerapi.Attest {
|
||||
|
||||
func (a *Attest) MarshalJSON() ([]byte, error) {
|
||||
m := make(map[string]interface{}, len(a.Attrs)+2)
|
||||
for k, v := range m {
|
||||
for k, v := range a.Attrs {
|
||||
m[k] = v
|
||||
}
|
||||
m["type"] = a.Type
|
||||
|
79
util/buildflags/attests_test.go
Normal file
79
util/buildflags/attests_test.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func TestAttests(t *testing.T) {
|
||||
t.Run("MarshalJSON", func(t *testing.T) {
|
||||
attests := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true},
|
||||
}
|
||||
|
||||
expected := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true}]`
|
||||
actual, err := json.Marshal(attests)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON", func(t *testing.T) {
|
||||
in := `[{"type":"provenance","mode":"max"},{"type":"sbom","disabled":true}]`
|
||||
|
||||
var actual Attests
|
||||
err := json.Unmarshal([]byte(in), &actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true, Attrs: map[string]string{}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("FromCtyValue", func(t *testing.T) {
|
||||
in := cty.TupleVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("provenance"),
|
||||
"mode": cty.StringVal("max"),
|
||||
}),
|
||||
cty.StringVal("type=sbom,disabled=true"),
|
||||
})
|
||||
|
||||
var actual Attests
|
||||
err := actual.FromCtyValue(in, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true, Attrs: map[string]string{}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("ToCtyValue", func(t *testing.T) {
|
||||
attests := Attests{
|
||||
{Type: "provenance", Attrs: map[string]string{"mode": "max"}},
|
||||
{Type: "sbom", Disabled: true},
|
||||
}
|
||||
|
||||
actual := attests.ToCtyValue()
|
||||
expected := cty.ListVal([]cty.Value{
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("provenance"),
|
||||
"mode": cty.StringVal("max"),
|
||||
}),
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("sbom"),
|
||||
"disabled": cty.StringVal("true"),
|
||||
}),
|
||||
})
|
||||
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
}
|
@@ -167,20 +167,37 @@ func (e *CacheOptionsEntry) validate(gv interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseCacheEntry(in []string) ([]*controllerapi.CacheOptionsEntry, error) {
|
||||
func ParseCacheEntry(in []string) (CacheOptions, error) {
|
||||
if len(in) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
opts := make(CacheOptions, 0, len(in))
|
||||
for _, in := range in {
|
||||
if !strings.Contains(in, "=") {
|
||||
// This is ref only format. Each field in the CSV is its own entry.
|
||||
fields, err := csvvalue.Fields(in, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, field := range fields {
|
||||
opt := CacheOptionsEntry{}
|
||||
if err := opt.UnmarshalText([]byte(field)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts = append(opts, &opt)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var out CacheOptionsEntry
|
||||
if err := out.UnmarshalText([]byte(in)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts = append(opts, &out)
|
||||
}
|
||||
return opts.ToPB(), nil
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
func addGithubToken(ci *controllerapi.CacheOptionsEntry) {
|
||||
|
@@ -30,6 +30,16 @@ func (o *CacheOptions) fromCtyValue(in cty.Value, p cty.Path) error {
|
||||
continue
|
||||
}
|
||||
|
||||
// Special handling for a string type to handle ref only format.
|
||||
if value.Type() == cty.String {
|
||||
entries, err := ParseCacheEntry([]string{value.AsString()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*o = append(*o, entries...)
|
||||
continue
|
||||
}
|
||||
|
||||
entry := &CacheOptionsEntry{}
|
||||
if err := entry.FromCtyValue(value, p); err != nil {
|
||||
return err
|
||||
@@ -52,13 +62,6 @@ func (o CacheOptions) ToCtyValue() cty.Value {
|
||||
}
|
||||
|
||||
func (o *CacheOptionsEntry) FromCtyValue(in cty.Value, p cty.Path) error {
|
||||
if in.Type() == cty.String {
|
||||
if err := o.UnmarshalText([]byte(in.AsString())); err != nil {
|
||||
return p.NewError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
conv, err := convert.Convert(in, cty.Map(cty.String))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -1,10 +1,12 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/buildx/controller/pb"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func TestCacheOptions_DerivedVars(t *testing.T) {
|
||||
@@ -35,5 +37,84 @@ func TestCacheOptions_DerivedVars(t *testing.T) {
|
||||
"session_token": "not_a_mitm_attack",
|
||||
},
|
||||
},
|
||||
}, cacheFrom)
|
||||
}, cacheFrom.ToPB())
|
||||
}
|
||||
|
||||
func TestCacheOptions(t *testing.T) {
|
||||
t.Run("MarshalJSON", func(t *testing.T) {
|
||||
cache := CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "user/app:cache"}},
|
||||
{Type: "local", Attrs: map[string]string{"src": "path/to/cache"}},
|
||||
}
|
||||
|
||||
expected := `[{"type":"registry","ref":"user/app:cache"},{"type":"local","src":"path/to/cache"}]`
|
||||
actual, err := json.Marshal(cache)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON", func(t *testing.T) {
|
||||
in := `[{"type":"registry","ref":"user/app:cache"},{"type":"local","src":"path/to/cache"}]`
|
||||
|
||||
var actual CacheOptions
|
||||
err := json.Unmarshal([]byte(in), &actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "user/app:cache"}},
|
||||
{Type: "local", Attrs: map[string]string{"src": "path/to/cache"}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("FromCtyValue", func(t *testing.T) {
|
||||
in := cty.TupleVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("registry"),
|
||||
"ref": cty.StringVal("user/app:cache"),
|
||||
}),
|
||||
cty.StringVal("type=local,src=path/to/cache"),
|
||||
})
|
||||
|
||||
var actual CacheOptions
|
||||
err := actual.FromCtyValue(in, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "user/app:cache"}},
|
||||
{Type: "local", Attrs: map[string]string{"src": "path/to/cache"}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("ToCtyValue", func(t *testing.T) {
|
||||
attests := CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "user/app:cache"}},
|
||||
{Type: "local", Attrs: map[string]string{"src": "path/to/cache"}},
|
||||
}
|
||||
|
||||
actual := attests.ToCtyValue()
|
||||
expected := cty.ListVal([]cty.Value{
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("registry"),
|
||||
"ref": cty.StringVal("user/app:cache"),
|
||||
}),
|
||||
cty.MapVal(map[string]cty.Value{
|
||||
"type": cty.StringVal("local"),
|
||||
"src": cty.StringVal("path/to/cache"),
|
||||
}),
|
||||
})
|
||||
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
}
|
||||
|
||||
func TestCacheOptions_RefOnlyFormat(t *testing.T) {
|
||||
opts, err := ParseCacheEntry([]string{"ref1", "ref2"})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, CacheOptions{
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "ref1"}},
|
||||
{Type: "registry", Attrs: map[string]string{"ref": "ref2"}},
|
||||
}, opts)
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
@@ -73,6 +74,22 @@ func (s *Secret) ToPB() *controllerapi.Secret {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Secret) UnmarshalJSON(data []byte) error {
|
||||
var v struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
FilePath string `json:"src,omitempty"`
|
||||
Env string `json:"env,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.ID = v.ID
|
||||
s.FilePath = v.FilePath
|
||||
s.Env = v.Env
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Secret) UnmarshalText(text []byte) error {
|
||||
value := string(text)
|
||||
fields, err := csvvalue.Fields(value, nil)
|
||||
|
84
util/buildflags/secrets_test.go
Normal file
84
util/buildflags/secrets_test.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func TestSecrets(t *testing.T) {
|
||||
t.Run("MarshalJSON", func(t *testing.T) {
|
||||
secrets := Secrets{
|
||||
{ID: "mysecret", FilePath: "/local/secret"},
|
||||
{ID: "mysecret2", Env: "TOKEN"},
|
||||
}
|
||||
|
||||
expected := `[{"id":"mysecret","src":"/local/secret"},{"id":"mysecret2","env":"TOKEN"}]`
|
||||
actual, err := json.Marshal(secrets)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON", func(t *testing.T) {
|
||||
in := `[{"id":"mysecret","src":"/local/secret"},{"id":"mysecret2","env":"TOKEN"}]`
|
||||
|
||||
var actual Secrets
|
||||
err := json.Unmarshal([]byte(in), &actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := Secrets{
|
||||
{ID: "mysecret", FilePath: "/local/secret"},
|
||||
{ID: "mysecret2", Env: "TOKEN"},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("FromCtyValue", func(t *testing.T) {
|
||||
in := cty.TupleVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("mysecret"),
|
||||
"src": cty.StringVal("/local/secret"),
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("mysecret2"),
|
||||
"env": cty.StringVal("TOKEN"),
|
||||
}),
|
||||
})
|
||||
|
||||
var actual Secrets
|
||||
err := actual.FromCtyValue(in, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := Secrets{
|
||||
{ID: "mysecret", FilePath: "/local/secret"},
|
||||
{ID: "mysecret2", Env: "TOKEN"},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("ToCtyValue", func(t *testing.T) {
|
||||
secrets := Secrets{
|
||||
{ID: "mysecret", FilePath: "/local/secret"},
|
||||
{ID: "mysecret2", Env: "TOKEN"},
|
||||
}
|
||||
|
||||
actual := secrets.ToCtyValue()
|
||||
expected := cty.ListVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("mysecret"),
|
||||
"src": cty.StringVal("/local/secret"),
|
||||
"env": cty.StringVal(""),
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("mysecret2"),
|
||||
"src": cty.StringVal(""),
|
||||
"env": cty.StringVal("TOKEN"),
|
||||
}),
|
||||
})
|
||||
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
}
|
@@ -2,6 +2,7 @@ package buildflags
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
@@ -76,6 +77,20 @@ func (s *SSH) ToPB() *controllerapi.SSH {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SSH) UnmarshalJSON(data []byte) error {
|
||||
var v struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.ID = v.ID
|
||||
s.Paths = v.Paths
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SSH) UnmarshalText(text []byte) error {
|
||||
parts := strings.SplitN(string(text), "=", 2)
|
||||
|
||||
|
85
util/buildflags/ssh_test.go
Normal file
85
util/buildflags/ssh_test.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package buildflags
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
)
|
||||
|
||||
func TestSSHKeys(t *testing.T) {
|
||||
t.Run("MarshalJSON", func(t *testing.T) {
|
||||
sshkeys := SSHKeys{
|
||||
{ID: "default", Paths: []string{}},
|
||||
{ID: "key", Paths: []string{"path/to/key"}},
|
||||
}
|
||||
|
||||
expected := `[{"id":"default"},{"id":"key","paths":["path/to/key"]}]`
|
||||
actual, err := json.Marshal(sshkeys)
|
||||
require.NoError(t, err)
|
||||
require.JSONEq(t, expected, string(actual))
|
||||
})
|
||||
|
||||
t.Run("UnmarshalJSON", func(t *testing.T) {
|
||||
in := `[{"id":"default"},{"id":"key","paths":["path/to/key"]}]`
|
||||
|
||||
var actual SSHKeys
|
||||
err := json.Unmarshal([]byte(in), &actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := SSHKeys{
|
||||
{ID: "default"},
|
||||
{ID: "key", Paths: []string{"path/to/key"}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("FromCtyValue", func(t *testing.T) {
|
||||
in := cty.TupleVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("default"),
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("key"),
|
||||
"paths": cty.TupleVal([]cty.Value{
|
||||
cty.StringVal("path/to/key"),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
var actual SSHKeys
|
||||
err := actual.FromCtyValue(in, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expected := SSHKeys{
|
||||
{ID: "default"},
|
||||
{ID: "key", Paths: []string{"path/to/key"}},
|
||||
}
|
||||
require.Equal(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("ToCtyValue", func(t *testing.T) {
|
||||
sshkeys := SSHKeys{
|
||||
{ID: "default", Paths: []string{}},
|
||||
{ID: "key", Paths: []string{"path/to/key"}},
|
||||
}
|
||||
|
||||
actual := sshkeys.ToCtyValue()
|
||||
expected := cty.ListVal([]cty.Value{
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("default"),
|
||||
"paths": cty.ListValEmpty(cty.String),
|
||||
}),
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.StringVal("key"),
|
||||
"paths": cty.ListVal([]cty.Value{
|
||||
cty.StringVal("path/to/key"),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
|
||||
result := actual.Equals(expected)
|
||||
require.True(t, result.True())
|
||||
})
|
||||
}
|
9
vendor/github.com/moby/buildkit/util/gitutil/git_cli.go
generated
vendored
9
vendor/github.com/moby/buildkit/util/gitutil/git_cli.go
generated
vendored
@@ -134,6 +134,10 @@ func (cli *GitCLI) Run(ctx context.Context, args ...string) (_ []byte, err error
|
||||
if cli.git != "" {
|
||||
gitBinary = cli.git
|
||||
}
|
||||
proxyEnvVars := [...]string{
|
||||
"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "ALL_PROXY",
|
||||
"http_proxy", "https_proxy", "no_proxy", "all_proxy",
|
||||
}
|
||||
|
||||
for {
|
||||
var cmd *exec.Cmd
|
||||
@@ -190,6 +194,11 @@ func (cli *GitCLI) Run(ctx context.Context, args ...string) (_ []byte, err error
|
||||
"HOME=/dev/null", // Disable reading from user gitconfig.
|
||||
"LC_ALL=C", // Ensure consistent output.
|
||||
}
|
||||
for _, ev := range proxyEnvVars {
|
||||
if v, ok := os.LookupEnv(ev); ok {
|
||||
cmd.Env = append(cmd.Env, ev+"="+v)
|
||||
}
|
||||
}
|
||||
if cli.sshAuthSock != "" {
|
||||
cmd.Env = append(cmd.Env, "SSH_AUTH_SOCK="+cli.sshAuthSock)
|
||||
}
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -493,7 +493,7 @@ github.com/mitchellh/go-wordwrap
|
||||
github.com/mitchellh/hashstructure/v2
|
||||
# github.com/mitchellh/mapstructure v1.5.0
|
||||
## explicit; go 1.14
|
||||
# github.com/moby/buildkit v0.19.0-rc2
|
||||
# github.com/moby/buildkit v0.19.0
|
||||
## explicit; go 1.22.0
|
||||
github.com/moby/buildkit/api/services/control
|
||||
github.com/moby/buildkit/api/types
|
||||
|
Reference in New Issue
Block a user