Compare commits

..

22 Commits

Author SHA1 Message Date
CrazyMax
f4ca8d20f2 Merge pull request #2653 from dvdksn/backport-doc-manuals-links
[v0.16 backport] docs: update links to moved manuals pages
2024-09-03 10:43:02 +02:00
David Karlsson
4cb785cabb docs: update links to moved manuals pages
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
(cherry picked from commit bc6e94ec61e39109aa67361a45983b8a910f9ebb)
Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
2024-08-19 13:17:11 +02:00
CrazyMax
99dea6daca Merge pull request #2630 from crazy-max/v0.16.2_cherry-picks
[v0.16] cherry-picks for v0.16.2
2024-07-25 16:45:22 +02:00
CrazyMax
7b8a06925e vendor: update buildkit to v0.15.1
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 0fb0b6db0d)
2024-07-25 15:59:48 +02:00
Tõnis Tiigi
34c195271a Merge pull request #2604 from crazy-max/v0.16.1_cherry-picks
[v0.16] cherry-picks for v0.16.1
2024-07-18 09:29:55 -07:00
Talon Bowler
dd3bb69a1e clarify the appropriate place to use the debug flag when viewing warnings
Signed-off-by: Talon Bowler <talon.bowler@docker.com>
(cherry picked from commit cedbc5d68d)
2024-07-18 18:18:03 +02:00
CrazyMax
9d8cf0bed3 test: bake print
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit bd0b425734)
2024-07-18 17:47:17 +02:00
CrazyMax
fb773fa805 bake: check printer before printing warnings
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
(cherry picked from commit 7823a2dc01)
2024-07-18 17:47:17 +02:00
Tõnis Tiigi
10c9ff901c Merge pull request #2590 from tonistiigi/vendor-buildkit-v0.15.0
[v0.16] vendor: update buildkit to v0.15.0
2024-07-11 11:35:48 -07:00
Tonis Tiigi
470e45e599 vendor: update buildkit to v0.15.0
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-07-11 11:23:39 -07:00
Tõnis Tiigi
2a2648b1db Merge pull request #2588 from tonistiigi/vendor-buildkit-v0.15.0-rc2
vendor: update buildkit to v0.15.0-rc2
2024-07-10 15:35:25 -07:00
Tonis Tiigi
ac930bda69 vendor: update buildkit to v0.15.0-rc2
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-07-10 15:03:14 -07:00
Tõnis Tiigi
6791ecb628 Merge pull request #2587 from tonistiigi/update-moby-27.0.3
Dockerfile: update moby for testing to v27.0.3
2024-07-10 13:06:16 -07:00
Tonis Tiigi
d717237e4f Dockerfile: update moby for testing to v27.0.3
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-07-10 11:16:38 -07:00
Tõnis Tiigi
ee642ecc4c Merge pull request #2578 from crazy-max/driver-client-opt
driver: allow arbitrary client opts
2024-07-10 09:55:15 -07:00
Tõnis Tiigi
06d96d665e Merge pull request #2584 from tonistiigi/bake-test-fix
bake: fix testing json formatted output
2024-07-09 12:40:51 -07:00
Tõnis Tiigi
dc83501a5b Merge pull request #2583 from tonistiigi/bake-implicit-cacheonly
bake: use cacheonly exporter for implicit targets
2024-07-09 12:40:21 -07:00
Tonis Tiigi
0f74f9a794 bake: fix testing json formatted output
Because the test checked for combinedoutput, it
could contain internal warning messages in stderr.
JSON output is guaranteed in stdout.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-07-08 18:32:37 -07:00
Tonis Tiigi
6d6adc11a1 bake: use cacheonly exporter for implicit targets
Clearing the exporter may result in default export
behavior from the driver.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-07-08 17:53:52 -07:00
Tõnis Tiigi
68076909b9 Merge pull request #2579 from crazy-max/fix-compose-project-name
bake: use compose project name from env if set
2024-07-08 11:20:42 -07:00
CrazyMax
7957b73a30 bake: use compose project name from env if set
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-07-04 16:37:07 +02:00
CrazyMax
1dceb49a27 driver: allow arbitrary client opts
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-07-04 16:36:55 +02:00
35 changed files with 447 additions and 135 deletions

View File

@@ -4,7 +4,7 @@ ARG GO_VERSION=1.22
ARG XX_VERSION=1.4.0 ARG XX_VERSION=1.4.0
# for testing # for testing
ARG DOCKER_VERSION=27.0.0-rc.2 ARG DOCKER_VERSION=27.0.3
ARG GOTESTSUM_VERSION=v1.9.0 ARG GOTESTSUM_VERSION=v1.9.0
ARG REGISTRY_VERSION=2.8.0 ARG REGISTRY_VERSION=2.8.0
ARG BUILDKIT_VERSION=v0.14.1 ARG BUILDKIT_VERSION=v0.14.1

View File

@@ -494,7 +494,7 @@ func (c Config) loadLinks(name string, t *Target, m map[string]*Target, o map[st
if err != nil { if err != nil {
return err return err
} }
t2.Outputs = nil t2.Outputs = []string{"type=cacheonly"}
t2.linked = true t2.linked = true
m[target] = t2 m[target] = t2
} }

View File

@@ -838,7 +838,8 @@ func TestReadContextFromTargetChain(t *testing.T) {
mid, ok := m["mid"] mid, ok := m["mid"]
require.True(t, ok) require.True(t, ok)
require.Equal(t, 0, len(mid.Outputs)) require.Equal(t, 1, len(mid.Outputs))
require.Equal(t, "type=cacheonly", mid.Outputs[0])
require.Equal(t, 1, len(mid.Contexts)) require.Equal(t, 1, len(mid.Contexts))
base, ok := m["base"] base, ok := m["base"]

View File

@@ -8,6 +8,7 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/compose-spec/compose-go/v2/consts"
"github.com/compose-spec/compose-go/v2/dotenv" "github.com/compose-spec/compose-go/v2/dotenv"
"github.com/compose-spec/compose-go/v2/loader" "github.com/compose-spec/compose-go/v2/loader"
composetypes "github.com/compose-spec/compose-go/v2/types" composetypes "github.com/compose-spec/compose-go/v2/types"
@@ -40,7 +41,11 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf
ConfigFiles: cfgs, ConfigFiles: cfgs,
Environment: envs, Environment: envs,
}, func(options *loader.Options) { }, func(options *loader.Options) {
options.SetProjectName("bake", false) projectName := "bake"
if v, ok := envs[consts.ComposeProjectName]; ok && v != "" {
projectName = v
}
options.SetProjectName(projectName, false)
options.SkipNormalization = true options.SkipNormalization = true
options.Profiles = []string{"*"} options.Profiles = []string{"*"}
}) })

View File

@@ -771,6 +771,33 @@ services:
require.NoError(t, err) require.NoError(t, err)
} }
func TestProjectName(t *testing.T) {
var dt = []byte(`
services:
scratch:
build:
context: ./webapp
args:
PROJECT_NAME: ${COMPOSE_PROJECT_NAME}
`)
t.Run("default", func(t *testing.T) {
c, err := ParseCompose([]composetypes.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Len(t, c.Targets, 1)
require.Len(t, c.Targets[0].Args, 1)
require.Equal(t, map[string]*string{"PROJECT_NAME": ptrstr("bake")}, c.Targets[0].Args)
})
t.Run("env", func(t *testing.T) {
c, err := ParseCompose([]composetypes.ConfigFile{{Content: dt}}, map[string]string{"COMPOSE_PROJECT_NAME": "foo"})
require.NoError(t, err)
require.Len(t, c.Targets, 1)
require.Len(t, c.Targets[0].Args, 1)
require.Equal(t, map[string]*string{"PROJECT_NAME": ptrstr("foo")}, c.Targets[0].Args)
})
}
// chdir changes the current working directory to the named directory, // chdir changes the current working directory to the named directory,
// and then restore the original working directory at the end of the test. // and then restore the original working directory at the end of the test.
func chdir(t *testing.T, dir string) { func chdir(t *testing.T, dir string) {

View File

@@ -48,8 +48,9 @@ func (b *Builder) Nodes() []Node {
type LoadNodesOption func(*loadNodesOptions) type LoadNodesOption func(*loadNodesOptions)
type loadNodesOptions struct { type loadNodesOptions struct {
data bool data bool
dialMeta map[string][]string dialMeta map[string][]string
clientOpt []client.ClientOpt
} }
func WithData() LoadNodesOption { func WithData() LoadNodesOption {
@@ -64,6 +65,12 @@ func WithDialMeta(dialMeta map[string][]string) LoadNodesOption {
} }
} }
func WithClientOpt(clientOpt ...client.ClientOpt) LoadNodesOption {
return func(o *loadNodesOptions) {
o.clientOpt = clientOpt
}
}
// LoadNodes loads and returns nodes for this builder. // LoadNodes loads and returns nodes for this builder.
// TODO: this should be a method on a Node object and lazy load data for each driver. // TODO: this should be a method on a Node object and lazy load data for each driver.
func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []Node, err error) { func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []Node, err error) {
@@ -151,7 +158,7 @@ func (b *Builder) LoadNodes(ctx context.Context, opts ...LoadNodesOption) (_ []N
node.ImageOpt = imageopt node.ImageOpt = imageopt
if lno.data { if lno.data {
if err := node.loadData(ctx); err != nil { if err := node.loadData(ctx, lno.clientOpt...); err != nil {
node.Err = err node.Err = err
} }
} }
@@ -247,7 +254,7 @@ func (n *Node) MarshalJSON() ([]byte, error) {
}) })
} }
func (n *Node) loadData(ctx context.Context) error { func (n *Node) loadData(ctx context.Context, clientOpt ...client.ClientOpt) error {
if n.Driver == nil { if n.Driver == nil {
return nil return nil
} }
@@ -257,7 +264,7 @@ func (n *Node) loadData(ctx context.Context) error {
} }
n.DriverInfo = info n.DriverInfo = info
if n.DriverInfo.Status == driver.Running { if n.DriverInfo.Status == driver.Running {
driverClient, err := n.Driver.Client(ctx) driverClient, err := n.Driver.Client(ctx, clientOpt...)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -146,7 +146,9 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
printer, err = progress.NewPrinter(ctx2, os.Stderr, progressMode, printer, err = progress.NewPrinter(ctx2, os.Stderr, progressMode,
progress.WithDesc(progressTextDesc, progressConsoleDesc), progress.WithDesc(progressTextDesc, progressConsoleDesc),
progress.WithOnClose(func() { progress.WithOnClose(func() {
printWarnings(os.Stderr, printer.Warnings(), progressMode) if p := printer; p != nil {
printWarnings(os.Stderr, p.Warnings(), progressMode)
}
}), }),
) )
if err != nil { if err != nil {

View File

@@ -835,7 +835,7 @@ func printWarnings(w io.Writer, warnings []client.VertexWarning, mode progressui
fmt.Fprintf(sb, "%d warnings found", len(warnings)) fmt.Fprintf(sb, "%d warnings found", len(warnings))
} }
if logrus.GetLevel() < logrus.DebugLevel { if logrus.GetLevel() < logrus.DebugLevel {
fmt.Fprintf(sb, " (use --debug to expand)") fmt.Fprintf(sb, " (use docker --debug to expand)")
} }
fmt.Fprintf(sb, ":\n") fmt.Fprintf(sb, ":\n")
fmt.Fprint(w, aec.Apply(sb.String(), aec.YellowF)) fmt.Fprint(w, aec.Apply(sb.String(), aec.YellowF))

View File

@@ -165,7 +165,7 @@ $ cat metadata.json
> **Note** > **Note**
> >
> Build record [provenance](https://docs.docker.com/build/attestations/slsa-provenance/#provenance-attestation-example) > Build record [provenance](https://docs.docker.com/build/metadata/attestations/slsa-provenance/#provenance-attestation-example)
> (`buildx.build.provenance`) includes minimal provenance by default. Set the > (`buildx.build.provenance`) includes minimal provenance by default. Set the
> `BUILDX_METADATA_PROVENANCE` environment variable to customize this behavior: > `BUILDX_METADATA_PROVENANCE` environment variable to customize this behavior:
> * `min` sets minimal provenance (default). > * `min` sets minimal provenance (default).

View File

@@ -144,7 +144,7 @@ For more information about annotations, see
--attest=type=provenance,... --attest=type=provenance,...
``` ```
Create [image attestations](https://docs.docker.com/build/attestations/). Create [image attestations](https://docs.docker.com/build/metadata/attestations/).
BuildKit currently supports: BuildKit currently supports:
- `sbom` - Software Bill of Materials. - `sbom` - Software Bill of Materials.
@@ -152,7 +152,7 @@ BuildKit currently supports:
Use `--attest=type=sbom` to generate an SBOM for an image at build-time. Use `--attest=type=sbom` to generate an SBOM for an image at build-time.
Alternatively, you can use the [`--sbom` shorthand](#sbom). Alternatively, you can use the [`--sbom` shorthand](#sbom).
For more information, see [here](https://docs.docker.com/build/attestations/sbom/). For more information, see [here](https://docs.docker.com/build/metadata/attestations/sbom/).
- `provenance` - SLSA Provenance - `provenance` - SLSA Provenance
@@ -162,7 +162,7 @@ BuildKit currently supports:
By default, a minimal provenance attestation will be created for the build By default, a minimal provenance attestation will be created for the build
result, which will only be attached for images pushed to registries. result, which will only be attached for images pushed to registries.
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/). For more information, see [here](https://docs.docker.com/build/metadata/attestations/slsa-provenance/).
### <a name="allow"></a> Allow extra privileged entitlement (--allow) ### <a name="allow"></a> Allow extra privileged entitlement (--allow)
@@ -583,7 +583,7 @@ $ cat metadata.json
> **Note** > **Note**
> >
> Build record [provenance](https://docs.docker.com/build/attestations/slsa-provenance/#provenance-attestation-example) > Build record [provenance](https://docs.docker.com/build/metadata/attestations/slsa-provenance/#provenance-attestation-example)
> (`buildx.build.provenance`) includes minimal provenance by default. Set the > (`buildx.build.provenance`) includes minimal provenance by default. Set the
> `BUILDX_METADATA_PROVENANCE` environment variable to customize this behavior: > `BUILDX_METADATA_PROVENANCE` environment variable to customize this behavior:
> >
@@ -669,7 +669,7 @@ The arguments for the `--no-cache-filter` flag must be names of stages.
``` ```
Sets the export action for the build result. The default output, when using the Sets the export action for the build result. The default output, when using the
`docker` [build driver](https://docs.docker.com/build/drivers/), is a container `docker` [build driver](https://docs.docker.com/build/builders/drivers/), is a container
image exported to the local image store. The `--output` flag makes this step image exported to the local image store. The `--output` flag makes this step
configurable allows export of results directly to the client's filesystem, an configurable allows export of results directly to the client's filesystem, an
OCI image tarball, a registry, and more. OCI image tarball, a registry, and more.
@@ -877,7 +877,7 @@ to a registry if you use the default image store. Alternatively, you can switch
to using the containerd image store. to using the containerd image store.
For more information about provenance attestations, see For more information about provenance attestations, see
[here](https://docs.docker.com/build/attestations/slsa-provenance/). [here](https://docs.docker.com/build/metadata/attestations/slsa-provenance/).
### <a name="push"></a> Push the build result to a registry (--push) ### <a name="push"></a> Push the build result to a registry (--push)
@@ -899,7 +899,7 @@ attestations. Provenance attestations only persist for images pushed directly
to a registry if you use the default image store. Alternatively, you can switch to a registry if you use the default image store. Alternatively, you can switch
to using the containerd image store. to using the containerd image store.
For more information, see [here](https://docs.docker.com/build/attestations/sbom/). For more information, see [here](https://docs.docker.com/build/metadata/attestations/sbom/).
### <a name="secret"></a> Secret to expose to the build (--secret) ### <a name="secret"></a> Secret to expose to the build (--secret)

View File

@@ -120,7 +120,7 @@ backend. Buildx supports the following drivers:
* `kubernetes` * `kubernetes`
* `remote` * `remote`
For more information about build drivers, see [here](https://docs.docker.com/build/drivers/). For more information about build drivers, see [here](https://docs.docker.com/build/builders/drivers/).
#### `docker` driver #### `docker` driver
@@ -167,10 +167,10 @@ Passes additional driver-specific options.
For information about available driver options, refer to the detailed For information about available driver options, refer to the detailed
documentation for the specific driver: documentation for the specific driver:
* [`docker` driver](https://docs.docker.com/build/drivers/docker/) * [`docker` driver](https://docs.docker.com/build/builders/drivers/docker/)
* [`docker-container` driver](https://docs.docker.com/build/drivers/docker-container/) * [`docker-container` driver](https://docs.docker.com/build/builders/drivers/docker-container/)
* [`kubernetes` driver](https://docs.docker.com/build/drivers/kubernetes/) * [`kubernetes` driver](https://docs.docker.com/build/builders/drivers/kubernetes/)
* [`remote` driver](https://docs.docker.com/build/drivers/remote/) * [`remote` driver](https://docs.docker.com/build/builders/drivers/remote/)
### <a name="leave"></a> Remove a node from a builder (--leave) ### <a name="leave"></a> Remove a node from a builder (--leave)

View File

@@ -155,9 +155,9 @@ type DriverHandle struct {
historyAPISupported bool historyAPISupported bool
} }
func (d *DriverHandle) Client(ctx context.Context) (*client.Client, error) { func (d *DriverHandle) Client(ctx context.Context, opt ...client.ClientOpt) (*client.Client, error) {
d.once.Do(func() { d.once.Do(func() {
d.client, d.err = d.Driver.Client(ctx, d.getClientOptions()...) d.client, d.err = d.Driver.Client(ctx, append(d.getClientOptions(), opt...)...)
}) })
return d.client, d.err return d.client, d.err
} }

8
go.mod
View File

@@ -20,7 +20,7 @@ require (
github.com/docker/cli-docs-tool v0.8.0 github.com/docker/cli-docs-tool v0.8.0
github.com/docker/docker v27.0.3+incompatible github.com/docker/docker v27.0.3+incompatible
github.com/docker/go-units v0.5.0 github.com/docker/go-units v0.5.0
github.com/gofrs/flock v0.12.0 github.com/gofrs/flock v0.12.1
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.4 github.com/golang/protobuf v1.5.4
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
@@ -29,7 +29,7 @@ require (
github.com/hashicorp/hcl/v2 v2.20.1 github.com/hashicorp/hcl/v2 v2.20.1
github.com/in-toto/in-toto-golang v0.5.0 github.com/in-toto/in-toto-golang v0.5.0
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/moby/buildkit v0.15.0-rc1 github.com/moby/buildkit v0.15.1
github.com/moby/sys/mountinfo v0.7.1 github.com/moby/sys/mountinfo v0.7.1
github.com/moby/sys/signal v0.7.0 github.com/moby/sys/signal v0.7.0
github.com/morikuni/aec v1.0.0 github.com/morikuni/aec v1.0.0
@@ -43,7 +43,7 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2 github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4
github.com/zclconf/go-cty v1.14.4 github.com/zclconf/go-cty v1.14.4
go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/metric v1.21.0 go.opentelemetry.io/otel/metric v1.21.0
@@ -51,7 +51,7 @@ require (
go.opentelemetry.io/otel/trace v1.21.0 go.opentelemetry.io/otel/trace v1.21.0
golang.org/x/mod v0.17.0 golang.org/x/mod v0.17.0
golang.org/x/sync v0.7.0 golang.org/x/sync v0.7.0
golang.org/x/sys v0.21.0 golang.org/x/sys v0.22.0
golang.org/x/term v0.20.0 golang.org/x/term v0.20.0
golang.org/x/text v0.15.0 golang.org/x/text v0.15.0
google.golang.org/grpc v1.59.0 google.golang.org/grpc v1.59.0

16
go.sum
View File

@@ -184,8 +184,8 @@ github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc=
github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gofrs/flock v0.12.0 h1:xHW8t8GPAiGtqz7KxiSqfOEXwpOaqhpYZrTE2MQBgXY= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
github.com/gofrs/flock v0.12.0/go.mod h1:FirDy1Ing0mI2+kB6wk+vyyAH+e6xiE+EYA0jnzV9jc= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -306,8 +306,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 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 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/buildkit v0.15.0-rc1 h1:74cW+CaRhCX8b/0sTEwWM6zPxgHJb90imPZMf+E42TY= github.com/moby/buildkit v0.15.1 h1:J6wrew7hphKqlq1wuu6yaUb/1Ra7gEzDAovylGztAKM=
github.com/moby/buildkit v0.15.0-rc1/go.mod h1:ik25J3PkZrQc2dDquClV6jXMjjtoXDCLFySlfZDk5j0= github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= 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/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -442,8 +442,8 @@ github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4D
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M= github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c h1:+6wg/4ORAbnSoGDzg2Q1i3CeMcT/jjhye/ZfnBHy7/M=
github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM= github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM=
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2 h1:4dXTcm/McJMoXXFhqr+4rNL4WkLqMoHkdMhT4nU0Z28= github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 h1:7I5c2Ig/5FgqkYOh/N87NzoyI9U15qUPXhDD8uCupv8=
github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE= github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw= github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw=
@@ -549,8 +549,8 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=

View File

@@ -1,6 +1,7 @@
package tests package tests
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
@@ -9,6 +10,7 @@ import (
"testing" "testing"
"github.com/containerd/continuity/fs/fstest" "github.com/containerd/continuity/fs/fstest"
"github.com/docker/buildx/bake"
"github.com/docker/buildx/util/gitutil" "github.com/docker/buildx/util/gitutil"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/moby/buildkit/identity" "github.com/moby/buildkit/identity"
@@ -28,6 +30,7 @@ func bakeCmd(sb integration.Sandbox, opts ...cmdOpt) (string, error) {
} }
var bakeTests = []func(t *testing.T, sb integration.Sandbox){ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakePrint,
testBakeLocal, testBakeLocal,
testBakeLocalMulti, testBakeLocalMulti,
testBakeRemote, testBakeRemote,
@@ -55,6 +58,49 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeCallCheckFlag, testBakeCallCheckFlag,
} }
func testBakePrint(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(`
FROM busybox
ARG HELLO
RUN echo "Hello ${HELLO}"
`)
bakefile := []byte(`
target "build" {
args = {
HELLO = "foo"
}
}
`)
dir := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateFile("Dockerfile", dockerfile, 0600),
)
cmd := buildxCmd(sb, withDir(dir), withArgs("bake", "--print", "build"))
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
cmd.Stdout = &stdout
cmd.Stderr = &stderr
require.NoError(t, cmd.Run(), stdout.String(), stderr.String())
var def struct {
Group map[string]*bake.Group `json:"group,omitempty"`
Target map[string]*bake.Target `json:"target"`
}
require.NoError(t, json.Unmarshal(stdout.Bytes(), &def))
require.Len(t, def.Group, 1)
require.Contains(t, def.Group, "default")
require.Equal(t, []string{"build"}, def.Group["default"].Targets)
require.Len(t, def.Target, 1)
require.Contains(t, def.Target, "build")
require.Equal(t, ".", *def.Target["build"].Context)
require.Equal(t, "Dockerfile", *def.Target["build"].Dockerfile)
require.Equal(t, map[string]*string{"HELLO": ptrstr("foo")}, def.Target["build"].Args)
}
func testBakeLocal(t *testing.T, sb integration.Sandbox) { func testBakeLocal(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(` dockerfile := []byte(`
FROM scratch FROM scratch
@@ -1074,15 +1120,16 @@ target "another" {
require.Contains(t, out, "another") require.Contains(t, out, "another")
require.Contains(t, out, "UndefinedVar") require.Contains(t, out, "UndefinedVar")
out, err = bakeCmd( cmd := buildxCmd(
sb, sb,
withDir(dir), withDir(dir),
withArgs("build", "another", "--call", "check,format=json"), withArgs("bake", "--progress=quiet", "build", "another", "--call", "check,format=json"),
) )
require.Error(t, err, out) outB, err := cmd.Output()
require.Error(t, err, string(outB))
var res map[string]any var res map[string]any
err = json.Unmarshal([]byte(out), &res) err = json.Unmarshal(outB, &res)
require.NoError(t, err, out) require.NoError(t, err, out)
targets, ok := res["target"].(map[string]any) targets, ok := res["target"].(map[string]any)

View File

@@ -4,6 +4,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"reflect"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@@ -208,3 +209,12 @@ func skipNoCompatBuildKit(t *testing.T, sb integration.Sandbox, constraint strin
t.Skipf("buildkit version %s does not match %s constraint (%s)", buildkitVersion(t, sb), constraint, msg) t.Skipf("buildkit version %s does not match %s constraint (%s)", buildkitVersion(t, sb), constraint, msg)
} }
} }
func ptrstr(s interface{}) *string {
var n *string
if reflect.ValueOf(s).Kind() == reflect.String {
ss := s.(string)
n = &ss
}
return n
}

View File

@@ -1,7 +1,7 @@
# flock # flock
[![Go Reference](https://pkg.go.dev/badge/github.com/gofrs/flock.svg)](https://pkg.go.dev/github.com/gofrs/flock) [![Go Reference](https://pkg.go.dev/badge/github.com/gofrs/flock.svg)](https://pkg.go.dev/github.com/gofrs/flock)
[![License](https://img.shields.io/badge/license-BSD_3--Clause-brightgreen.svg?style=flat)](https://github.com/gofrs/flock/blob/master/LICENSE) [![License](https://img.shields.io/badge/license-BSD_3--Clause-brightgreen.svg?style=flat)](https://github.com/gofrs/flock/blob/main/LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/gofrs/flock)](https://goreportcard.com/report/github.com/gofrs/flock) [![Go Report Card](https://goreportcard.com/badge/github.com/gofrs/flock)](https://goreportcard.com/report/github.com/gofrs/flock)
`flock` implements a thread-safe file lock. `flock` implements a thread-safe file lock.

View File

@@ -163,9 +163,9 @@ func tryCtx(ctx context.Context, fn func() (bool, error), retryDelay time.Durati
} }
} }
func (f *Flock) setFh() error { func (f *Flock) setFh(flag int) error {
// open a new os.File instance // open a new os.File instance
fh, err := os.OpenFile(f.path, f.flag, f.perm) fh, err := os.OpenFile(f.path, flag, f.perm)
if err != nil { if err != nil {
return err return err
} }
@@ -176,9 +176,11 @@ func (f *Flock) setFh() error {
return nil return nil
} }
// ensure the file handle is closed if no lock is held. // resetFh resets file handle:
func (f *Flock) ensureFhState() { // - tries to close the file (ignore errors)
if f.l || f.r || f.fh == nil { // - sets fh to nil.
func (f *Flock) resetFh() {
if f.fh == nil {
return return
} }
@@ -187,11 +189,18 @@ func (f *Flock) ensureFhState() {
f.fh = nil f.fh = nil
} }
// ensure the file handle is closed if no lock is held.
func (f *Flock) ensureFhState() {
if f.l || f.r || f.fh == nil {
return
}
f.resetFh()
}
func (f *Flock) reset() { func (f *Flock) reset() {
f.l = false f.l = false
f.r = false f.r = false
_ = f.fh.Close() f.resetFh()
f.fh = nil
} }

View File

@@ -50,7 +50,7 @@ func (f *Flock) lock(locked *bool, flag int) error {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return err return err
} }
@@ -147,7 +147,7 @@ func (f *Flock) try(locked *bool, flag int) (bool, error) {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return false, err return false, err
} }
@@ -183,6 +183,7 @@ retry:
// This comes from `util-linux/sys-utils/flock.c`: // This comes from `util-linux/sys-utils/flock.c`:
// > Since Linux 3.4 (commit 55725513) // > Since Linux 3.4 (commit 55725513)
// > Probably NFSv4 where flock() is emulated by fcntl(). // > Probably NFSv4 where flock() is emulated by fcntl().
// > https://github.com/util-linux/util-linux/blob/198e920aa24743ef6ace4e07cf6237de527f9261/sys-utils/flock.c#L374-L390
func (f *Flock) reopenFDOnError(err error) (bool, error) { func (f *Flock) reopenFDOnError(err error) (bool, error) {
if !errors.Is(err, unix.EIO) && !errors.Is(err, unix.EBADF) { if !errors.Is(err, unix.EIO) && !errors.Is(err, unix.EBADF) {
return false, nil return false, nil
@@ -197,16 +198,13 @@ func (f *Flock) reopenFDOnError(err error) (bool, error) {
return false, nil return false, nil
} }
_ = f.fh.Close() f.resetFh()
f.fh = nil
// reopen in read-write mode and set the file handle // reopen in read-write mode and set the file handle
fh, err := os.OpenFile(f.path, f.flag, f.perm) err = f.setFh(f.flag | os.O_RDWR)
if err != nil { if err != nil {
return false, err return false, err
} }
f.fh = fh
return true, nil return true, nil
} }

View File

@@ -112,7 +112,7 @@ func (f *Flock) lock(locked *bool, flag lockType) error {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return err return err
} }
@@ -359,7 +359,7 @@ func (f *Flock) try(locked *bool, flag lockType) (bool, error) {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return false, err return false, err
} }

View File

@@ -56,7 +56,7 @@ func (f *Flock) lock(locked *bool, flag uint32) error {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return err return err
} }
@@ -136,7 +136,7 @@ func (f *Flock) try(locked *bool, flag uint32) (bool, error) {
} }
if f.fh == nil { if f.fh == nil {
if err := f.setFh(); err != nil { if err := f.setFh(f.flag); err != nil {
return false, err return false, err
} }

View File

@@ -148,4 +148,20 @@ var (
return fmt.Sprintf("Default value for ARG %v results in empty or invalid base image name", baseName) return fmt.Sprintf("Default value for ARG %v results in empty or invalid base image name", baseName)
}, },
} }
RuleFromPlatformFlagConstDisallowed = LinterRule[func(string) string]{
Name: "FromPlatformFlagConstDisallowed",
Description: "FROM --platform flag should not use a constant value",
URL: "https://docs.docker.com/go/dockerfile/rule/from-platform-flag-const-disallowed/",
Format: func(platform string) string {
return fmt.Sprintf("FROM --platform flag should not use constant value %q", platform)
},
}
RuleCopyIgnoredFile = LinterRule[func(string, string) string]{
Name: "CopyIgnoredFile",
Description: "Attempting to Copy file that is excluded by .dockerignore",
URL: "https://docs.docker.com/go/dockerfile/rule/copy-ignored-file/",
Format: func(cmd, file string) string {
return fmt.Sprintf("Attempting to %s file %q that is excluded by .dockerignore", cmd, file)
},
}
) )

View File

@@ -45,28 +45,30 @@ const (
// Don't forget to update frontend documentation if you add // Don't forget to update frontend documentation if you add
// a new build-arg: frontend/dockerfile/docs/reference.md // a new build-arg: frontend/dockerfile/docs/reference.md
keyCacheNSArg = "build-arg:BUILDKIT_CACHE_MOUNT_NS" keyCacheNSArg = "build-arg:BUILDKIT_CACHE_MOUNT_NS"
keyMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM" keyMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM"
keyHostnameArg = "build-arg:BUILDKIT_SANDBOX_HOSTNAME" keyHostnameArg = "build-arg:BUILDKIT_SANDBOX_HOSTNAME"
keyDockerfileLintArg = "build-arg:BUILDKIT_DOCKERFILE_CHECK" keyDockerfileLintArg = "build-arg:BUILDKIT_DOCKERFILE_CHECK"
keyContextKeepGitDirArg = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR" keyContextKeepGitDirArg = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR"
keySourceDateEpoch = "build-arg:SOURCE_DATE_EPOCH" keySourceDateEpoch = "build-arg:SOURCE_DATE_EPOCH"
keyCopyIgnoredCheckEnabled = "build-arg:BUILDKIT_DOCKERFILE_CHECK_COPYIGNORED_EXPERIMENT"
) )
type Config struct { type Config struct {
BuildArgs map[string]string BuildArgs map[string]string
CacheIDNamespace string CacheIDNamespace string
CgroupParent string CgroupParent string
Epoch *time.Time Epoch *time.Time
ExtraHosts []llb.HostIP ExtraHosts []llb.HostIP
Hostname string Hostname string
ImageResolveMode llb.ResolveMode ImageResolveMode llb.ResolveMode
Labels map[string]string Labels map[string]string
NetworkMode pb.NetMode NetworkMode pb.NetMode
ShmSize int64 ShmSize int64
Target string Target string
Ulimits []pb.Ulimit Ulimits []pb.Ulimit
LinterConfig *linter.Config LinterConfig *linter.Config
CopyIgnoredCheckEnabled bool
CacheImports []client.CacheOptionsEntry CacheImports []client.CacheOptionsEntry
TargetPlatforms []ocispecs.Platform // nil means default TargetPlatforms []ocispecs.Platform // nil means default
@@ -286,6 +288,16 @@ func (bc *Client) init() error {
return errors.Wrapf(err, "failed to parse %s", keyDockerfileLintArg) return errors.Wrapf(err, "failed to parse %s", keyDockerfileLintArg)
} }
} }
// CopyIgnoredCheckEnabled is an experimental feature to check if COPY is ignored by .dockerignore,
// and it is disabled by default. It is expected that this feature will be enabled by default in a future
// release, and this build-arg will be removed.
if v, ok := opts[keyCopyIgnoredCheckEnabled]; ok {
bc.CopyIgnoredCheckEnabled, err = strconv.ParseBool(v)
if err != nil {
return errors.Wrapf(err, "failed to parse %s", keyCopyIgnoredCheckEnabled)
}
}
return nil return nil
} }
@@ -410,44 +422,9 @@ func (bc *Client) MainContext(ctx context.Context, opts ...llb.LocalOption) (*ll
return bctx.context, nil return bctx.context, nil
} }
if bc.dockerignore == nil { excludes, err := bc.dockerIgnorePatterns(ctx, bctx)
st := llb.Local(bctx.contextLocalName, if err != nil {
llb.SessionID(bc.bopts.SessionID), return nil, errors.Wrapf(err, "failed to read dockerignore patterns")
llb.FollowPaths([]string{DefaultDockerignoreName}),
llb.SharedKeyHint(bctx.contextLocalName+"-"+DefaultDockerignoreName),
WithInternalName("load "+DefaultDockerignoreName),
llb.Differ(llb.DiffNone, false),
)
def, err := st.Marshal(ctx, bc.marshalOpts()...)
if err != nil {
return nil, err
}
res, err := bc.client.Solve(ctx, client.SolveRequest{
Definition: def.ToPB(),
})
if err != nil {
return nil, err
}
ref, err := res.SingleRef()
if err != nil {
return nil, err
}
dt, _ := ref.ReadFile(ctx, client.ReadRequest{ // ignore error
Filename: DefaultDockerignoreName,
})
if dt == nil {
dt = []byte{}
}
bc.dockerignore = dt
bc.dockerignoreName = DefaultDockerignoreName
}
var excludes []string
if len(bc.dockerignore) != 0 {
excludes, err = ignorefile.ReadAll(bytes.NewBuffer(bc.dockerignore))
if err != nil {
return nil, errors.Wrapf(err, "failed parsing %s", bc.dockerignoreName)
}
} }
opts = append([]llb.LocalOption{ opts = append([]llb.LocalOption{
@@ -493,6 +470,21 @@ func (bc *Client) IsNoCache(name string) bool {
return false return false
} }
func (bc *Client) DockerIgnorePatterns(ctx context.Context) ([]string, error) {
if bc == nil {
return nil, nil
}
bctx, err := bc.buildContext(ctx)
if err != nil {
return nil, err
}
if bctx.context != nil {
return nil, nil
}
return bc.dockerIgnorePatterns(ctx, bctx)
}
func DefaultMainContext(opts ...llb.LocalOption) *llb.State { func DefaultMainContext(opts ...llb.LocalOption) *llb.State {
opts = append([]llb.LocalOption{ opts = append([]llb.LocalOption{
llb.SharedKeyHint(DefaultLocalNameContext), llb.SharedKeyHint(DefaultLocalNameContext),
@@ -505,3 +497,46 @@ func DefaultMainContext(opts ...llb.LocalOption) *llb.State {
func WithInternalName(name string) llb.ConstraintsOpt { func WithInternalName(name string) llb.ConstraintsOpt {
return llb.WithCustomName("[internal] " + name) return llb.WithCustomName("[internal] " + name)
} }
func (bc *Client) dockerIgnorePatterns(ctx context.Context, bctx *buildContext) ([]string, error) {
if bc.dockerignore == nil {
st := llb.Local(bctx.contextLocalName,
llb.SessionID(bc.bopts.SessionID),
llb.FollowPaths([]string{DefaultDockerignoreName}),
llb.SharedKeyHint(bctx.contextLocalName+"-"+DefaultDockerignoreName),
WithInternalName("load "+DefaultDockerignoreName),
llb.Differ(llb.DiffNone, false),
)
def, err := st.Marshal(ctx, bc.marshalOpts()...)
if err != nil {
return nil, err
}
res, err := bc.client.Solve(ctx, client.SolveRequest{
Definition: def.ToPB(),
})
if err != nil {
return nil, err
}
ref, err := res.SingleRef()
if err != nil {
return nil, err
}
dt, _ := ref.ReadFile(ctx, client.ReadRequest{ // ignore error
Filename: DefaultDockerignoreName,
})
if dt == nil {
dt = []byte{}
}
bc.dockerignore = dt
bc.dockerignoreName = DefaultDockerignoreName
}
var err error
var excludes []string
if len(bc.dockerignore) != 0 {
excludes, err = ignorefile.ReadAll(bytes.NewBuffer(bc.dockerignore))
if err != nil {
return nil, errors.Wrapf(err, "failed parsing %s", bc.dockerignoreName)
}
}
return excludes, nil
}

View File

@@ -13,6 +13,7 @@ import (
"runtime" "runtime"
"sort" "sort"
"strings" "strings"
"sync"
"testing" "testing"
"time" "time"
@@ -161,10 +162,7 @@ func Run(t *testing.T, testCases []Test, opt ...TestOpt) {
o(&tc) o(&tc)
} }
mirror, cleanup, err := runMirror(t, tc.mirroredImages) getMirror := lazyMirrorRunnerFunc(t, tc.mirroredImages)
require.NoError(t, err)
t.Cleanup(func() { _ = cleanup() })
matrix := prepareValueMatrix(tc) matrix := prepareValueMatrix(tc)
@@ -200,7 +198,7 @@ func Run(t *testing.T, testCases []Test, opt ...TestOpt) {
ctx, cancel := context.WithCancelCause(ctx) ctx, cancel := context.WithCancelCause(ctx)
defer cancel(errors.WithStack(context.Canceled)) defer cancel(errors.WithStack(context.Canceled))
sb, closer, err := newSandbox(ctx, br, mirror, mv) sb, closer, err := newSandbox(ctx, br, getMirror(), mv)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { _ = closer() }) t.Cleanup(func() { _ = closer() })
defer func() { defer func() {
@@ -238,6 +236,11 @@ func copyImagesLocal(t *testing.T, host string, images map[string]string) error
} }
localImageCache[host][to] = struct{}{} localImageCache[host][to] = struct{}{}
// already exists check
if _, _, err := docker.NewResolver(docker.ResolverOptions{}).Resolve(context.TODO(), host+"/"+to); err == nil {
continue
}
var desc ocispecs.Descriptor var desc ocispecs.Descriptor
var provider content.Provider var provider content.Provider
var err error var err error
@@ -257,12 +260,6 @@ func copyImagesLocal(t *testing.T, host string, images map[string]string) error
} }
} }
// already exists check
_, _, err = docker.NewResolver(docker.ResolverOptions{}).Resolve(context.TODO(), host+"/"+to)
if err == nil {
continue
}
ingester, err := contentutil.IngesterFromRef(host + "/" + to) ingester, err := contentutil.IngesterFromRef(host + "/" + to)
if err != nil { if err != nil {
return err return err
@@ -329,6 +326,20 @@ func WriteConfig(updaters []ConfigUpdater) (string, error) {
return filepath.Join(tmpdir, buildkitdConfigFile), nil return filepath.Join(tmpdir, buildkitdConfigFile), nil
} }
func lazyMirrorRunnerFunc(t *testing.T, images map[string]string) func() string {
var once sync.Once
var mirror string
return func() string {
once.Do(func() {
host, cleanup, err := runMirror(t, images)
require.NoError(t, err)
t.Cleanup(func() { _ = cleanup() })
mirror = host
})
return mirror
}
}
func runMirror(t *testing.T, mirroredImages map[string]string) (host string, _ func() error, err error) { func runMirror(t *testing.T, mirroredImages map[string]string) (host string, _ func() error, err error) {
mirrorDir := os.Getenv("BUILDKIT_REGISTRY_MIRROR_DIR") mirrorDir := os.Getenv("BUILDKIT_REGISTRY_MIRROR_DIR")

View File

@@ -126,6 +126,7 @@ parseField:
appendToLast(dst, "\"") appendToLast(dst, "\"")
line = line[quoteLen:] line = line[quoteLen:]
pos += quoteLen pos += quoteLen
halfOpen = true
case rn == r.Comma: case rn == r.Comma:
// `",` sequence (end of field). // `",` sequence (end of field).
line = line[commaLen:] line = line[commaLen:]

View File

@@ -50,3 +50,8 @@ func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data [
func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) { func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
return mapper.Mremap(oldData, newLength, flags) return mapper.Mremap(oldData, newLength, flags)
} }
func MremapPtr(oldAddr unsafe.Pointer, oldSize uintptr, newAddr unsafe.Pointer, newSize uintptr, flags int) (ret unsafe.Pointer, err error) {
xaddr, err := mapper.mremap(uintptr(oldAddr), oldSize, newSize, flags, uintptr(newAddr))
return unsafe.Pointer(xaddr), err
}

View File

@@ -542,6 +542,18 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
} }
} }
//sys pthread_chdir_np(path string) (err error)
func PthreadChdir(path string) (err error) {
return pthread_chdir_np(path)
}
//sys pthread_fchdir_np(fd int) (err error)
func PthreadFchdir(fd int) (err error) {
return pthread_fchdir_np(fd)
}
//sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) //sys sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error) //sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)

View File

@@ -154,6 +154,15 @@ func Munmap(b []byte) (err error) {
return mapper.Munmap(b) return mapper.Munmap(b)
} }
func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) {
xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset)
return unsafe.Pointer(xaddr), err
}
func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) {
return mapper.munmap(uintptr(addr), length)
}
func Read(fd int, p []byte) (n int, err error) { func Read(fd int, p []byte) (n int, err error) {
n, err = read(fd, p) n, err = read(fd, p)
if raceenabled { if raceenabled {

View File

@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_chdir_np(path string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_chdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_fchdir_np(fd int) (err error) {
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_fchdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 { if e1 != 0 {

View File

@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_chdir_np(SB)
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_fchdir_np(SB)
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB) JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8

View File

@@ -760,6 +760,39 @@ var libc_sysctl_trampoline_addr uintptr
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_chdir_np(path string) (err error) {
var _p0 *byte
_p0, err = BytePtrFromString(path)
if err != nil {
return
}
_, _, e1 := syscall_syscall(libc_pthread_chdir_np_trampoline_addr, uintptr(unsafe.Pointer(_p0)), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_chdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_chdir_np pthread_chdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func pthread_fchdir_np(fd int) (err error) {
_, _, e1 := syscall_syscall(libc_pthread_fchdir_np_trampoline_addr, uintptr(fd), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
var libc_pthread_fchdir_np_trampoline_addr uintptr
//go:cgo_import_dynamic libc_pthread_fchdir_np pthread_fchdir_np "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) { func sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error) {
_, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags)) _, _, e1 := syscall_syscall6(libc_sendfile_trampoline_addr, uintptr(infd), uintptr(outfd), uintptr(offset), uintptr(unsafe.Pointer(len)), uintptr(hdtr), uintptr(flags))
if e1 != 0 { if e1 != 0 {

View File

@@ -228,6 +228,16 @@ TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0
GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8
DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB)
TEXT libc_pthread_chdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_chdir_np(SB)
GLOBL ·libc_pthread_chdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_chdir_np_trampoline_addr(SB)/8, $libc_pthread_chdir_np_trampoline<>(SB)
TEXT libc_pthread_fchdir_np_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_pthread_fchdir_np(SB)
GLOBL ·libc_pthread_fchdir_np_trampoline_addr(SB), RODATA, $8
DATA ·libc_pthread_fchdir_np_trampoline_addr(SB)/8, $libc_pthread_fchdir_np_trampoline<>(SB)
TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0
JMP libc_sendfile(SB) JMP libc_sendfile(SB)
GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8

View File

@@ -894,7 +894,7 @@ type ACL struct {
aclRevision byte aclRevision byte
sbz1 byte sbz1 byte
aclSize uint16 aclSize uint16
aceCount uint16 AceCount uint16
sbz2 uint16 sbz2 uint16
} }
@@ -1087,6 +1087,27 @@ type EXPLICIT_ACCESS struct {
Trustee TRUSTEE Trustee TRUSTEE
} }
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
type ACE_HEADER struct {
AceType uint8
AceFlags uint8
AceSize uint16
}
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
type ACCESS_ALLOWED_ACE struct {
Header ACE_HEADER
Mask ACCESS_MASK
SidStart uint32
}
const (
// Constants for AceType
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
ACCESS_ALLOWED_ACE_TYPE = 0
ACCESS_DENIED_ACE_TYPE = 1
)
// This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions. // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
type TrusteeValue uintptr type TrusteeValue uintptr
@@ -1158,6 +1179,7 @@ type OBJECTS_AND_NAME struct {
//sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD //sys makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
//sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW //sys setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
//sys GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) = advapi32.GetAce
// Control returns the security descriptor control bits. // Control returns the security descriptor control bits.
func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) { func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {

View File

@@ -91,6 +91,7 @@ var (
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW") procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procEqualSid = modadvapi32.NewProc("EqualSid") procEqualSid = modadvapi32.NewProc("EqualSid")
procFreeSid = modadvapi32.NewProc("FreeSid") procFreeSid = modadvapi32.NewProc("FreeSid")
procGetAce = modadvapi32.NewProc("GetAce")
procGetLengthSid = modadvapi32.NewProc("GetLengthSid") procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW") procGetNamedSecurityInfoW = modadvapi32.NewProc("GetNamedSecurityInfoW")
procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl") procGetSecurityDescriptorControl = modadvapi32.NewProc("GetSecurityDescriptorControl")
@@ -1224,6 +1225,14 @@ func setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCE
return return
} }
func GetAce(acl *ACL, aceIndex uint32, pAce **ACCESS_ALLOWED_ACE) (ret error) {
r0, _, _ := syscall.Syscall(procGetAce.Addr(), 3, uintptr(unsafe.Pointer(acl)), uintptr(aceIndex), uintptr(unsafe.Pointer(pAce)))
if r0 == 0 {
ret = GetLastError()
}
return
}
func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) { func SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) {
r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor))) r1, _, e1 := syscall.Syscall(procSetKernelObjectSecurity.Addr(), 3, uintptr(handle), uintptr(securityInformation), uintptr(unsafe.Pointer(securityDescriptor)))
if r1 == 0 { if r1 == 0 {

8
vendor/modules.txt vendored
View File

@@ -357,7 +357,7 @@ github.com/go-openapi/swag
## explicit; go 1.18 ## explicit; go 1.18
github.com/go-viper/mapstructure/v2 github.com/go-viper/mapstructure/v2
github.com/go-viper/mapstructure/v2/internal/errors github.com/go-viper/mapstructure/v2/internal/errors
# github.com/gofrs/flock v0.12.0 # github.com/gofrs/flock v0.12.1
## explicit; go 1.21.0 ## explicit; go 1.21.0
github.com/gofrs/flock github.com/gofrs/flock
# github.com/gogo/googleapis v1.4.1 # github.com/gogo/googleapis v1.4.1
@@ -518,7 +518,7 @@ github.com/mitchellh/go-wordwrap
github.com/mitchellh/hashstructure/v2 github.com/mitchellh/hashstructure/v2
# github.com/mitchellh/mapstructure v1.5.0 # github.com/mitchellh/mapstructure v1.5.0
## explicit; go 1.14 ## explicit; go 1.14
# github.com/moby/buildkit v0.15.0-rc1 # github.com/moby/buildkit v0.15.1
## explicit; go 1.21.0 ## explicit; go 1.21.0
github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types github.com/moby/buildkit/api/types
@@ -728,7 +728,7 @@ github.com/theupdateframework/notary/tuf/validation
## explicit; go 1.20 ## explicit; go 1.20
github.com/tonistiigi/fsutil github.com/tonistiigi/fsutil
github.com/tonistiigi/fsutil/types github.com/tonistiigi/fsutil/types
# github.com/tonistiigi/go-csvvalue v0.0.0-20240619222358-bb8dd5cba3c2 # github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4
## explicit; go 1.16 ## explicit; go 1.16
github.com/tonistiigi/go-csvvalue github.com/tonistiigi/go-csvvalue
# github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea # github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
@@ -897,7 +897,7 @@ golang.org/x/oauth2/internal
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sync/errgroup golang.org/x/sync/errgroup
golang.org/x/sync/semaphore golang.org/x/sync/semaphore
# golang.org/x/sys v0.21.0 # golang.org/x/sys v0.22.0
## explicit; go 1.18 ## explicit; go 1.18
golang.org/x/sys/cpu golang.org/x/sys/cpu
golang.org/x/sys/plan9 golang.org/x/sys/plan9