From b1cb658a3184904d6d30055f5b4e6c331147fb07 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Sternberg" Date: Fri, 31 May 2024 16:11:33 -0500 Subject: [PATCH 1/2] vendor: update buildkit to v0.14.0-rc1 Update buildkit dependency to v0.14.0-rc1. Update the tracing infrastructure to use the new detect API which updates how the delegated exporter is configured. Signed-off-by: Jonathan A. Sternberg --- cmd/buildx/tracing.go | 1 - driver/manager.go | 21 +- go.mod | 23 +- go.sum | 43 +- util/tracing/trace.go | 18 +- .../Microsoft/go-winio/.golangci.yml | 10 +- .../github.com/Microsoft/go-winio/backup.go | 33 +- vendor/github.com/Microsoft/go-winio/file.go | 85 ++- .../github.com/Microsoft/go-winio/fileinfo.go | 22 +- .../github.com/Microsoft/go-winio/hvsock.go | 47 +- .../Microsoft/go-winio/internal/fs/fs.go | 72 ++- .../go-winio/internal/fs/zsyscall_windows.go | 9 +- .../go-winio/internal/socket/socket.go | 8 +- .../internal/socket/zsyscall_windows.go | 9 +- .../go-winio/internal/stringbuffer/wstring.go | 2 +- vendor/github.com/Microsoft/go-winio/pipe.go | 125 ++-- .../Microsoft/go-winio/privilege.go | 9 +- vendor/github.com/Microsoft/go-winio/sd.go | 37 +- vendor/github.com/Microsoft/go-winio/tools.go | 5 - .../Microsoft/go-winio/zsyscall_windows.go | 211 +++---- .../containerd/containerd/images/diffid.go | 2 +- .../containerd/images/mediatypes.go | 2 +- .../containerd/remotes/docker/authorizer.go | 18 +- .../containerd/remotes/docker/resolver.go | 70 +++ .../containerd/containerd/version/version.go | 2 +- vendor/github.com/containerd/ttrpc/client.go | 37 +- vendor/github.com/docker/docker/AUTHORS | 9 + .../docker/docker/pkg/system/stat_illumos.go | 15 + vendor/github.com/hashicorp/errwrap/LICENSE | 354 ++++++++++++ vendor/github.com/hashicorp/errwrap/README.md | 89 +++ .../github.com/hashicorp/errwrap/errwrap.go | 178 ++++++ .../hashicorp/go-multierror/LICENSE | 353 ++++++++++++ .../hashicorp/go-multierror/Makefile | 31 + .../hashicorp/go-multierror/README.md | 150 +++++ .../hashicorp/go-multierror/append.go | 43 ++ .../hashicorp/go-multierror/flatten.go | 26 + .../hashicorp/go-multierror/format.go | 27 + .../hashicorp/go-multierror/group.go | 38 ++ .../hashicorp/go-multierror/multierror.go | 121 ++++ .../hashicorp/go-multierror/prefix.go | 37 ++ .../hashicorp/go-multierror/sort.go | 16 + .../client/connhelper/npipe/npipe_windows.go | 2 +- .../buildkit/cmd/buildkitd/config/config.go | 31 +- .../buildkit/cmd/buildkitd/config/gcpolicy.go | 23 + .../cmd/buildkitd/config/gcpolicy_openbsd.go | 19 + .../cmd/buildkitd/config/gcpolicy_unix.go | 22 +- .../cmd/buildkitd/config/gcpolicy_windows.go | 29 +- .../frontend/dockerfile/parser/directives.go | 32 +- .../dockerfile/parser/line_parsers.go | 15 +- .../buildkit/frontend/dockerfile/shell/lex.go | 53 +- .../moby/buildkit/frontend/dockerui/config.go | 6 + .../frontend/gateway/grpcclient/client.go | 15 +- .../frontend/subrequests/lint/lint.go | 6 + .../frontend/subrequests/targets/targets.go | 6 +- .../sshforward/sshprovider/agentprovider.go | 1 + .../moby/buildkit/util/gitutil/git_cli.go | 12 +- .../buildkit/util/progress/multireader.go | 1 + .../util/progress/progressui/display.go | 7 +- .../buildkit/util/progress/progressui/init.go | 6 +- .../moby/buildkit/util/system/path.go | 4 +- .../buildkit/util/testutil/integration/run.go | 4 + .../util/testutil/integration/sandbox.go | 5 + .../buildkit/util/testutil/workers/util.go | 4 + .../{detect => }/delegated/delegated.go | 15 +- .../buildkit/util/tracing/detect/detect.go | 253 +++------ .../buildkit/util/tracing/detect/resource.go | 58 ++ .../util/tracing/multi_span_exporter.go | 36 ++ .../image-spec/specs-go/v1/mediatype.go | 28 +- .../image-spec/specs-go/version.go | 2 +- .../tonistiigi/fsutil/diff_containerd.go | 2 +- .../tonistiigi/fsutil/diskwriter.go | 20 +- .../github.com/tonistiigi/fsutil/hardlinks.go | 68 +++ .../github.com/tonistiigi/fsutil/receive.go | 45 +- vendor/github.com/tonistiigi/fsutil/send.go | 3 +- vendor/github.com/tonistiigi/vt100/vt100.go | 1 + .../otel/exporters/prometheus/LICENSE | 201 ------- .../otel/exporters/prometheus/config.go | 153 ----- .../otel/exporters/prometheus/doc.go | 18 - .../otel/exporters/prometheus/exporter.go | 533 ------------------ vendor/modules.txt | 33 +- 80 files changed, 2583 insertions(+), 1597 deletions(-) delete mode 100644 vendor/github.com/Microsoft/go-winio/tools.go create mode 100644 vendor/github.com/docker/docker/pkg/system/stat_illumos.go create mode 100644 vendor/github.com/hashicorp/errwrap/LICENSE create mode 100644 vendor/github.com/hashicorp/errwrap/README.md create mode 100644 vendor/github.com/hashicorp/errwrap/errwrap.go create mode 100644 vendor/github.com/hashicorp/go-multierror/LICENSE create mode 100644 vendor/github.com/hashicorp/go-multierror/Makefile create mode 100644 vendor/github.com/hashicorp/go-multierror/README.md create mode 100644 vendor/github.com/hashicorp/go-multierror/append.go create mode 100644 vendor/github.com/hashicorp/go-multierror/flatten.go create mode 100644 vendor/github.com/hashicorp/go-multierror/format.go create mode 100644 vendor/github.com/hashicorp/go-multierror/group.go create mode 100644 vendor/github.com/hashicorp/go-multierror/multierror.go create mode 100644 vendor/github.com/hashicorp/go-multierror/prefix.go create mode 100644 vendor/github.com/hashicorp/go-multierror/sort.go create mode 100644 vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_openbsd.go rename vendor/github.com/moby/buildkit/util/tracing/{detect => }/delegated/delegated.go (80%) create mode 100644 vendor/github.com/moby/buildkit/util/tracing/detect/resource.go create mode 100644 vendor/github.com/moby/buildkit/util/tracing/multi_span_exporter.go delete mode 100644 vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE delete mode 100644 vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go delete mode 100644 vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go delete mode 100644 vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go diff --git a/cmd/buildx/tracing.go b/cmd/buildx/tracing.go index fb7338a0..e550fd55 100644 --- a/cmd/buildx/tracing.go +++ b/cmd/buildx/tracing.go @@ -4,7 +4,6 @@ import ( "github.com/moby/buildkit/util/tracing/detect" "go.opentelemetry.io/otel" - _ "github.com/moby/buildkit/util/tracing/detect/delegated" _ "github.com/moby/buildkit/util/tracing/env" ) diff --git a/driver/manager.go b/driver/manager.go index 8e30a242..746fd8f2 100644 --- a/driver/manager.go +++ b/driver/manager.go @@ -9,7 +9,7 @@ import ( dockerclient "github.com/docker/docker/client" "github.com/moby/buildkit/client" - "github.com/moby/buildkit/util/tracing/detect" + "github.com/moby/buildkit/util/tracing/delegated" specs "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "k8s.io/client-go/rest" @@ -157,26 +157,15 @@ type DriverHandle struct { func (d *DriverHandle) Client(ctx context.Context) (*client.Client, error) { d.once.Do(func() { - opts, err := d.getClientOptions() - if err != nil { - d.err = err - return - } - d.client, d.err = d.Driver.Client(ctx, opts...) + d.client, d.err = d.Driver.Client(ctx, d.getClientOptions()...) }) return d.client, d.err } -func (d *DriverHandle) getClientOptions() ([]client.ClientOpt, error) { - exp, _, err := detect.Exporter() - if err != nil { - return nil, err - } else if td, ok := exp.(client.TracerDelegate); ok { - return []client.ClientOpt{ - client.WithTracerDelegate(td), - }, nil +func (d *DriverHandle) getClientOptions() []client.ClientOpt { + return []client.ClientOpt{ + client.WithTracerDelegate(delegated.DefaultExporter), } - return nil, nil } func (d *DriverHandle) HistoryAPISupported(ctx context.Context) bool { diff --git a/go.mod b/go.mod index 32decf06..7181c0de 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,11 @@ go 1.21 require ( github.com/Masterminds/semver/v3 v3.2.1 - github.com/Microsoft/go-winio v0.6.1 + github.com/Microsoft/go-winio v0.6.2 github.com/aws/aws-sdk-go-v2/config v1.26.6 github.com/compose-spec/compose-go/v2 v2.1.1 github.com/containerd/console v1.0.4 - github.com/containerd/containerd v1.7.15 + github.com/containerd/containerd v1.7.17 github.com/containerd/continuity v0.4.3 github.com/containerd/log v0.1.0 github.com/containerd/typeurl/v2 v2.1.1 @@ -16,7 +16,7 @@ require ( github.com/distribution/reference v0.5.0 github.com/docker/cli v26.1.3+incompatible github.com/docker/cli-docs-tool v0.7.0 - github.com/docker/docker v26.0.0+incompatible + github.com/docker/docker v26.1.3+incompatible github.com/docker/go-units v0.5.0 github.com/gofrs/flock v0.8.1 github.com/gogo/protobuf v1.3.2 @@ -26,12 +26,12 @@ require ( github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992 github.com/hashicorp/hcl/v2 v2.20.1 github.com/in-toto/in-toto-golang v0.5.0 - github.com/moby/buildkit v0.13.0-rc3.0.20240417151852-71f99c52a669 // v0.14.0-dev + github.com/moby/buildkit v0.14.0-rc1 github.com/moby/sys/mountinfo v0.7.1 github.com/moby/sys/signal v0.7.0 github.com/morikuni/aec v1.0.0 github.com/opencontainers/go-digest v1.0.0 - github.com/opencontainers/image-spec v1.1.0-rc5 + github.com/opencontainers/image-spec v1.1.0 github.com/pelletier/go-toml v1.9.5 github.com/pkg/errors v0.9.1 github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b @@ -39,10 +39,11 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 - github.com/tonistiigi/fsutil v0.0.0-20240301111122-7525a1af2bb5 + github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c github.com/zclconf/go-cty v1.14.4 go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/metric v1.21.0 + go.opentelemetry.io/otel/sdk v1.21.0 go.opentelemetry.io/otel/trace v1.21.0 golang.org/x/mod v0.14.0 golang.org/x/sync v0.6.0 @@ -58,7 +59,7 @@ require ( require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/hcsshim v0.11.4 // indirect + github.com/Microsoft/hcsshim v0.11.5 // indirect github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-cidr v1.0.1 // indirect @@ -78,7 +79,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/containerd/ttrpc v1.2.3 // indirect + github.com/containerd/ttrpc v1.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.0 // indirect @@ -100,7 +101,9 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -136,7 +139,7 @@ require ( github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/theupdateframework/notary v0.7.0 // indirect github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect - github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect + github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect @@ -149,8 +152,6 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.42.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect golang.org/x/crypto v0.21.0 // indirect diff --git a/go.sum b/go.sum index febfdcfe..772ae725 100644 --- a/go.sum +++ b/go.sum @@ -13,10 +13,10 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hcsshim v0.11.5 h1:haEcLNpj9Ka1gd3B3tAEs9CpE0c+1IhoL59w/exYU38= +github.com/Microsoft/hcsshim v0.11.5/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -90,8 +90,8 @@ github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaD github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= -github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= +github.com/containerd/containerd v1.7.17 h1:KjNnn0+tAVQHAoaWRjmdak9WlvnFR/8rU1CHHy8Rm2A= +github.com/containerd/containerd v1.7.17/go.mod h1:vK+hhT4TIv2uejlcDlbVIc8+h/BqtKLIyNrtCZol8lI= github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8= github.com/containerd/continuity v0.4.3/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= @@ -103,8 +103,8 @@ github.com/containerd/nydus-snapshotter v0.13.7/go.mod h1:VPVKQ3jmHFIcUIV2yiQ1kI github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0= -github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM= +github.com/containerd/ttrpc v1.2.4 h1:eQCQK4h9dxDmpOb9QOOMh2NHTfzroH1IkmHiKZi05Oo= +github.com/containerd/ttrpc v1.2.4/go.mod h1:ojvb8SJBSch0XkqNO0L0YX/5NxR3UnVk2LzFKBK0upc= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -124,8 +124,8 @@ github.com/docker/cli-docs-tool v0.7.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbI github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v26.0.0+incompatible h1:Ng2qi+gdKADUa/VM+6b6YaY2nlZhk/lVJiKR/2bMudU= -github.com/docker/docker v26.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo= +github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= @@ -225,10 +225,15 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rH github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992 h1:fYOrSfO5C9PmFGtmRWSYGqq52SOoE2dXMtAn2Xzh1LQ= github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992/go.mod h1:Abjk0jbRkDaNCzsRhOv2iDCofYpX1eVsjozoiK63qLA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -293,8 +298,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/buildkit v0.13.0-rc3.0.20240417151852-71f99c52a669 h1:DnnuoY7BDEXoW4qbDHBvWy2lCzus6AO4CJGaEq94e7M= -github.com/moby/buildkit v0.13.0-rc3.0.20240417151852-71f99c52a669/go.mod h1:iqJg3dy9wLt5maCeC8WBbDISnLvuSX+R9jVNzg2zACU= +github.com/moby/buildkit v0.14.0-rc1 h1:pdnGXXT0Wu480PMQzyFUBN/LgtfIwlYoLlT7jba1IVQ= +github.com/moby/buildkit v0.14.0-rc1/go.mod h1:J3TW5gH3fc2BVrLnqxnGGQauChFwCzhv6FPkBKTGciU= 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= @@ -341,8 +346,8 @@ github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= @@ -426,12 +431,12 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= -github.com/tonistiigi/fsutil v0.0.0-20240301111122-7525a1af2bb5 h1:oZS8KCqAg62sxJkEq/Ppzqrb6EooqzWtL8Oaex7bc5c= -github.com/tonistiigi/fsutil v0.0.0-20240301111122-7525a1af2bb5/go.mod h1:vbbYqJlnswsbJqWUcJN8fKtBhnEgldDrcagTgnBVKKM= +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/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/vt100 v0.0.0-20230623042737-f9a4f7ef6531 h1:Y/M5lygoNPKwVNLMPXgVfsRT40CSFKXCxuU8LoHySjs= -github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= +github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw= +github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc= github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -471,8 +476,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqhe go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/prometheus v0.42.0 h1:jwV9iQdvp38fxXi8ZC+lNpxjK16MRcZlpDYvbuO1FiA= -go.opentelemetry.io/otel/exporters/prometheus v0.42.0/go.mod h1:f3bYiqNqhoPxkvI2LrXqQVC546K7BuRDL/kKuxkujhA= go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= diff --git a/util/tracing/trace.go b/util/tracing/trace.go index c95ad5a4..d16ca9f9 100644 --- a/util/tracing/trace.go +++ b/util/tracing/trace.go @@ -5,16 +5,26 @@ import ( "os" "strings" + "github.com/moby/buildkit/util/tracing/delegated" "github.com/moby/buildkit/util/tracing/detect" + "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" ) func TraceCurrentCommand(ctx context.Context, name string) (context.Context, func(error), error) { - tp, err := detect.TracerProvider() - if err != nil { - return context.Background(), nil, err + opts := []sdktrace.TracerProviderOption{ + sdktrace.WithResource(detect.Resource()), + sdktrace.WithBatcher(delegated.DefaultExporter), } + if exp, err := detect.NewSpanExporter(ctx); err != nil { + otel.Handle(err) + } else if !detect.IsNoneSpanExporter(exp) { + opts = append(opts, sdktrace.WithBatcher(exp)) + } + + tp := sdktrace.NewTracerProvider(opts...) ctx, span := tp.Tracer("").Start(ctx, name, trace.WithAttributes( attribute.String("command", strings.Join(os.Args, " ")), )) @@ -25,6 +35,6 @@ func TraceCurrentCommand(ctx context.Context, name string) (context.Context, fun } span.End() - detect.Shutdown(context.TODO()) + _ = tp.Shutdown(context.TODO()) }, nil } diff --git a/vendor/github.com/Microsoft/go-winio/.golangci.yml b/vendor/github.com/Microsoft/go-winio/.golangci.yml index 7b503d26..faedfe93 100644 --- a/vendor/github.com/Microsoft/go-winio/.golangci.yml +++ b/vendor/github.com/Microsoft/go-winio/.golangci.yml @@ -1,7 +1,3 @@ -run: - skip-dirs: - - pkg/etw/sample - linters: enable: # style @@ -20,9 +16,13 @@ linters: - gofmt # files are gofmt'ed - gosec # security - nilerr # returns nil even with non-nil error + - thelper # test helpers without t.Helper() - unparam # unused function params issues: + exclude-dirs: + - pkg/etw/sample + exclude-rules: # err is very often shadowed in nested scopes - linters: @@ -69,9 +69,7 @@ linters-settings: # struct order is often for Win32 compat # also, ignore pointer bytes/GC issues for now until performance becomes an issue - fieldalignment - check-shadowing: true nolintlint: - allow-leading-space: false require-explanation: true require-specific: true revive: diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go index 09621c88..b54341da 100644 --- a/vendor/github.com/Microsoft/go-winio/backup.go +++ b/vendor/github.com/Microsoft/go-winio/backup.go @@ -10,14 +10,14 @@ import ( "io" "os" "runtime" - "syscall" "unicode/utf16" + "github.com/Microsoft/go-winio/internal/fs" "golang.org/x/sys/windows" ) -//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead -//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite +//sys backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead +//sys backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite const ( BackupData = uint32(iota + 1) @@ -104,7 +104,7 @@ func (r *BackupStreamReader) Next() (*BackupHeader, error) { if err := binary.Read(r.r, binary.LittleEndian, name); err != nil { return nil, err } - hdr.Name = syscall.UTF16ToString(name) + hdr.Name = windows.UTF16ToString(name) } if wsi.StreamID == BackupSparseBlock { if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil { @@ -205,7 +205,7 @@ func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader { // Read reads a backup stream from the file by calling the Win32 API BackupRead(). func (r *BackupFileReader) Read(b []byte) (int, error) { var bytesRead uint32 - err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx) + err := backupRead(windows.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx) if err != nil { return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err} } @@ -220,7 +220,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) { // the underlying file. func (r *BackupFileReader) Close() error { if r.ctx != 0 { - _ = backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) + _ = backupRead(windows.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) runtime.KeepAlive(r.f) r.ctx = 0 } @@ -244,7 +244,7 @@ func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter { // Write restores a portion of the file using the provided backup stream. func (w *BackupFileWriter) Write(b []byte) (int, error) { var bytesWritten uint32 - err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx) + err := backupWrite(windows.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx) if err != nil { return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err} } @@ -259,7 +259,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) { // close the underlying file. func (w *BackupFileWriter) Close() error { if w.ctx != 0 { - _ = backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) + _ = backupWrite(windows.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) runtime.KeepAlive(w.f) w.ctx = 0 } @@ -271,17 +271,14 @@ func (w *BackupFileWriter) Close() error { // // If the file opened was a directory, it cannot be used with Readdir(). func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) { - winPath, err := syscall.UTF16FromString(path) - if err != nil { - return nil, err - } - h, err := syscall.CreateFile(&winPath[0], - access, - share, + h, err := fs.CreateFile(path, + fs.AccessMask(access), + fs.FileShareMode(share), nil, - createmode, - syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT, - 0) + fs.FileCreationDisposition(createmode), + fs.FILE_FLAG_BACKUP_SEMANTICS|fs.FILE_FLAG_OPEN_REPARSE_POINT, + 0, + ) if err != nil { err = &os.PathError{Op: "open", Path: path, Err: err} return nil, err diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go index 175a99d3..fe82a180 100644 --- a/vendor/github.com/Microsoft/go-winio/file.go +++ b/vendor/github.com/Microsoft/go-winio/file.go @@ -15,26 +15,11 @@ import ( "golang.org/x/sys/windows" ) -//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx -//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort -//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus -//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes -//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult - -type atomicBool int32 - -func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 } -func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) } -func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) } - -//revive:disable-next-line:predeclared Keep "new" to maintain consistency with "atomic" pkg -func (b *atomicBool) swap(new bool) bool { - var newInt int32 - if new { - newInt = 1 - } - return atomic.SwapInt32((*int32)(b), newInt) == 1 -} +//sys cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) = CancelIoEx +//sys createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) = CreateIoCompletionPort +//sys getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus +//sys setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes +//sys wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult var ( ErrFileClosed = errors.New("file has already been closed") @@ -50,7 +35,7 @@ func (*timeoutError) Temporary() bool { return true } type timeoutChan chan struct{} var ioInitOnce sync.Once -var ioCompletionPort syscall.Handle +var ioCompletionPort windows.Handle // ioResult contains the result of an asynchronous IO operation. type ioResult struct { @@ -60,12 +45,12 @@ type ioResult struct { // ioOperation represents an outstanding asynchronous Win32 IO. type ioOperation struct { - o syscall.Overlapped + o windows.Overlapped ch chan ioResult } func initIO() { - h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff) + h, err := createIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff) if err != nil { panic(err) } @@ -76,10 +61,10 @@ func initIO() { // win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall. // It takes ownership of this handle and will close it if it is garbage collected. type win32File struct { - handle syscall.Handle + handle windows.Handle wg sync.WaitGroup wgLock sync.RWMutex - closing atomicBool + closing atomic.Bool socket bool readDeadline deadlineHandler writeDeadline deadlineHandler @@ -90,11 +75,11 @@ type deadlineHandler struct { channel timeoutChan channelLock sync.RWMutex timer *time.Timer - timedout atomicBool + timedout atomic.Bool } // makeWin32File makes a new win32File from an existing file handle. -func makeWin32File(h syscall.Handle) (*win32File, error) { +func makeWin32File(h windows.Handle) (*win32File, error) { f := &win32File{handle: h} ioInitOnce.Do(initIO) _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) @@ -110,7 +95,12 @@ func makeWin32File(h syscall.Handle) (*win32File, error) { return f, nil } +// Deprecated: use NewOpenFile instead. func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { + return NewOpenFile(windows.Handle(h)) +} + +func NewOpenFile(h windows.Handle) (io.ReadWriteCloser, error) { // If we return the result of makeWin32File directly, it can result in an // interface-wrapped nil, rather than a nil interface value. f, err := makeWin32File(h) @@ -124,13 +114,13 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { func (f *win32File) closeHandle() { f.wgLock.Lock() // Atomically set that we are closing, releasing the resources only once. - if !f.closing.swap(true) { + if !f.closing.Swap(true) { f.wgLock.Unlock() // cancel all IO and wait for it to complete _ = cancelIoEx(f.handle, nil) f.wg.Wait() // at this point, no new IO can start - syscall.Close(f.handle) + windows.Close(f.handle) f.handle = 0 } else { f.wgLock.Unlock() @@ -145,14 +135,14 @@ func (f *win32File) Close() error { // IsClosed checks if the file has been closed. func (f *win32File) IsClosed() bool { - return f.closing.isSet() + return f.closing.Load() } // prepareIO prepares for a new IO operation. // The caller must call f.wg.Done() when the IO is finished, prior to Close() returning. func (f *win32File) prepareIO() (*ioOperation, error) { f.wgLock.RLock() - if f.closing.isSet() { + if f.closing.Load() { f.wgLock.RUnlock() return nil, ErrFileClosed } @@ -164,12 +154,12 @@ func (f *win32File) prepareIO() (*ioOperation, error) { } // ioCompletionProcessor processes completed async IOs forever. -func ioCompletionProcessor(h syscall.Handle) { +func ioCompletionProcessor(h windows.Handle) { for { var bytes uint32 var key uintptr var op *ioOperation - err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE) + err := getQueuedCompletionStatus(h, &bytes, &key, &op, windows.INFINITE) if op == nil { panic(err) } @@ -182,11 +172,11 @@ func ioCompletionProcessor(h syscall.Handle) { // asyncIO processes the return value from ReadFile or WriteFile, blocking until // the operation has actually completed. func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) { - if err != syscall.ERROR_IO_PENDING { //nolint:errorlint // err is Errno + if err != windows.ERROR_IO_PENDING { //nolint:errorlint // err is Errno return int(bytes), err } - if f.closing.isSet() { + if f.closing.Load() { _ = cancelIoEx(f.handle, &c.o) } @@ -201,8 +191,8 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er select { case r = <-c.ch: err = r.err - if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno - if f.closing.isSet() { + if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno + if f.closing.Load() { err = ErrFileClosed } } else if err != nil && f.socket { @@ -214,7 +204,7 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er _ = cancelIoEx(f.handle, &c.o) r = <-c.ch err = r.err - if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno + if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno err = ErrTimeout } } @@ -235,23 +225,22 @@ func (f *win32File) Read(b []byte) (int, error) { } defer f.wg.Done() - if f.readDeadline.timedout.isSet() { + if f.readDeadline.timedout.Load() { return 0, ErrTimeout } var bytes uint32 - err = syscall.ReadFile(f.handle, b, &bytes, &c.o) + err = windows.ReadFile(f.handle, b, &bytes, &c.o) n, err := f.asyncIO(c, &f.readDeadline, bytes, err) runtime.KeepAlive(b) // Handle EOF conditions. if err == nil && n == 0 && len(b) != 0 { return 0, io.EOF - } else if err == syscall.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno + } else if err == windows.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno return 0, io.EOF - } else { - return n, err } + return n, err } // Write writes to a file handle. @@ -262,12 +251,12 @@ func (f *win32File) Write(b []byte) (int, error) { } defer f.wg.Done() - if f.writeDeadline.timedout.isSet() { + if f.writeDeadline.timedout.Load() { return 0, ErrTimeout } var bytes uint32 - err = syscall.WriteFile(f.handle, b, &bytes, &c.o) + err = windows.WriteFile(f.handle, b, &bytes, &c.o) n, err := f.asyncIO(c, &f.writeDeadline, bytes, err) runtime.KeepAlive(b) return n, err @@ -282,7 +271,7 @@ func (f *win32File) SetWriteDeadline(deadline time.Time) error { } func (f *win32File) Flush() error { - return syscall.FlushFileBuffers(f.handle) + return windows.FlushFileBuffers(f.handle) } func (f *win32File) Fd() uintptr { @@ -299,7 +288,7 @@ func (d *deadlineHandler) set(deadline time.Time) error { } d.timer = nil } - d.timedout.setFalse() + d.timedout.Store(false) select { case <-d.channel: @@ -314,7 +303,7 @@ func (d *deadlineHandler) set(deadline time.Time) error { } timeoutIO := func() { - d.timedout.setTrue() + d.timedout.Store(true) close(d.channel) } diff --git a/vendor/github.com/Microsoft/go-winio/fileinfo.go b/vendor/github.com/Microsoft/go-winio/fileinfo.go index 702950e7..c860eb99 100644 --- a/vendor/github.com/Microsoft/go-winio/fileinfo.go +++ b/vendor/github.com/Microsoft/go-winio/fileinfo.go @@ -18,9 +18,18 @@ type FileBasicInfo struct { _ uint32 // padding } +// alignedFileBasicInfo is a FileBasicInfo, but aligned to uint64 by containing +// uint64 rather than windows.Filetime. Filetime contains two uint32s. uint64 +// alignment is necessary to pass this as FILE_BASIC_INFO. +type alignedFileBasicInfo struct { + CreationTime, LastAccessTime, LastWriteTime, ChangeTime uint64 + FileAttributes uint32 + _ uint32 // padding +} + // GetFileBasicInfo retrieves times and attributes for a file. func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { - bi := &FileBasicInfo{} + bi := &alignedFileBasicInfo{} if err := windows.GetFileInformationByHandleEx( windows.Handle(f.Fd()), windows.FileBasicInfo, @@ -30,16 +39,21 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} } runtime.KeepAlive(f) - return bi, nil + // Reinterpret the alignedFileBasicInfo as a FileBasicInfo so it matches the + // public API of this module. The data may be unnecessarily aligned. + return (*FileBasicInfo)(unsafe.Pointer(bi)), nil } // SetFileBasicInfo sets times and attributes for a file. func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { + // Create an alignedFileBasicInfo based on a FileBasicInfo. The copy is + // suitable to pass to GetFileInformationByHandleEx. + biAligned := *(*alignedFileBasicInfo)(unsafe.Pointer(bi)) if err := windows.SetFileInformationByHandle( windows.Handle(f.Fd()), windows.FileBasicInfo, - (*byte)(unsafe.Pointer(bi)), - uint32(unsafe.Sizeof(*bi)), + (*byte)(unsafe.Pointer(&biAligned)), + uint32(unsafe.Sizeof(biAligned)), ); err != nil { return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} } diff --git a/vendor/github.com/Microsoft/go-winio/hvsock.go b/vendor/github.com/Microsoft/go-winio/hvsock.go index c8819165..c4fdd9d4 100644 --- a/vendor/github.com/Microsoft/go-winio/hvsock.go +++ b/vendor/github.com/Microsoft/go-winio/hvsock.go @@ -10,7 +10,6 @@ import ( "io" "net" "os" - "syscall" "time" "unsafe" @@ -181,13 +180,13 @@ type HvsockConn struct { var _ net.Conn = &HvsockConn{} func newHVSocket() (*win32File, error) { - fd, err := syscall.Socket(afHVSock, syscall.SOCK_STREAM, 1) + fd, err := windows.Socket(afHVSock, windows.SOCK_STREAM, 1) if err != nil { return nil, os.NewSyscallError("socket", err) } f, err := makeWin32File(fd) if err != nil { - syscall.Close(fd) + windows.Close(fd) return nil, err } f.socket = true @@ -197,16 +196,24 @@ func newHVSocket() (*win32File, error) { // ListenHvsock listens for connections on the specified hvsock address. func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) { l := &HvsockListener{addr: *addr} - sock, err := newHVSocket() + + var sock *win32File + sock, err = newHVSocket() if err != nil { return nil, l.opErr("listen", err) } + defer func() { + if err != nil { + _ = sock.Close() + } + }() + sa := addr.raw() - err = socket.Bind(windows.Handle(sock.handle), &sa) + err = socket.Bind(sock.handle, &sa) if err != nil { return nil, l.opErr("listen", os.NewSyscallError("socket", err)) } - err = syscall.Listen(sock.handle, 16) + err = windows.Listen(sock.handle, 16) if err != nil { return nil, l.opErr("listen", os.NewSyscallError("listen", err)) } @@ -246,7 +253,7 @@ func (l *HvsockListener) Accept() (_ net.Conn, err error) { var addrbuf [addrlen * 2]byte var bytes uint32 - err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o) + err = windows.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o) if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil { return nil, l.opErr("accept", os.NewSyscallError("acceptex", err)) } @@ -263,7 +270,7 @@ func (l *HvsockListener) Accept() (_ net.Conn, err error) { conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen]))) // initialize the accepted socket and update its properties with those of the listening socket - if err = windows.Setsockopt(windows.Handle(sock.handle), + if err = windows.Setsockopt(sock.handle, windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil { return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err)) @@ -334,7 +341,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock }() sa := addr.raw() - err = socket.Bind(windows.Handle(sock.handle), &sa) + err = socket.Bind(sock.handle, &sa) if err != nil { return nil, conn.opErr(op, os.NewSyscallError("bind", err)) } @@ -347,7 +354,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock var bytes uint32 for i := uint(0); i <= d.Retries; i++ { err = socket.ConnectEx( - windows.Handle(sock.handle), + sock.handle, &sa, nil, // sendBuf 0, // sendDataLen @@ -367,7 +374,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock // update the connection properties, so shutdown can be used if err = windows.Setsockopt( - windows.Handle(sock.handle), + sock.handle, windows.SOL_SOCKET, windows.SO_UPDATE_CONNECT_CONTEXT, nil, // optvalue @@ -378,7 +385,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock // get the local name var sal rawHvsockAddr - err = socket.GetSockName(windows.Handle(sock.handle), &sal) + err = socket.GetSockName(sock.handle, &sal) if err != nil { return nil, conn.opErr(op, os.NewSyscallError("getsockname", err)) } @@ -421,7 +428,7 @@ func (d *HvsockDialer) redialWait(ctx context.Context) (err error) { return ctx.Err() } -// assumes error is a plain, unwrapped syscall.Errno provided by direct syscall. +// assumes error is a plain, unwrapped windows.Errno provided by direct syscall. func canRedial(err error) bool { //nolint:errorlint // guaranteed to be an Errno switch err { @@ -447,9 +454,9 @@ func (conn *HvsockConn) Read(b []byte) (int, error) { return 0, conn.opErr("read", err) } defer conn.sock.wg.Done() - buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))} + buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))} var flags, bytes uint32 - err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil) + err = windows.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil) n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err) if err != nil { var eno windows.Errno @@ -482,9 +489,9 @@ func (conn *HvsockConn) write(b []byte) (int, error) { return 0, conn.opErr("write", err) } defer conn.sock.wg.Done() - buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))} + buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))} var bytes uint32 - err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil) + err = windows.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil) n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err) if err != nil { var eno windows.Errno @@ -511,7 +518,7 @@ func (conn *HvsockConn) shutdown(how int) error { return socket.ErrSocketClosed } - err := syscall.Shutdown(conn.sock.handle, how) + err := windows.Shutdown(conn.sock.handle, how) if err != nil { // If the connection was closed, shutdowns fail with "not connected" if errors.Is(err, windows.WSAENOTCONN) || @@ -525,7 +532,7 @@ func (conn *HvsockConn) shutdown(how int) error { // CloseRead shuts down the read end of the socket, preventing future read operations. func (conn *HvsockConn) CloseRead() error { - err := conn.shutdown(syscall.SHUT_RD) + err := conn.shutdown(windows.SHUT_RD) if err != nil { return conn.opErr("closeread", err) } @@ -535,7 +542,7 @@ func (conn *HvsockConn) CloseRead() error { // CloseWrite shuts down the write end of the socket, preventing future write operations and // notifying the other endpoint that no more data will be written. func (conn *HvsockConn) CloseWrite() error { - err := conn.shutdown(syscall.SHUT_WR) + err := conn.shutdown(windows.SHUT_WR) if err != nil { return conn.opErr("closewrite", err) } diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go index 509b3ec6..0cd9621d 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go +++ b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go @@ -11,12 +11,14 @@ import ( //go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew -//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW +//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW const NullHandle windows.Handle = 0 // AccessMask defines standard, specific, and generic rights. // +// Used with CreateFile and NtCreateFile (and co.). +// // Bitmask: // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 @@ -47,6 +49,12 @@ const ( // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters FILE_ANY_ACCESS AccessMask = 0 + GENERIC_READ AccessMask = 0x8000_0000 + GENERIC_WRITE AccessMask = 0x4000_0000 + GENERIC_EXECUTE AccessMask = 0x2000_0000 + GENERIC_ALL AccessMask = 0x1000_0000 + ACCESS_SYSTEM_SECURITY AccessMask = 0x0100_0000 + // Specific Object Access // from ntioapi.h @@ -124,14 +132,32 @@ const ( TRUNCATE_EXISTING FileCreationDisposition = 0x05 ) +// Create disposition values for NtCreate* +type NTFileCreationDisposition uint32 + +//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. +const ( + // From ntioapi.h + + FILE_SUPERSEDE NTFileCreationDisposition = 0x00 + FILE_OPEN NTFileCreationDisposition = 0x01 + FILE_CREATE NTFileCreationDisposition = 0x02 + FILE_OPEN_IF NTFileCreationDisposition = 0x03 + FILE_OVERWRITE NTFileCreationDisposition = 0x04 + FILE_OVERWRITE_IF NTFileCreationDisposition = 0x05 + FILE_MAXIMUM_DISPOSITION NTFileCreationDisposition = 0x05 +) + // CreateFile and co. take flags or attributes together as one parameter. // Define alias until we can use generics to allow both - +// // https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants type FileFlagOrAttribute uint32 //nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( // from winnt.h +const ( + // from winnt.h + FILE_FLAG_WRITE_THROUGH FileFlagOrAttribute = 0x8000_0000 FILE_FLAG_OVERLAPPED FileFlagOrAttribute = 0x4000_0000 FILE_FLAG_NO_BUFFERING FileFlagOrAttribute = 0x2000_0000 @@ -145,17 +171,51 @@ const ( // from winnt.h FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000 ) +// NtCreate* functions take a dedicated CreateOptions parameter. +// +// https://learn.microsoft.com/en-us/windows/win32/api/Winternl/nf-winternl-ntcreatefile +// +// https://learn.microsoft.com/en-us/windows/win32/devnotes/nt-create-named-pipe-file +type NTCreateOptions uint32 + +//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. +const ( + // From ntioapi.h + + FILE_DIRECTORY_FILE NTCreateOptions = 0x0000_0001 + FILE_WRITE_THROUGH NTCreateOptions = 0x0000_0002 + FILE_SEQUENTIAL_ONLY NTCreateOptions = 0x0000_0004 + FILE_NO_INTERMEDIATE_BUFFERING NTCreateOptions = 0x0000_0008 + + FILE_SYNCHRONOUS_IO_ALERT NTCreateOptions = 0x0000_0010 + FILE_SYNCHRONOUS_IO_NONALERT NTCreateOptions = 0x0000_0020 + FILE_NON_DIRECTORY_FILE NTCreateOptions = 0x0000_0040 + FILE_CREATE_TREE_CONNECTION NTCreateOptions = 0x0000_0080 + + FILE_COMPLETE_IF_OPLOCKED NTCreateOptions = 0x0000_0100 + FILE_NO_EA_KNOWLEDGE NTCreateOptions = 0x0000_0200 + FILE_DISABLE_TUNNELING NTCreateOptions = 0x0000_0400 + FILE_RANDOM_ACCESS NTCreateOptions = 0x0000_0800 + + FILE_DELETE_ON_CLOSE NTCreateOptions = 0x0000_1000 + FILE_OPEN_BY_FILE_ID NTCreateOptions = 0x0000_2000 + FILE_OPEN_FOR_BACKUP_INTENT NTCreateOptions = 0x0000_4000 + FILE_NO_COMPRESSION NTCreateOptions = 0x0000_8000 +) + type FileSQSFlag = FileFlagOrAttribute //nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( // from winbase.h +const ( + // from winbase.h + SECURITY_ANONYMOUS FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16) SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16) SECURITY_IMPERSONATION FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16) SECURITY_DELEGATION FileSQSFlag = FileSQSFlag(SecurityDelegation << 16) - SECURITY_SQOS_PRESENT FileSQSFlag = 0x00100000 - SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000 + SECURITY_SQOS_PRESENT FileSQSFlag = 0x0010_0000 + SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F_0000 ) // GetFinalPathNameByHandle flags diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go index e2f7bb24..a94e234c 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go @@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error { case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) return e } @@ -45,7 +42,7 @@ var ( procCreateFileW = modkernel32.NewProc("CreateFileW") ) -func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { +func CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(name) if err != nil { @@ -54,8 +51,8 @@ func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall. return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile) } -func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) +func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile)) handle = windows.Handle(r0) if handle == windows.InvalidHandle { err = errnoErr(e1) diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go index aeb7b725..88580d97 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go +++ b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go @@ -156,9 +156,7 @@ func connectEx( bytesSent *uint32, overlapped *windows.Overlapped, ) (err error) { - // todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN - r1, _, e1 := syscall.Syscall9(connectExFunc.addr, - 7, + r1, _, e1 := syscall.SyscallN(connectExFunc.addr, uintptr(s), uintptr(name), uintptr(namelen), @@ -166,8 +164,8 @@ func connectEx( uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), - 0, - 0) + ) + if r1 == 0 { if e1 != 0 { err = error(e1) diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go index 6d2e1a9e..e1504126 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go @@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error { case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) return e } @@ -48,7 +45,7 @@ var ( ) func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen)) + r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) if r1 == socketError { err = errnoErr(e1) } @@ -56,7 +53,7 @@ func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) { } func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) + r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) if r1 == socketError { err = errnoErr(e1) } @@ -64,7 +61,7 @@ func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err err } func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) { - r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) + r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) if r1 == socketError { err = errnoErr(e1) } diff --git a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go index 7ad50570..42ebc019 100644 --- a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go +++ b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go @@ -62,7 +62,7 @@ func (b *WString) Free() { // ResizeTo grows the buffer to at least c and returns the new capacity, freeing the // previous buffer back into pool. func (b *WString) ResizeTo(c uint32) uint32 { - // allready sufficient (or n is 0) + // already sufficient (or n is 0) if c <= b.Cap() { return b.Cap() } diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go index 25cc8110..a2da6639 100644 --- a/vendor/github.com/Microsoft/go-winio/pipe.go +++ b/vendor/github.com/Microsoft/go-winio/pipe.go @@ -11,7 +11,6 @@ import ( "net" "os" "runtime" - "syscall" "time" "unsafe" @@ -20,20 +19,44 @@ import ( "github.com/Microsoft/go-winio/internal/fs" ) -//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe -//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW -//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo -//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW -//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc -//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile +//sys connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) = ConnectNamedPipe +//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateNamedPipeW +//sys disconnectNamedPipe(pipe windows.Handle) (err error) = DisconnectNamedPipe +//sys getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo +//sys getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW +//sys ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile //sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb //sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U //sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl +type PipeConn interface { + net.Conn + Disconnect() error + Flush() error +} + +// type aliases for mkwinsyscall code +type ( + ntAccessMask = fs.AccessMask + ntFileShareMode = fs.FileShareMode + ntFileCreationDisposition = fs.NTFileCreationDisposition + ntFileOptions = fs.NTCreateOptions +) + type ioStatusBlock struct { Status, Information uintptr } +// typedef struct _OBJECT_ATTRIBUTES { +// ULONG Length; +// HANDLE RootDirectory; +// PUNICODE_STRING ObjectName; +// ULONG Attributes; +// PVOID SecurityDescriptor; +// PVOID SecurityQualityOfService; +// } OBJECT_ATTRIBUTES; +// +// https://learn.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_attributes type objectAttributes struct { Length uintptr RootDirectory uintptr @@ -49,6 +72,17 @@ type unicodeString struct { Buffer uintptr } +// typedef struct _SECURITY_DESCRIPTOR { +// BYTE Revision; +// BYTE Sbz1; +// SECURITY_DESCRIPTOR_CONTROL Control; +// PSID Owner; +// PSID Group; +// PACL Sacl; +// PACL Dacl; +// } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR; +// +// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor type securityDescriptor struct { Revision byte Sbz1 byte @@ -80,6 +114,8 @@ type win32Pipe struct { path string } +var _ PipeConn = (*win32Pipe)(nil) + type win32MessageBytePipe struct { win32Pipe writeClosed bool @@ -103,6 +139,10 @@ func (f *win32Pipe) SetDeadline(t time.Time) error { return f.SetWriteDeadline(t) } +func (f *win32Pipe) Disconnect() error { + return disconnectNamedPipe(f.win32File.handle) +} + // CloseWrite closes the write side of a message pipe in byte mode. func (f *win32MessageBytePipe) CloseWrite() error { if f.writeClosed { @@ -146,7 +186,7 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) { // zero-byte message, ensure that all future Read() calls // also return EOF. f.readEOF = true - } else if err == syscall.ERROR_MORE_DATA { //nolint:errorlint // err is Errno + } else if err == windows.ERROR_MORE_DATA { //nolint:errorlint // err is Errno // ERROR_MORE_DATA indicates that the pipe's read mode is message mode // and the message still has more bytes. Treat this as a success, since // this package presents all named pipes as byte streams. @@ -164,21 +204,20 @@ func (s pipeAddress) String() string { } // tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout. -func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (syscall.Handle, error) { +func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask, impLevel PipeImpLevel) (windows.Handle, error) { for { select { case <-ctx.Done(): - return syscall.Handle(0), ctx.Err() + return windows.Handle(0), ctx.Err() default: - wh, err := fs.CreateFile(*path, + h, err := fs.CreateFile(*path, access, 0, // mode nil, // security attributes fs.OPEN_EXISTING, - fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.SECURITY_ANONYMOUS, + fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.FileSQSFlag(impLevel), 0, // template file handle ) - h := syscall.Handle(wh) if err == nil { return h, nil } @@ -214,15 +253,33 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { // DialPipeContext attempts to connect to a named pipe by `path` until `ctx` // cancellation or timeout. func DialPipeContext(ctx context.Context, path string) (net.Conn, error) { - return DialPipeAccess(ctx, path, syscall.GENERIC_READ|syscall.GENERIC_WRITE) + return DialPipeAccess(ctx, path, uint32(fs.GENERIC_READ|fs.GENERIC_WRITE)) } +// PipeImpLevel is an enumeration of impersonation levels that may be set +// when calling DialPipeAccessImpersonation. +type PipeImpLevel uint32 + +const ( + PipeImpLevelAnonymous = PipeImpLevel(fs.SECURITY_ANONYMOUS) + PipeImpLevelIdentification = PipeImpLevel(fs.SECURITY_IDENTIFICATION) + PipeImpLevelImpersonation = PipeImpLevel(fs.SECURITY_IMPERSONATION) + PipeImpLevelDelegation = PipeImpLevel(fs.SECURITY_DELEGATION) +) + // DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx` // cancellation or timeout. func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) { + return DialPipeAccessImpLevel(ctx, path, access, PipeImpLevelAnonymous) +} + +// DialPipeAccessImpLevel attempts to connect to a named pipe by `path` with +// `access` at `impLevel` until `ctx` cancellation or timeout. The other +// DialPipe* implementations use PipeImpLevelAnonymous. +func DialPipeAccessImpLevel(ctx context.Context, path string, access uint32, impLevel PipeImpLevel) (net.Conn, error) { var err error - var h syscall.Handle - h, err = tryDialPipe(ctx, &path, fs.AccessMask(access)) + var h windows.Handle + h, err = tryDialPipe(ctx, &path, fs.AccessMask(access), impLevel) if err != nil { return nil, err } @@ -235,7 +292,7 @@ func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, f, err := makeWin32File(h) if err != nil { - syscall.Close(h) + windows.Close(h) return nil, err } @@ -255,7 +312,7 @@ type acceptResponse struct { } type win32PipeListener struct { - firstHandle syscall.Handle + firstHandle windows.Handle path string config PipeConfig acceptCh chan (chan acceptResponse) @@ -263,8 +320,8 @@ type win32PipeListener struct { doneCh chan int } -func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) { - path16, err := syscall.UTF16FromString(path) +func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (windows.Handle, error) { + path16, err := windows.UTF16FromString(path) if err != nil { return 0, &os.PathError{Op: "open", Path: path, Err: err} } @@ -280,16 +337,20 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy ).Err(); err != nil { return 0, &os.PathError{Op: "open", Path: path, Err: err} } - defer localFree(ntPath.Buffer) + defer windows.LocalFree(windows.Handle(ntPath.Buffer)) //nolint:errcheck oa.ObjectName = &ntPath oa.Attributes = windows.OBJ_CASE_INSENSITIVE // The security descriptor is only needed for the first pipe. if first { if sd != nil { + //todo: does `sdb` need to be allocated on the heap, or can go allocate it? l := uint32(len(sd)) - sdb := localAlloc(0, l) - defer localFree(sdb) + sdb, err := windows.LocalAlloc(0, l) + if err != nil { + return 0, fmt.Errorf("LocalAlloc for security descriptor with of length %d: %w", l, err) + } + defer windows.LocalFree(windows.Handle(sdb)) //nolint:errcheck copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd) oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb)) } else { @@ -298,7 +359,7 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy if err := rtlDefaultNpAcl(&dacl).Err(); err != nil { return 0, fmt.Errorf("getting default named pipe ACL: %w", err) } - defer localFree(dacl) + defer windows.LocalFree(windows.Handle(dacl)) //nolint:errcheck sdb := &securityDescriptor{ Revision: 1, @@ -314,27 +375,27 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy typ |= windows.FILE_PIPE_MESSAGE_TYPE } - disposition := uint32(windows.FILE_OPEN) - access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE) + disposition := fs.FILE_OPEN + access := fs.GENERIC_READ | fs.GENERIC_WRITE | fs.SYNCHRONIZE if first { - disposition = windows.FILE_CREATE + disposition = fs.FILE_CREATE // By not asking for read or write access, the named pipe file system // will put this pipe into an initially disconnected state, blocking // client connections until the next call with first == false. - access = syscall.SYNCHRONIZE + access = fs.SYNCHRONIZE } timeout := int64(-50 * 10000) // 50ms var ( - h syscall.Handle + h windows.Handle iosb ioStatusBlock ) err = ntCreateNamedPipeFile(&h, access, &oa, &iosb, - syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, + fs.FILE_SHARE_READ|fs.FILE_SHARE_WRITE, disposition, 0, typ, @@ -359,7 +420,7 @@ func (l *win32PipeListener) makeServerPipe() (*win32File, error) { } f, err := makeWin32File(h) if err != nil { - syscall.Close(h) + windows.Close(h) return nil, err } return f, nil @@ -418,7 +479,7 @@ func (l *win32PipeListener) listenerRoutine() { closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno } } - syscall.Close(l.firstHandle) + windows.Close(l.firstHandle) l.firstHandle = 0 // Notify Close() and Accept() callers that the handle has been closed. close(l.doneCh) diff --git a/vendor/github.com/Microsoft/go-winio/privilege.go b/vendor/github.com/Microsoft/go-winio/privilege.go index 0ff9dac9..d9b90b6e 100644 --- a/vendor/github.com/Microsoft/go-winio/privilege.go +++ b/vendor/github.com/Microsoft/go-winio/privilege.go @@ -9,7 +9,6 @@ import ( "fmt" "runtime" "sync" - "syscall" "unicode/utf16" "golang.org/x/sys/windows" @@ -18,8 +17,8 @@ import ( //sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges //sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf //sys revertToSelf() (err error) = advapi32.RevertToSelf -//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken -//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread +//sys openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken +//sys getCurrentThread() (h windows.Handle) = GetCurrentThread //sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW //sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW //sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW @@ -29,7 +28,7 @@ const ( SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED //revive:disable-next-line:var-naming ALL_CAPS - ERROR_NOT_ALL_ASSIGNED syscall.Errno = windows.ERROR_NOT_ALL_ASSIGNED + ERROR_NOT_ALL_ASSIGNED windows.Errno = windows.ERROR_NOT_ALL_ASSIGNED SeBackupPrivilege = "SeBackupPrivilege" SeRestorePrivilege = "SeRestorePrivilege" @@ -177,7 +176,7 @@ func newThreadToken() (windows.Token, error) { } var token windows.Token - err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token) + err = openThreadToken(getCurrentThread(), windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, false, &token) if err != nil { rerr := revertToSelf() if rerr != nil { diff --git a/vendor/github.com/Microsoft/go-winio/sd.go b/vendor/github.com/Microsoft/go-winio/sd.go index 5550ef6b..c3685e98 100644 --- a/vendor/github.com/Microsoft/go-winio/sd.go +++ b/vendor/github.com/Microsoft/go-winio/sd.go @@ -5,7 +5,7 @@ package winio import ( "errors" - "syscall" + "fmt" "unsafe" "golang.org/x/sys/windows" @@ -15,10 +15,6 @@ import ( //sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW //sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW //sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW -//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW -//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW -//sys localFree(mem uintptr) = LocalFree -//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength type AccountLookupError struct { Name string @@ -64,7 +60,7 @@ func LookupSidByName(name string) (sid string, err error) { var sidSize, sidNameUse, refDomainSize uint32 err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse) - if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno + if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno return "", &AccountLookupError{name, err} } sidBuffer := make([]byte, sidSize) @@ -78,8 +74,8 @@ func LookupSidByName(name string) (sid string, err error) { if err != nil { return "", &AccountLookupError{name, err} } - sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:]) - localFree(uintptr(unsafe.Pointer(strBuffer))) + sid = windows.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:]) + _, _ = windows.LocalFree(windows.Handle(unsafe.Pointer(strBuffer))) return sid, nil } @@ -100,7 +96,7 @@ func LookupNameBySid(sid string) (name string, err error) { if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil { return "", &AccountLookupError{sid, err} } - defer localFree(uintptr(unsafe.Pointer(sidPtr))) + defer windows.LocalFree(windows.Handle(unsafe.Pointer(sidPtr))) //nolint:errcheck var nameSize, refDomainSize, sidNameUse uint32 err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse) @@ -120,25 +116,18 @@ func LookupNameBySid(sid string) (name string, err error) { } func SddlToSecurityDescriptor(sddl string) ([]byte, error) { - var sdBuffer uintptr - err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil) + sd, err := windows.SecurityDescriptorFromString(sddl) if err != nil { - return nil, &SddlConversionError{sddl, err} + return nil, &SddlConversionError{Sddl: sddl, Err: err} } - defer localFree(sdBuffer) - sd := make([]byte, getSecurityDescriptorLength(sdBuffer)) - copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)]) - return sd, nil + b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length()) + return b, nil } func SecurityDescriptorToSddl(sd []byte) (string, error) { - var sddl *uint16 - // The returned string length seems to include an arbitrary number of terminating NULs. - // Don't use it. - err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil) - if err != nil { - return "", err + if l := int(unsafe.Sizeof(windows.SECURITY_DESCRIPTOR{})); len(sd) < l { + return "", fmt.Errorf("SecurityDescriptor (%d) smaller than expected (%d): %w", len(sd), l, windows.ERROR_INCORRECT_SIZE) } - defer localFree(uintptr(unsafe.Pointer(sddl))) - return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil + s := (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&sd[0])) + return s.String(), nil } diff --git a/vendor/github.com/Microsoft/go-winio/tools.go b/vendor/github.com/Microsoft/go-winio/tools.go deleted file mode 100644 index 2aa04584..00000000 --- a/vendor/github.com/Microsoft/go-winio/tools.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build tools - -package winio - -import _ "golang.org/x/tools/cmd/stringer" diff --git a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go index 469b16f6..89b66eda 100644 --- a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go @@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error { case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } - // TODO: add more here, after collecting data on the common - // error values see on Windows. (perhaps when running - // all.bat?) return e } @@ -45,38 +42,34 @@ var ( modntdll = windows.NewLazySystemDLL("ntdll.dll") modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") - procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") - procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") - procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") - procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength") - procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") - procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") - procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procBackupRead = modkernel32.NewProc("BackupRead") - procBackupWrite = modkernel32.NewProc("BackupWrite") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") - procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") - procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") - procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procLocalAlloc = modkernel32.NewProc("LocalAlloc") - procLocalFree = modkernel32.NewProc("LocalFree") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") - procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") - procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U") - procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") - procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") + procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") + procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") + procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") + procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") + procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") + procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procBackupRead = modkernel32.NewProc("BackupRead") + procBackupWrite = modkernel32.NewProc("BackupWrite") + procCancelIoEx = modkernel32.NewProc("CancelIoEx") + procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") + procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") + procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") + procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") + procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") + procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") + procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") + procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") + procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U") + procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") + procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") ) func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { @@ -84,7 +77,7 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou if releaseAll { _p0 = 1 } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) + r0, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) success = r0 != 0 if true { err = errnoErr(e1) @@ -92,33 +85,8 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou return } -func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - func convertSidToStringSid(sid *byte, str **uint16) (err error) { - r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(str) - if err != nil { - return - } - return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) -} - -func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str))) if r1 == 0 { err = errnoErr(e1) } @@ -126,21 +94,15 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision } func convertStringSidToSid(str *uint16, sid **byte) (err error) { - r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)), 0) + r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid))) if r1 == 0 { err = errnoErr(e1) } return } -func getSecurityDescriptorLength(sd uintptr) (len uint32) { - r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0) - len = uint32(r0) - return -} - func impersonateSelf(level uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) + r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(level)) if r1 == 0 { err = errnoErr(e1) } @@ -157,7 +119,7 @@ func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSiz } func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse))) if r1 == 0 { err = errnoErr(e1) } @@ -165,7 +127,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS } func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse))) if r1 == 0 { err = errnoErr(e1) } @@ -182,7 +144,7 @@ func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, } func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeDisplayNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId))) if r1 == 0 { err = errnoErr(e1) } @@ -199,7 +161,7 @@ func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size * } func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size))) if r1 == 0 { err = errnoErr(e1) } @@ -221,19 +183,19 @@ func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err err } func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) if r1 == 0 { err = errnoErr(e1) } return } -func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { +func openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { var _p0 uint32 if openAsSelf { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) + r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token))) if r1 == 0 { err = errnoErr(e1) } @@ -241,14 +203,14 @@ func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, } func revertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) + r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr()) if r1 == 0 { err = errnoErr(e1) } return } -func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { +func backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { var _p0 *byte if len(b) > 0 { _p0 = &b[0] @@ -261,14 +223,14 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce if processSecurity { _p2 = 1 } - r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) + r1, _, e1 := syscall.SyscallN(procBackupRead.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context))) if r1 == 0 { err = errnoErr(e1) } return } -func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { +func backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { var _p0 *byte if len(b) > 0 { _p0 = &b[0] @@ -281,39 +243,39 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p if processSecurity { _p2 = 1 } - r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) + r1, _, e1 := syscall.SyscallN(procBackupWrite.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context))) if r1 == 0 { err = errnoErr(e1) } return } -func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) +func cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(file), uintptr(unsafe.Pointer(o))) if r1 == 0 { err = errnoErr(e1) } return } -func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) +func connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) { + r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(o))) if r1 == 0 { err = errnoErr(e1) } return } -func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) - newport = syscall.Handle(r0) +func createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount)) + newport = windows.Handle(r0) if newport == 0 { err = errnoErr(e1) } return } -func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { +func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) { var _p0 *uint16 _p0, err = syscall.UTF16PtrFromString(name) if err != nil { @@ -322,96 +284,93 @@ func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances ui return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) } -func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { +func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) { + r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa))) + handle = windows.Handle(r0) + if handle == windows.InvalidHandle { err = errnoErr(e1) } return } -func getCurrentThread() (h syscall.Handle) { - r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) - h = syscall.Handle(r0) - return -} - -func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) +func disconnectNamedPipe(pipe windows.Handle) (err error) { + r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe)) if r1 == 0 { err = errnoErr(e1) } return } -func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) +func getCurrentThread() (h windows.Handle) { + r0, _, _ := syscall.SyscallN(procGetCurrentThread.Addr()) + h = windows.Handle(r0) + return +} + +func getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize)) if r1 == 0 { err = errnoErr(e1) } return } -func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) +func getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances))) if r1 == 0 { err = errnoErr(e1) } return } -func localAlloc(uFlags uint32, length uint32) (ptr uintptr) { - r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0) - ptr = uintptr(r0) - return -} - -func localFree(mem uintptr) { - syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) - return -} - -func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { - r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) +func getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { + r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout)) if r1 == 0 { err = errnoErr(e1) } return } -func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) { - r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0) +func setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) { + r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(h), uintptr(flags)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + +func ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) { + r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout))) status = ntStatus(r0) return } func rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) { - r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(dacl))) status = ntStatus(r0) return } func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) { - r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved)) status = ntStatus(r0) return } func rtlNtStatusToDosError(status ntStatus) (winerr error) { - r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0) + r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(status)) if r0 != 0 { winerr = syscall.Errno(r0) } return } -func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { +func wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { var _p0 uint32 if wait { _p0 = 1 } - r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0) + r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags))) if r1 == 0 { err = errnoErr(e1) } diff --git a/vendor/github.com/containerd/containerd/images/diffid.go b/vendor/github.com/containerd/containerd/images/diffid.go index 56193cc2..85577eed 100644 --- a/vendor/github.com/containerd/containerd/images/diffid.go +++ b/vendor/github.com/containerd/containerd/images/diffid.go @@ -36,7 +36,7 @@ func GetDiffID(ctx context.Context, cs content.Store, desc ocispec.Descriptor) ( MediaTypeDockerSchema2Layer, ocispec.MediaTypeImageLayer, MediaTypeDockerSchema2LayerForeign, - ocispec.MediaTypeImageLayerNonDistributable: + ocispec.MediaTypeImageLayerNonDistributable: //nolint:staticcheck // deprecated return desc.Digest, nil } info, err := cs.Info(ctx, desc.Digest) diff --git a/vendor/github.com/containerd/containerd/images/mediatypes.go b/vendor/github.com/containerd/containerd/images/mediatypes.go index 067963ba..d3b28d42 100644 --- a/vendor/github.com/containerd/containerd/images/mediatypes.go +++ b/vendor/github.com/containerd/containerd/images/mediatypes.go @@ -81,7 +81,7 @@ func DiffCompression(ctx context.Context, mediaType string) (string, error) { return "", nil } return "gzip", nil - case ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerNonDistributable: + case ocispec.MediaTypeImageLayer, ocispec.MediaTypeImageLayerNonDistributable: //nolint:staticcheck // Non-distributable layers are deprecated if len(ext) > 0 { switch ext[len(ext)-1] { case "gzip": diff --git a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go index 9b3663cd..ebd69c16 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/authorizer.go @@ -148,9 +148,11 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R defer a.mu.Unlock() for _, c := range auth.ParseAuthHeader(last.Header) { if c.Scheme == auth.BearerAuth { - if err := invalidAuthorization(c, responses); err != nil { + if retry, err := invalidAuthorization(ctx, c, responses); err != nil { delete(a.handlers, host) return err + } else if retry { + delete(a.handlers, host) } // reuse existing handler @@ -328,18 +330,24 @@ func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken st return resp.Token, resp.RefreshToken, nil } -func invalidAuthorization(c auth.Challenge, responses []*http.Response) error { +func invalidAuthorization(ctx context.Context, c auth.Challenge, responses []*http.Response) (retry bool, _ error) { errStr := c.Parameters["error"] if errStr == "" { - return nil + return retry, nil } n := len(responses) if n == 1 || (n > 1 && !sameRequest(responses[n-2].Request, responses[n-1].Request)) { - return nil + limitedErr := errStr + errLenghLimit := 64 + if len(limitedErr) > errLenghLimit { + limitedErr = limitedErr[:errLenghLimit] + "..." + } + log.G(ctx).WithField("error", limitedErr).Debug("authorization error using bearer token, retrying") + return true, nil } - return fmt.Errorf("server message: %s: %w", errStr, ErrInvalidAuthorization) + return retry, fmt.Errorf("server message: %s: %w", errStr, ErrInvalidAuthorization) } func sameRequest(r1, r2 *http.Request) bool { diff --git a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go index cca4ca6a..ce1f6462 100644 --- a/vendor/github.com/containerd/containerd/remotes/docker/resolver.go +++ b/vendor/github.com/containerd/containerd/remotes/docker/resolver.go @@ -704,9 +704,71 @@ func IsLocalhost(host string) bool { return ip.IsLoopback() } +// NewHTTPFallback returns http.RoundTripper which allows fallback from https to +// http for registry endpoints with configurations for both http and TLS, +// such as defaulted localhost endpoints. +func NewHTTPFallback(transport http.RoundTripper) http.RoundTripper { + return &httpFallback{ + super: transport, + } +} + +type httpFallback struct { + super http.RoundTripper + host string +} + +func (f *httpFallback) RoundTrip(r *http.Request) (*http.Response, error) { + // only fall back if the same host had previously fell back + if f.host != r.URL.Host { + resp, err := f.super.RoundTrip(r) + if !isTLSError(err) { + return resp, err + } + } + + plainHTTPUrl := *r.URL + plainHTTPUrl.Scheme = "http" + + plainHTTPRequest := *r + plainHTTPRequest.URL = &plainHTTPUrl + + if f.host != r.URL.Host { + f.host = r.URL.Host + + // update body on the second attempt + if r.Body != nil && r.GetBody != nil { + body, err := r.GetBody() + if err != nil { + return nil, err + } + plainHTTPRequest.Body = body + } + } + + return f.super.RoundTrip(&plainHTTPRequest) +} + +func isTLSError(err error) bool { + if err == nil { + return false + } + var tlsErr tls.RecordHeaderError + if errors.As(err, &tlsErr) && string(tlsErr.RecordHeader[:]) == "HTTP/" { + return true + } + if strings.Contains(err.Error(), "TLS handshake timeout") { + return true + } + + return false +} + // HTTPFallback is an http.RoundTripper which allows fallback from https to http // for registry endpoints with configurations for both http and TLS, such as // defaulted localhost endpoints. +// +// Deprecated: Use NewHTTPFallback instead. type HTTPFallback struct { http.RoundTripper } @@ -722,6 +784,14 @@ func (f HTTPFallback) RoundTrip(r *http.Request) (*http.Response, error) { plainHTTPRequest := *r plainHTTPRequest.URL = &plainHTTPUrl + if r.Body != nil && r.GetBody != nil { + body, err := r.GetBody() + if err != nil { + return nil, err + } + plainHTTPRequest.Body = body + } + return f.RoundTripper.RoundTrip(&plainHTTPRequest) } diff --git a/vendor/github.com/containerd/containerd/version/version.go b/vendor/github.com/containerd/containerd/version/version.go index 4c4c6714..782771e4 100644 --- a/vendor/github.com/containerd/containerd/version/version.go +++ b/vendor/github.com/containerd/containerd/version/version.go @@ -23,7 +23,7 @@ var ( Package = "github.com/containerd/containerd" // Version holds the complete version number. Filled in at linking time. - Version = "1.7.15+unknown" + Version = "1.7.17+unknown" // Revision is filled with the VCS (e.g. git) revision being used to build // the program at linking time. diff --git a/vendor/github.com/containerd/ttrpc/client.go b/vendor/github.com/containerd/ttrpc/client.go index 482a68e3..685a00a9 100644 --- a/vendor/github.com/containerd/ttrpc/client.go +++ b/vendor/github.com/containerd/ttrpc/client.go @@ -386,25 +386,44 @@ func (c *Client) receiveLoop() error { // createStream creates a new stream and registers it with the client // Introduce stream types for multiple or single response func (c *Client) createStream(flags uint8, b []byte) (*stream, error) { - c.streamLock.Lock() + // sendLock must be held across both allocation of the stream ID and sending it across the wire. + // This ensures that new stream IDs sent on the wire are always increasing, which is a + // requirement of the TTRPC protocol. + // This use of sendLock could be split into another mutex that covers stream creation + first send, + // and just use sendLock to guard writing to the wire, but for now it seems simpler to have fewer mutexes. + c.sendLock.Lock() + defer c.sendLock.Unlock() // Check if closed since lock acquired to prevent adding // anything after cleanup completes select { case <-c.ctx.Done(): - c.streamLock.Unlock() return nil, ErrClosed default: } - // Stream ID should be allocated at same time - s := newStream(c.nextStreamID, c) - c.streams[s.id] = s - c.nextStreamID = c.nextStreamID + 2 + var s *stream + if err := func() error { + // In the future this could be replaced with a sync.Map instead of streamLock+map. + c.streamLock.Lock() + defer c.streamLock.Unlock() - c.sendLock.Lock() - defer c.sendLock.Unlock() - c.streamLock.Unlock() + // Check if closed since lock acquired to prevent adding + // anything after cleanup completes + select { + case <-c.ctx.Done(): + return ErrClosed + default: + } + + s = newStream(c.nextStreamID, c) + c.streams[s.id] = s + c.nextStreamID = c.nextStreamID + 2 + + return nil + }(); err != nil { + return nil, err + } if err := c.channel.send(uint32(s.id), messageTypeRequest, flags, b); err != nil { return s, filterCloseErr(err) diff --git a/vendor/github.com/docker/docker/AUTHORS b/vendor/github.com/docker/docker/AUTHORS index 48d04f9a..36315d42 100644 --- a/vendor/github.com/docker/docker/AUTHORS +++ b/vendor/github.com/docker/docker/AUTHORS @@ -669,6 +669,7 @@ Erik Hollensbe Erik Inge Bolsø Erik Kristensen Erik Sipsma +Erik Sjölund Erik St. Martin Erik Weathers Erno Hopearuoho @@ -731,6 +732,7 @@ Feroz Salam Ferran Rodenas Filipe Brandenburger Filipe Oliveira +Filipe Pina Flavio Castelli Flavio Crisciani Florian @@ -875,6 +877,8 @@ Hsing-Yu (David) Chen hsinko <21551195@zju.edu.cn> Hu Keping Hu Tao +Huajin Tong +huang-jl <1046678590@qq.com> HuanHuan Ye Huanzhong Zhang Huayi Zhang @@ -969,6 +973,7 @@ Jannick Fahlbusch Januar Wayong Jared Biel Jared Hocutt +Jaroslav Jindrak Jaroslaw Zabiello Jasmine Hegman Jason A. Donenfeld @@ -1012,6 +1017,7 @@ Jeffrey Bolle Jeffrey Morgan Jeffrey van Gogh Jenny Gebske +Jeongseok Kang Jeremy Chambers Jeremy Grosser Jeremy Huntwork @@ -1029,6 +1035,7 @@ Jezeniel Zapanta Jhon Honce Ji.Zhilong Jian Liao +Jian Zeng Jian Zhang Jiang Jinyang Jianyong Wu @@ -1967,6 +1974,7 @@ Sergey Evstifeev Sergii Kabashniuk Sergio Lopez Serhat Gülçiçek +Serhii Nakon SeungUkLee Sevki Hasirci Shane Canon @@ -2253,6 +2261,7 @@ VladimirAus Vladislav Kolesnikov Vlastimil Zeman Vojtech Vitek (V-Teq) +voloder <110066198+voloder@users.noreply.github.com> Walter Leibbrandt Walter Stanish Wang Chao diff --git a/vendor/github.com/docker/docker/pkg/system/stat_illumos.go b/vendor/github.com/docker/docker/pkg/system/stat_illumos.go new file mode 100644 index 00000000..851374e5 --- /dev/null +++ b/vendor/github.com/docker/docker/pkg/system/stat_illumos.go @@ -0,0 +1,15 @@ +package system // import "github.com/docker/docker/pkg/system" + +import "syscall" + +// fromStatT converts a syscall.Stat_t type to a system.Stat_t type +func fromStatT(s *syscall.Stat_t) (*StatT, error) { + return &StatT{ + size: s.Size, + mode: uint32(s.Mode), + uid: s.Uid, + gid: s.Gid, + rdev: uint64(s.Rdev), + mtim: s.Mtim, + }, nil +} diff --git a/vendor/github.com/hashicorp/errwrap/LICENSE b/vendor/github.com/hashicorp/errwrap/LICENSE new file mode 100644 index 00000000..c33dcc7c --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/LICENSE @@ -0,0 +1,354 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. + diff --git a/vendor/github.com/hashicorp/errwrap/README.md b/vendor/github.com/hashicorp/errwrap/README.md new file mode 100644 index 00000000..444df08f --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/README.md @@ -0,0 +1,89 @@ +# errwrap + +`errwrap` is a package for Go that formalizes the pattern of wrapping errors +and checking if an error contains another error. + +There is a common pattern in Go of taking a returned `error` value and +then wrapping it (such as with `fmt.Errorf`) before returning it. The problem +with this pattern is that you completely lose the original `error` structure. + +Arguably the _correct_ approach is that you should make a custom structure +implementing the `error` interface, and have the original error as a field +on that structure, such [as this example](http://golang.org/pkg/os/#PathError). +This is a good approach, but you have to know the entire chain of possible +rewrapping that happens, when you might just care about one. + +`errwrap` formalizes this pattern (it doesn't matter what approach you use +above) by giving a single interface for wrapping errors, checking if a specific +error is wrapped, and extracting that error. + +## Installation and Docs + +Install using `go get github.com/hashicorp/errwrap`. + +Full documentation is available at +http://godoc.org/github.com/hashicorp/errwrap + +## Usage + +#### Basic Usage + +Below is a very basic example of its usage: + +```go +// A function that always returns an error, but wraps it, like a real +// function might. +func tryOpen() error { + _, err := os.Open("/i/dont/exist") + if err != nil { + return errwrap.Wrapf("Doesn't exist: {{err}}", err) + } + + return nil +} + +func main() { + err := tryOpen() + + // We can use the Contains helpers to check if an error contains + // another error. It is safe to do this with a nil error, or with + // an error that doesn't even use the errwrap package. + if errwrap.Contains(err, "does not exist") { + // Do something + } + if errwrap.ContainsType(err, new(os.PathError)) { + // Do something + } + + // Or we can use the associated `Get` functions to just extract + // a specific error. This would return nil if that specific error doesn't + // exist. + perr := errwrap.GetType(err, new(os.PathError)) +} +``` + +#### Custom Types + +If you're already making custom types that properly wrap errors, then +you can get all the functionality of `errwraps.Contains` and such by +implementing the `Wrapper` interface with just one function. Example: + +```go +type AppError { + Code ErrorCode + Err error +} + +func (e *AppError) WrappedErrors() []error { + return []error{e.Err} +} +``` + +Now this works: + +```go +err := &AppError{Err: fmt.Errorf("an error")} +if errwrap.ContainsType(err, fmt.Errorf("")) { + // This will work! +} +``` diff --git a/vendor/github.com/hashicorp/errwrap/errwrap.go b/vendor/github.com/hashicorp/errwrap/errwrap.go new file mode 100644 index 00000000..44e368e5 --- /dev/null +++ b/vendor/github.com/hashicorp/errwrap/errwrap.go @@ -0,0 +1,178 @@ +// Package errwrap implements methods to formalize error wrapping in Go. +// +// All of the top-level functions that take an `error` are built to be able +// to take any error, not just wrapped errors. This allows you to use errwrap +// without having to type-check and type-cast everywhere. +package errwrap + +import ( + "errors" + "reflect" + "strings" +) + +// WalkFunc is the callback called for Walk. +type WalkFunc func(error) + +// Wrapper is an interface that can be implemented by custom types to +// have all the Contains, Get, etc. functions in errwrap work. +// +// When Walk reaches a Wrapper, it will call the callback for every +// wrapped error in addition to the wrapper itself. Since all the top-level +// functions in errwrap use Walk, this means that all those functions work +// with your custom type. +type Wrapper interface { + WrappedErrors() []error +} + +// Wrap defines that outer wraps inner, returning an error type that +// can be cleanly used with the other methods in this package, such as +// Contains, GetAll, etc. +// +// This function won't modify the error message at all (the outer message +// will be used). +func Wrap(outer, inner error) error { + return &wrappedError{ + Outer: outer, + Inner: inner, + } +} + +// Wrapf wraps an error with a formatting message. This is similar to using +// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap +// errors, you should replace it with this. +// +// format is the format of the error message. The string '{{err}}' will +// be replaced with the original error message. +// +// Deprecated: Use fmt.Errorf() +func Wrapf(format string, err error) error { + outerMsg := "" + if err != nil { + outerMsg = err.Error() + } + + outer := errors.New(strings.Replace( + format, "{{err}}", outerMsg, -1)) + + return Wrap(outer, err) +} + +// Contains checks if the given error contains an error with the +// message msg. If err is not a wrapped error, this will always return +// false unless the error itself happens to match this msg. +func Contains(err error, msg string) bool { + return len(GetAll(err, msg)) > 0 +} + +// ContainsType checks if the given error contains an error with +// the same concrete type as v. If err is not a wrapped error, this will +// check the err itself. +func ContainsType(err error, v interface{}) bool { + return len(GetAllType(err, v)) > 0 +} + +// Get is the same as GetAll but returns the deepest matching error. +func Get(err error, msg string) error { + es := GetAll(err, msg) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetType is the same as GetAllType but returns the deepest matching error. +func GetType(err error, v interface{}) error { + es := GetAllType(err, v) + if len(es) > 0 { + return es[len(es)-1] + } + + return nil +} + +// GetAll gets all the errors that might be wrapped in err with the +// given message. The order of the errors is such that the outermost +// matching error (the most recent wrap) is index zero, and so on. +func GetAll(err error, msg string) []error { + var result []error + + Walk(err, func(err error) { + if err.Error() == msg { + result = append(result, err) + } + }) + + return result +} + +// GetAllType gets all the errors that are the same type as v. +// +// The order of the return value is the same as described in GetAll. +func GetAllType(err error, v interface{}) []error { + var result []error + + var search string + if v != nil { + search = reflect.TypeOf(v).String() + } + Walk(err, func(err error) { + var needle string + if err != nil { + needle = reflect.TypeOf(err).String() + } + + if needle == search { + result = append(result, err) + } + }) + + return result +} + +// Walk walks all the wrapped errors in err and calls the callback. If +// err isn't a wrapped error, this will be called once for err. If err +// is a wrapped error, the callback will be called for both the wrapper +// that implements error as well as the wrapped error itself. +func Walk(err error, cb WalkFunc) { + if err == nil { + return + } + + switch e := err.(type) { + case *wrappedError: + cb(e.Outer) + Walk(e.Inner, cb) + case Wrapper: + cb(err) + + for _, err := range e.WrappedErrors() { + Walk(err, cb) + } + case interface{ Unwrap() error }: + cb(err) + Walk(e.Unwrap(), cb) + default: + cb(err) + } +} + +// wrappedError is an implementation of error that has both the +// outer and inner errors. +type wrappedError struct { + Outer error + Inner error +} + +func (w *wrappedError) Error() string { + return w.Outer.Error() +} + +func (w *wrappedError) WrappedErrors() []error { + return []error{w.Outer, w.Inner} +} + +func (w *wrappedError) Unwrap() error { + return w.Inner +} diff --git a/vendor/github.com/hashicorp/go-multierror/LICENSE b/vendor/github.com/hashicorp/go-multierror/LICENSE new file mode 100644 index 00000000..82b4de97 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/LICENSE @@ -0,0 +1,353 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. diff --git a/vendor/github.com/hashicorp/go-multierror/Makefile b/vendor/github.com/hashicorp/go-multierror/Makefile new file mode 100644 index 00000000..b97cd6ed --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/Makefile @@ -0,0 +1,31 @@ +TEST?=./... + +default: test + +# test runs the test suite and vets the code. +test: generate + @echo "==> Running tests..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -parallel=10 ${TESTARGS} + +# testrace runs the race checker +testrace: generate + @echo "==> Running tests (race)..." + @go list $(TEST) \ + | grep -v "/vendor/" \ + | xargs -n1 go test -timeout=60s -race ${TESTARGS} + +# updatedeps installs all the dependencies needed to run and build. +updatedeps: + @sh -c "'${CURDIR}/scripts/deps.sh' '${NAME}'" + +# generate runs `go generate` to build the dynamically generated source files. +generate: + @echo "==> Generating..." + @find . -type f -name '.DS_Store' -delete + @go list ./... \ + | grep -v "/vendor/" \ + | xargs -n1 go generate + +.PHONY: default test testrace updatedeps generate diff --git a/vendor/github.com/hashicorp/go-multierror/README.md b/vendor/github.com/hashicorp/go-multierror/README.md new file mode 100644 index 00000000..71dd308e --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/README.md @@ -0,0 +1,150 @@ +# go-multierror + +[![CircleCI](https://img.shields.io/circleci/build/github/hashicorp/go-multierror/master)](https://circleci.com/gh/hashicorp/go-multierror) +[![Go Reference](https://pkg.go.dev/badge/github.com/hashicorp/go-multierror.svg)](https://pkg.go.dev/github.com/hashicorp/go-multierror) +![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/hashicorp/go-multierror) + +[circleci]: https://app.circleci.com/pipelines/github/hashicorp/go-multierror +[godocs]: https://pkg.go.dev/github.com/hashicorp/go-multierror + +`go-multierror` is a package for Go that provides a mechanism for +representing a list of `error` values as a single `error`. + +This allows a function in Go to return an `error` that might actually +be a list of errors. If the caller knows this, they can unwrap the +list and access the errors. If the caller doesn't know, the error +formats to a nice human-readable format. + +`go-multierror` is fully compatible with the Go standard library +[errors](https://golang.org/pkg/errors/) package, including the +functions `As`, `Is`, and `Unwrap`. This provides a standardized approach +for introspecting on error values. + +## Installation and Docs + +Install using `go get github.com/hashicorp/go-multierror`. + +Full documentation is available at +https://pkg.go.dev/github.com/hashicorp/go-multierror + +### Requires go version 1.13 or newer + +`go-multierror` requires go version 1.13 or newer. Go 1.13 introduced +[error wrapping](https://golang.org/doc/go1.13#error_wrapping), which +this library takes advantage of. + +If you need to use an earlier version of go, you can use the +[v1.0.0](https://github.com/hashicorp/go-multierror/tree/v1.0.0) +tag, which doesn't rely on features in go 1.13. + +If you see compile errors that look like the below, it's likely that +you're on an older version of go: + +``` +/go/src/github.com/hashicorp/go-multierror/multierror.go:112:9: undefined: errors.As +/go/src/github.com/hashicorp/go-multierror/multierror.go:117:9: undefined: errors.Is +``` + +## Usage + +go-multierror is easy to use and purposely built to be unobtrusive in +existing Go applications/libraries that may not be aware of it. + +**Building a list of errors** + +The `Append` function is used to create a list of errors. This function +behaves a lot like the Go built-in `append` function: it doesn't matter +if the first argument is nil, a `multierror.Error`, or any other `error`, +the function behaves as you would expect. + +```go +var result error + +if err := step1(); err != nil { + result = multierror.Append(result, err) +} +if err := step2(); err != nil { + result = multierror.Append(result, err) +} + +return result +``` + +**Customizing the formatting of the errors** + +By specifying a custom `ErrorFormat`, you can customize the format +of the `Error() string` function: + +```go +var result *multierror.Error + +// ... accumulate errors here, maybe using Append + +if result != nil { + result.ErrorFormat = func([]error) string { + return "errors!" + } +} +``` + +**Accessing the list of errors** + +`multierror.Error` implements `error` so if the caller doesn't know about +multierror, it will work just fine. But if you're aware a multierror might +be returned, you can use type switches to access the list of errors: + +```go +if err := something(); err != nil { + if merr, ok := err.(*multierror.Error); ok { + // Use merr.Errors + } +} +``` + +You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap) +function. This will continue to unwrap into subsequent errors until none exist. + +**Extracting an error** + +The standard library [`errors.As`](https://golang.org/pkg/errors/#As) +function can be used directly with a multierror to extract a specific error: + +```go +// Assume err is a multierror value +err := somefunc() + +// We want to know if "err" has a "RichErrorType" in it and extract it. +var errRich RichErrorType +if errors.As(err, &errRich) { + // It has it, and now errRich is populated. +} +``` + +**Checking for an exact error value** + +Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables) +error in the `os` package. You can check if this error is present by using +the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function. + +```go +// Assume err is a multierror value +err := somefunc() +if errors.Is(err, os.ErrNotExist) { + // err contains os.ErrNotExist +} +``` + +**Returning a multierror only if there are errors** + +If you build a `multierror.Error`, you can use the `ErrorOrNil` function +to return an `error` implementation only if there are errors to return: + +```go +var result *multierror.Error + +// ... accumulate errors here + +// Return the `error` only if errors were added to the multierror, otherwise +// return nil since there are no errors. +return result.ErrorOrNil() +``` diff --git a/vendor/github.com/hashicorp/go-multierror/append.go b/vendor/github.com/hashicorp/go-multierror/append.go new file mode 100644 index 00000000..3e2589bf --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/append.go @@ -0,0 +1,43 @@ +package multierror + +// Append is a helper function that will append more errors +// onto an Error in order to create a larger multi-error. +// +// If err is not a multierror.Error, then it will be turned into +// one. If any of the errs are multierr.Error, they will be flattened +// one level into err. +// Any nil errors within errs will be ignored. If err is nil, a new +// *Error will be returned. +func Append(err error, errs ...error) *Error { + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Go through each error and flatten + for _, e := range errs { + switch e := e.(type) { + case *Error: + if e != nil { + err.Errors = append(err.Errors, e.Errors...) + } + default: + if e != nil { + err.Errors = append(err.Errors, e) + } + } + } + + return err + default: + newErrs := make([]error, 0, len(errs)+1) + if err != nil { + newErrs = append(newErrs, err) + } + newErrs = append(newErrs, errs...) + + return Append(&Error{}, newErrs...) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/flatten.go b/vendor/github.com/hashicorp/go-multierror/flatten.go new file mode 100644 index 00000000..aab8e9ab --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/flatten.go @@ -0,0 +1,26 @@ +package multierror + +// Flatten flattens the given error, merging any *Errors together into +// a single *Error. +func Flatten(err error) error { + // If it isn't an *Error, just return the error as-is + if _, ok := err.(*Error); !ok { + return err + } + + // Otherwise, make the result and flatten away! + flatErr := new(Error) + flatten(err, flatErr) + return flatErr +} + +func flatten(err error, flatErr *Error) { + switch err := err.(type) { + case *Error: + for _, e := range err.Errors { + flatten(e, flatErr) + } + default: + flatErr.Errors = append(flatErr.Errors, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/format.go b/vendor/github.com/hashicorp/go-multierror/format.go new file mode 100644 index 00000000..47f13c49 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/format.go @@ -0,0 +1,27 @@ +package multierror + +import ( + "fmt" + "strings" +) + +// ErrorFormatFunc is a function callback that is called by Error to +// turn the list of errors into a string. +type ErrorFormatFunc func([]error) string + +// ListFormatFunc is a basic formatter that outputs the number of errors +// that occurred along with a bullet point list of the errors. +func ListFormatFunc(es []error) string { + if len(es) == 1 { + return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0]) + } + + points := make([]string, len(es)) + for i, err := range es { + points[i] = fmt.Sprintf("* %s", err) + } + + return fmt.Sprintf( + "%d errors occurred:\n\t%s\n\n", + len(es), strings.Join(points, "\n\t")) +} diff --git a/vendor/github.com/hashicorp/go-multierror/group.go b/vendor/github.com/hashicorp/go-multierror/group.go new file mode 100644 index 00000000..9c29efb7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/group.go @@ -0,0 +1,38 @@ +package multierror + +import "sync" + +// Group is a collection of goroutines which return errors that need to be +// coalesced. +type Group struct { + mutex sync.Mutex + err *Error + wg sync.WaitGroup +} + +// Go calls the given function in a new goroutine. +// +// If the function returns an error it is added to the group multierror which +// is returned by Wait. +func (g *Group) Go(f func() error) { + g.wg.Add(1) + + go func() { + defer g.wg.Done() + + if err := f(); err != nil { + g.mutex.Lock() + g.err = Append(g.err, err) + g.mutex.Unlock() + } + }() +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the multierror. +func (g *Group) Wait() *Error { + g.wg.Wait() + g.mutex.Lock() + defer g.mutex.Unlock() + return g.err +} diff --git a/vendor/github.com/hashicorp/go-multierror/multierror.go b/vendor/github.com/hashicorp/go-multierror/multierror.go new file mode 100644 index 00000000..f5457432 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/multierror.go @@ -0,0 +1,121 @@ +package multierror + +import ( + "errors" + "fmt" +) + +// Error is an error type to track multiple errors. This is used to +// accumulate errors in cases and return them as a single "error". +type Error struct { + Errors []error + ErrorFormat ErrorFormatFunc +} + +func (e *Error) Error() string { + fn := e.ErrorFormat + if fn == nil { + fn = ListFormatFunc + } + + return fn(e.Errors) +} + +// ErrorOrNil returns an error interface if this Error represents +// a list of errors, or returns nil if the list of errors is empty. This +// function is useful at the end of accumulation to make sure that the value +// returned represents the existence of errors. +func (e *Error) ErrorOrNil() error { + if e == nil { + return nil + } + if len(e.Errors) == 0 { + return nil + } + + return e +} + +func (e *Error) GoString() string { + return fmt.Sprintf("*%#v", *e) +} + +// WrappedErrors returns the list of errors that this Error is wrapping. It is +// an implementation of the errwrap.Wrapper interface so that multierror.Error +// can be used with that library. +// +// This method is not safe to be called concurrently. Unlike accessing the +// Errors field directly, this function also checks if the multierror is nil to +// prevent a null-pointer panic. It satisfies the errwrap.Wrapper interface. +func (e *Error) WrappedErrors() []error { + if e == nil { + return nil + } + return e.Errors +} + +// Unwrap returns an error from Error (or nil if there are no errors). +// This error returned will further support Unwrap to get the next error, +// etc. The order will match the order of Errors in the multierror.Error +// at the time of calling. +// +// The resulting error supports errors.As/Is/Unwrap so you can continue +// to use the stdlib errors package to introspect further. +// +// This will perform a shallow copy of the errors slice. Any errors appended +// to this error after calling Unwrap will not be available until a new +// Unwrap is called on the multierror.Error. +func (e *Error) Unwrap() error { + // If we have no errors then we do nothing + if e == nil || len(e.Errors) == 0 { + return nil + } + + // If we have exactly one error, we can just return that directly. + if len(e.Errors) == 1 { + return e.Errors[0] + } + + // Shallow copy the slice + errs := make([]error, len(e.Errors)) + copy(errs, e.Errors) + return chain(errs) +} + +// chain implements the interfaces necessary for errors.Is/As/Unwrap to +// work in a deterministic way with multierror. A chain tracks a list of +// errors while accounting for the current represented error. This lets +// Is/As be meaningful. +// +// Unwrap returns the next error. In the cleanest form, Unwrap would return +// the wrapped error here but we can't do that if we want to properly +// get access to all the errors. Instead, users are recommended to use +// Is/As to get the correct error type out. +// +// Precondition: []error is non-empty (len > 0) +type chain []error + +// Error implements the error interface +func (e chain) Error() string { + return e[0].Error() +} + +// Unwrap implements errors.Unwrap by returning the next error in the +// chain or nil if there are no more errors. +func (e chain) Unwrap() error { + if len(e) == 1 { + return nil + } + + return e[1:] +} + +// As implements errors.As by attempting to map to the current value. +func (e chain) As(target interface{}) bool { + return errors.As(e[0], target) +} + +// Is implements errors.Is by comparing the current value directly. +func (e chain) Is(target error) bool { + return errors.Is(e[0], target) +} diff --git a/vendor/github.com/hashicorp/go-multierror/prefix.go b/vendor/github.com/hashicorp/go-multierror/prefix.go new file mode 100644 index 00000000..5c477abe --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/prefix.go @@ -0,0 +1,37 @@ +package multierror + +import ( + "fmt" + + "github.com/hashicorp/errwrap" +) + +// Prefix is a helper function that will prefix some text +// to the given error. If the error is a multierror.Error, then +// it will be prefixed to each wrapped error. +// +// This is useful to use when appending multiple multierrors +// together in order to give better scoping. +func Prefix(err error, prefix string) error { + if err == nil { + return nil + } + + format := fmt.Sprintf("%s {{err}}", prefix) + switch err := err.(type) { + case *Error: + // Typed nils can reach here, so initialize if we are nil + if err == nil { + err = new(Error) + } + + // Wrap each of the errors + for i, e := range err.Errors { + err.Errors[i] = errwrap.Wrapf(format, e) + } + + return err + default: + return errwrap.Wrapf(format, err) + } +} diff --git a/vendor/github.com/hashicorp/go-multierror/sort.go b/vendor/github.com/hashicorp/go-multierror/sort.go new file mode 100644 index 00000000..fecb14e8 --- /dev/null +++ b/vendor/github.com/hashicorp/go-multierror/sort.go @@ -0,0 +1,16 @@ +package multierror + +// Len implements sort.Interface function for length +func (err Error) Len() int { + return len(err.Errors) +} + +// Swap implements sort.Interface function for swapping elements +func (err Error) Swap(i, j int) { + err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i] +} + +// Less implements sort.Interface function for determining order +func (err Error) Less(i, j int) bool { + return err.Errors[i].Error() < err.Errors[j].Error() +} diff --git a/vendor/github.com/moby/buildkit/client/connhelper/npipe/npipe_windows.go b/vendor/github.com/moby/buildkit/client/connhelper/npipe/npipe_windows.go index 00e83225..c9f1144a 100644 --- a/vendor/github.com/moby/buildkit/client/connhelper/npipe/npipe_windows.go +++ b/vendor/github.com/moby/buildkit/client/connhelper/npipe/npipe_windows.go @@ -19,7 +19,7 @@ func Helper(u *url.URL) (*connhelper.ConnectionHelper, error) { if len(addrParts) != 2 { return nil, errors.Errorf("invalid address %s", u) } - address := strings.Replace(addrParts[1], "/", "\\", -1) + address := strings.ReplaceAll(addrParts[1], "/", "\\") return &connhelper.ConnectionHelper{ ContextDialer: func(ctx context.Context, addr string) (net.Conn, error) { return winio.DialPipeContext(ctx, address) diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go index 9af4156f..d8da19ec 100644 --- a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/config.go @@ -33,6 +33,19 @@ type Config struct { DNS *DNSConfig `toml:"dns"` History *HistoryConfig `toml:"history"` + + Frontends struct { + Dockerfile DockerfileFrontendConfig `toml:"dockerfile.v0"` + Gateway GatewayFrontendConfig `toml:"gateway.v0"` + } `toml:"frontend"` + + System *SystemConfig `toml:"system"` +} + +type SystemConfig struct { + // PlatformCacheMaxAge controls how often supported platforms + // are refreshed by rescanning the system. + PlatformsCacheMaxAge *Duration `toml:"platformsCacheMaxAge"` } type LogConfig struct { @@ -40,10 +53,11 @@ type LogConfig struct { } type GRPCConfig struct { - Address []string `toml:"address"` - DebugAddress string `toml:"debugAddress"` - UID *int `toml:"uid"` - GID *int `toml:"gid"` + Address []string `toml:"address"` + DebugAddress string `toml:"debugAddress"` + UID *int `toml:"uid"` + GID *int `toml:"gid"` + SecurityDescriptor string `toml:"securityDescriptor"` TLS TLSConfig `toml:"tls"` // MaxRecvMsgSize int `toml:"max_recv_message_size"` @@ -154,3 +168,12 @@ type HistoryConfig struct { MaxAge Duration `toml:"maxAge"` MaxEntries int64 `toml:"maxEntries"` } + +type DockerfileFrontendConfig struct { + Enabled *bool `toml:"enabled"` +} + +type GatewayFrontendConfig struct { + Enabled *bool `toml:"enabled"` + AllowedRepositories []string `toml:"allowedRepositories"` +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go index 4078cc6d..5e9ac6ac 100644 --- a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy.go @@ -7,6 +7,7 @@ import ( "time" "github.com/docker/go-units" + "github.com/moby/buildkit/util/bklog" "github.com/pkg/errors" ) @@ -104,3 +105,25 @@ func stripQuotes(s string) string { } return s } + +func DetectDefaultGCCap() DiskSpace { + return DiskSpace{Percentage: DiskSpacePercentage} +} + +func (d DiskSpace) AsBytes(root string) int64 { + if d.Bytes != 0 { + return d.Bytes + } + if d.Percentage == 0 { + return 0 + } + + diskSize, err := getDiskSize(root) + if err != nil { + bklog.L.Warnf("failed to get disk size: %v", err) + return defaultCap + } + avail := diskSize * d.Percentage / 100 + rounded := (avail/(1<<30) + 1) * 1e9 // round up + return rounded +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_openbsd.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_openbsd.go new file mode 100644 index 00000000..341ac2cd --- /dev/null +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_openbsd.go @@ -0,0 +1,19 @@ +//go:build openbsd +// +build openbsd + +package config + +import ( + "syscall" +) + +var DiskSpacePercentage int64 = 10 + +func getDiskSize(root string) (int64, error) { + var st syscall.Statfs_t + if err := syscall.Statfs(root, &st); err != nil { + return 0, err + } + diskSize := int64(st.F_bsize) * int64(st.F_blocks) + return diskSize, nil +} diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go index 232a9ac3..b88e2172 100644 --- a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_unix.go @@ -1,5 +1,5 @@ -//go:build !windows -// +build !windows +//go:build !windows && !openbsd +// +build !windows,!openbsd package config @@ -7,23 +7,13 @@ import ( "syscall" ) -func DetectDefaultGCCap() DiskSpace { - return DiskSpace{Percentage: 10} -} - -func (d DiskSpace) AsBytes(root string) int64 { - if d.Bytes != 0 { - return d.Bytes - } - if d.Percentage == 0 { - return 0 - } +var DiskSpacePercentage int64 = 10 +func getDiskSize(root string) (int64, error) { var st syscall.Statfs_t if err := syscall.Statfs(root, &st); err != nil { - return defaultCap + return 0, err } diskSize := int64(st.Bsize) * int64(st.Blocks) - avail := diskSize * d.Percentage / 100 - return (avail/(1<<30) + 1) * 1e9 // round up + return diskSize, nil } diff --git a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go index 55ce4dd7..77c7099d 100644 --- a/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go +++ b/vendor/github.com/moby/buildkit/cmd/buildkitd/config/gcpolicy_windows.go @@ -3,10 +3,29 @@ package config -func DetectDefaultGCCap() DiskSpace { - return DiskSpace{Bytes: defaultCap} -} +import ( + "golang.org/x/sys/windows" +) -func (d DiskSpace) AsBytes(root string) int64 { - return d.Bytes +// set as double that for Linux since +// Windows images are generally larger. +var DiskSpacePercentage int64 = 20 + +func getDiskSize(root string) (int64, error) { + rootUTF16, err := windows.UTF16FromString(root) + if err != nil { + return 0, err + } + var freeAvailableBytes uint64 + var totalBytes uint64 + var totalFreeBytes uint64 + + if err := windows.GetDiskFreeSpaceEx( + &rootUTF16[0], + &freeAvailableBytes, + &totalBytes, + &totalFreeBytes); err != nil { + return 0, err + } + return int64(totalBytes), nil } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go index db1668f2..651b1314 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/directives.go @@ -13,12 +13,14 @@ import ( const ( keySyntax = "syntax" + keyCheck = "check" keyEscape = "escape" ) var validDirectives = map[string]struct{}{ keySyntax: {}, keyEscape: {}, + keyCheck: {}, } type Directive struct { @@ -110,6 +112,10 @@ func (d *DirectiveParser) ParseAll(data []byte) ([]*Directive, error) { // This allows for a flexible range of input formats, and appropriate syntax // selection. func DetectSyntax(dt []byte) (string, string, []Range, bool) { + return ParseDirective(keySyntax, dt) +} + +func ParseDirective(key string, dt []byte) (string, string, []Range, bool) { dt, hadShebang, err := discardShebang(dt) if err != nil { return "", "", nil, false @@ -119,42 +125,38 @@ func DetectSyntax(dt []byte) (string, string, []Range, bool) { line++ } - // use default directive parser, and search for #syntax= + // use default directive parser, and search for #key= directiveParser := DirectiveParser{line: line} - if syntax, cmdline, loc, ok := detectSyntaxFromParser(dt, directiveParser); ok { + if syntax, cmdline, loc, ok := detectDirectiveFromParser(key, dt, directiveParser); ok { return syntax, cmdline, loc, true } - // use directive with different comment prefix, and search for //syntax= + // use directive with different comment prefix, and search for //key= directiveParser = DirectiveParser{line: line} directiveParser.setComment("//") - if syntax, cmdline, loc, ok := detectSyntaxFromParser(dt, directiveParser); ok { + if syntax, cmdline, loc, ok := detectDirectiveFromParser(key, dt, directiveParser); ok { return syntax, cmdline, loc, true } - // search for possible json directives - var directive struct { - Syntax string `json:"syntax"` - } - if err := json.Unmarshal(dt, &directive); err == nil { - if directive.Syntax != "" { + // use json directive, and search for { "key": "..." } + jsonDirective := map[string]string{} + if err := json.Unmarshal(dt, &jsonDirective); err == nil { + if v, ok := jsonDirective[key]; ok { loc := []Range{{ Start: Position{Line: line}, End: Position{Line: line}, }} - return directive.Syntax, directive.Syntax, loc, true + return v, v, loc, true } } return "", "", nil, false } -func detectSyntaxFromParser(dt []byte, parser DirectiveParser) (string, string, []Range, bool) { +func detectDirectiveFromParser(key string, dt []byte, parser DirectiveParser) (string, string, []Range, bool) { directives, _ := parser.ParseAll(dt) for _, d := range directives { - // check for syntax directive before erroring out, since the error - // might have occurred *after* the syntax directive - if d.Name == keySyntax { + if d.Name == key { p, _, _ := strings.Cut(d.Value, " ") return p, d.Value, d.Location, true } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go index 33f7965d..4f621df7 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go @@ -154,7 +154,7 @@ func parseNameVal(rest string, key string, d *directives) (*Node, error) { if len(parts) < 2 { return nil, errors.Errorf("%s must have two arguments", key) } - return newKeyValueNode(parts[0], parts[1]), nil + return newKeyValueNode(parts[0], parts[1], ""), nil } var rootNode *Node @@ -165,17 +165,20 @@ func parseNameVal(rest string, key string, d *directives) (*Node, error) { } parts := strings.SplitN(word, "=", 2) - node := newKeyValueNode(parts[0], parts[1]) + node := newKeyValueNode(parts[0], parts[1], "=") rootNode, prevNode = appendKeyValueNode(node, rootNode, prevNode) } return rootNode, nil } -func newKeyValueNode(key, value string) *Node { +func newKeyValueNode(key, value, sep string) *Node { return &Node{ Value: key, - Next: &Node{Value: value}, + Next: &Node{ + Value: value, + Next: &Node{Value: sep}, + }, } } @@ -187,7 +190,9 @@ func appendKeyValueNode(node, rootNode, prevNode *Node) (*Node, *Node) { prevNode.Next = node } - prevNode = node.Next + for prevNode = node.Next; prevNode.Next != nil; { + prevNode = prevNode.Next + } return rootNode, prevNode } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go index 7f6934a9..306eb5e8 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go @@ -32,10 +32,12 @@ func NewLex(escapeToken rune) *Lex { } // ProcessWord will use the 'env' list of environment variables, -// and replace any env var references in 'word'. -func (s *Lex) ProcessWord(word string, env []string) (string, error) { - word, _, err := s.process(word, BuildEnvs(env)) - return word, err +// and replace any env var references in 'word'. It will also +// return variables in word which were not found in the 'env' list, +// which is useful in later linting. +func (s *Lex) ProcessWord(word string, env []string) (string, map[string]struct{}, error) { + result, err := s.process(word, BuildEnvs(env)) + return result.Result, result.Unmatched, err } // ProcessWords will use the 'env' list of environment variables, @@ -46,28 +48,40 @@ func (s *Lex) ProcessWord(word string, env []string) (string, error) { // Note, each one is trimmed to remove leading and trailing spaces (unless // they are quoted", but ProcessWord retains spaces between words. func (s *Lex) ProcessWords(word string, env []string) ([]string, error) { - _, words, err := s.process(word, BuildEnvs(env)) - return words, err + result, err := s.process(word, BuildEnvs(env)) + return result.Words, err } // ProcessWordWithMap will use the 'env' list of environment variables, // and replace any env var references in 'word'. func (s *Lex) ProcessWordWithMap(word string, env map[string]string) (string, error) { - word, _, err := s.process(word, env) - return word, err + result, err := s.process(word, env) + return result.Result, err +} + +type ProcessWordResult struct { + Result string + Words []string + Matched map[string]struct{} + Unmatched map[string]struct{} } // ProcessWordWithMatches will use the 'env' list of environment variables, // replace any env var references in 'word' and return the env that were used. -func (s *Lex) ProcessWordWithMatches(word string, env map[string]string) (string, map[string]struct{}, error) { +func (s *Lex) ProcessWordWithMatches(word string, env map[string]string) (ProcessWordResult, error) { sw := s.init(word, env) - word, _, err := sw.process(word) - return word, sw.matches, err + word, words, err := sw.process(word) + return ProcessWordResult{ + Result: word, + Words: words, + Matched: sw.matches, + Unmatched: sw.nonmatches, + }, err } func (s *Lex) ProcessWordsWithMap(word string, env map[string]string) ([]string, error) { - _, words, err := s.process(word, env) - return words, err + result, err := s.process(word, env) + return result.Words, err } func (s *Lex) init(word string, env map[string]string) *shellWord { @@ -79,14 +93,21 @@ func (s *Lex) init(word string, env map[string]string) *shellWord { rawQuotes: s.RawQuotes, rawEscapes: s.RawEscapes, matches: make(map[string]struct{}), + nonmatches: make(map[string]struct{}), } sw.scanner.Init(strings.NewReader(word)) return sw } -func (s *Lex) process(word string, env map[string]string) (string, []string, error) { +func (s *Lex) process(word string, env map[string]string) (*ProcessWordResult, error) { sw := s.init(word, env) - return sw.process(word) + word, words, err := sw.process(word) + return &ProcessWordResult{ + Result: word, + Words: words, + Matched: sw.matches, + Unmatched: sw.nonmatches, + }, err } type shellWord struct { @@ -98,6 +119,7 @@ type shellWord struct { skipUnsetEnv bool skipProcessQuotes bool matches map[string]struct{} + nonmatches map[string]struct{} } func (sw *shellWord) process(source string) (string, []string, error) { @@ -511,6 +533,7 @@ func (sw *shellWord) getEnv(name string) (string, bool) { return value, true } } + sw.nonmatches[name] = struct{}{} return "", false } diff --git a/vendor/github.com/moby/buildkit/frontend/dockerui/config.go b/vendor/github.com/moby/buildkit/frontend/dockerui/config.go index 476c9faf..d99b3aff 100644 --- a/vendor/github.com/moby/buildkit/frontend/dockerui/config.go +++ b/vendor/github.com/moby/buildkit/frontend/dockerui/config.go @@ -47,6 +47,7 @@ const ( keyCacheNSArg = "build-arg:BUILDKIT_CACHE_MOUNT_NS" keyMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM" keyHostnameArg = "build-arg:BUILDKIT_SANDBOX_HOSTNAME" + keyDockerfileLintArg = "build-arg:BUILDKIT_DOCKERFILE_CHECK" keyContextKeepGitDirArg = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR" keySourceDateEpoch = "build-arg:SOURCE_DATE_EPOCH" ) @@ -64,6 +65,7 @@ type Config struct { ShmSize int64 Target string Ulimits []pb.Ulimit + LinterConfig *string CacheImports []client.CacheOptionsEntry TargetPlatforms []ocispecs.Platform // nil means default @@ -277,6 +279,10 @@ func (bc *Client) init() error { opts[keyHostname] = v } bc.Hostname = opts[keyHostname] + + if v, ok := opts[keyDockerfileLintArg]; ok { + bc.LinterConfig = &v + } return nil } diff --git a/vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go b/vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go index f5e82077..cb857a09 100644 --- a/vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go +++ b/vendor/github.com/moby/buildkit/frontend/gateway/grpcclient/client.go @@ -1249,11 +1249,18 @@ func (r *reference) StatFile(ctx context.Context, req client.StatRequest) (*fsty } func grpcClientConn(ctx context.Context) (context.Context, *grpc.ClientConn, error) { - dialOpt := grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { - return stdioConn(), nil - }) + dialOpts := []grpc.DialOption{ + grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + return stdioConn(), nil + }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithUnaryInterceptor(grpcerrors.UnaryClientInterceptor), + grpc.WithStreamInterceptor(grpcerrors.StreamClientInterceptor), + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(16 << 20)), + grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(16 << 20)), + } - cc, err := grpc.DialContext(ctx, "localhost", dialOpt, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithUnaryInterceptor(grpcerrors.UnaryClientInterceptor), grpc.WithStreamInterceptor(grpcerrors.StreamClientInterceptor)) + cc, err := grpc.DialContext(ctx, "localhost", dialOpts...) if err != nil { return nil, nil, errors.Wrap(err, "failed to create grpc client") } diff --git a/vendor/github.com/moby/buildkit/frontend/subrequests/lint/lint.go b/vendor/github.com/moby/buildkit/frontend/subrequests/lint/lint.go index 6237eb3c..99a36ff1 100644 --- a/vendor/github.com/moby/buildkit/frontend/subrequests/lint/lint.go +++ b/vendor/github.com/moby/buildkit/frontend/subrequests/lint/lint.go @@ -39,9 +39,15 @@ type Warning struct { Location pb.Location `json:"location,omitempty"` } +type BuildError struct { + Message string `json:"message"` + Location pb.Location `json:"location"` +} + type LintResults struct { Warnings []Warning `json:"warnings"` Sources []*pb.SourceInfo `json:"sources"` + Error *BuildError `json:"buildError,omitempty"` } func (results *LintResults) AddSource(sourceMap *llb.SourceMap) int { diff --git a/vendor/github.com/moby/buildkit/frontend/subrequests/targets/targets.go b/vendor/github.com/moby/buildkit/frontend/subrequests/targets/targets.go index bf00a3b2..d9d9dcd9 100644 --- a/vendor/github.com/moby/buildkit/frontend/subrequests/targets/targets.go +++ b/vendor/github.com/moby/buildkit/frontend/subrequests/targets/targets.go @@ -72,10 +72,8 @@ func PrintTargets(dt []byte, w io.Writer) error { name := t.Name if name == "" && t.Default { name = "(default)" - } else { - if t.Default { - name = fmt.Sprintf("%s (default)", name) - } + } else if t.Default { + name = fmt.Sprintf("%s (default)", name) } fmt.Fprintf(tw, "%s\t%s\n", name, t.Description) } diff --git a/vendor/github.com/moby/buildkit/session/sshforward/sshprovider/agentprovider.go b/vendor/github.com/moby/buildkit/session/sshforward/sshprovider/agentprovider.go index f6501113..4b263143 100644 --- a/vendor/github.com/moby/buildkit/session/sshforward/sshprovider/agentprovider.go +++ b/vendor/github.com/moby/buildkit/session/sshforward/sshprovider/agentprovider.go @@ -166,6 +166,7 @@ func toAgentSource(paths []string) (source, error) { return source{}, errors.Wrapf(err, "failed to open %s", p) } dt, err := io.ReadAll(&io.LimitedReader{R: f, N: 100 * 1024}) + _ = f.Close() if err != nil { return source{}, errors.Wrapf(err, "failed to read %s", p) } diff --git a/vendor/github.com/moby/buildkit/util/gitutil/git_cli.go b/vendor/github.com/moby/buildkit/util/gitutil/git_cli.go index dac803f8..61187184 100644 --- a/vendor/github.com/moby/buildkit/util/gitutil/git_cli.go +++ b/vendor/github.com/moby/buildkit/util/gitutil/git_cli.go @@ -210,13 +210,23 @@ func (cli *GitCLI) Run(ctx context.Context, args ...string) (_ []byte, err error } if err != nil { + select { + case <-ctx.Done(): + cerr := context.Cause(ctx) + if cerr != nil { + return buf.Bytes(), errors.Wrapf(cerr, "context completed: git stderr:\n%s", errbuf.String()) + } + default: + } + if strings.Contains(errbuf.String(), "--depth") || strings.Contains(errbuf.String(), "shallow") { if newArgs := argsNoDepth(args); len(args) > len(newArgs) { args = newArgs continue } } - return buf.Bytes(), errors.Errorf("git error: %s\nstderr:\n%s", err, errbuf.String()) + + return buf.Bytes(), errors.Wrapf(err, "git stderr:\n%s", errbuf.String()) } return buf.Bytes(), nil } diff --git a/vendor/github.com/moby/buildkit/util/progress/multireader.go b/vendor/github.com/moby/buildkit/util/progress/multireader.go index d6d3fb7c..6afcca9f 100644 --- a/vendor/github.com/moby/buildkit/util/progress/multireader.go +++ b/vendor/github.com/moby/buildkit/util/progress/multireader.go @@ -95,6 +95,7 @@ func (mr *MultiReader) Reader(ctx context.Context) Reader { mr.mu.Lock() defer mr.mu.Unlock() delete(mr.writers, w) + closeWriter(context.Cause(ctx)) }() if !mr.initialized { diff --git a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go index fcc4b835..c6ec68e6 100644 --- a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go +++ b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go @@ -285,7 +285,6 @@ type rawJSONDisplay struct { // output of status update events. func newRawJSONDisplay(w io.Writer) Display { enc := json.NewEncoder(w) - enc.SetIndent("", " ") return Display{ disp: &rawJSONDisplay{ enc: enc, @@ -744,6 +743,7 @@ func (t *trace) update(s *client.SolveStatus, termWidth int) { v.jobCached = false if v.term != nil { if v.term.Width != termWidth { + termHeight = max(termHeightMin, min(termHeightInitial, v.term.Height-termHeightMin-1)) v.term.Resize(termHeight, termWidth-termPad) } v.termBytes += len(l.Data) @@ -823,7 +823,7 @@ func (t *trace) displayInfo() (d displayInfo) { } var jobs []*job j := &job{ - name: strings.Replace(v.Name, "\t", " ", -1), + name: strings.ReplaceAll(v.Name, "\t", " "), vertex: v, isCompleted: true, } @@ -913,7 +913,7 @@ func addTime(tm *time.Time, d time.Duration) *time.Time { if tm == nil { return nil } - t := (*tm).Add(d) + t := tm.Add(d) return &t } @@ -957,6 +957,7 @@ func setupTerminals(jobs []*job, height int, all bool) []*job { numFree := height - 2 - numInUse numToHide := 0 + termHeight = max(termHeightMin, min(termHeightInitial, height-termHeightMin-1)) termLimit := termHeight + 3 for i := 0; numFree > termLimit && i < len(candidates); i++ { diff --git a/vendor/github.com/moby/buildkit/util/progress/progressui/init.go b/vendor/github.com/moby/buildkit/util/progress/progressui/init.go index 0bef2e23..e34af9ef 100644 --- a/vendor/github.com/moby/buildkit/util/progress/progressui/init.go +++ b/vendor/github.com/moby/buildkit/util/progress/progressui/init.go @@ -13,7 +13,10 @@ var colorCancel aec.ANSI var colorWarning aec.ANSI var colorError aec.ANSI -var termHeight = 6 +const termHeightMin = 6 + +var termHeightInitial = termHeightMin +var termHeight = termHeightMin func init() { // As recommended on https://no-color.org/ @@ -43,6 +46,7 @@ func init() { if termHeightStr != "" { termHeightVal, err := strconv.Atoi(termHeightStr) if err == nil && termHeightVal > 0 { + termHeightInitial = termHeightVal termHeight = termHeightVal } } diff --git a/vendor/github.com/moby/buildkit/util/system/path.go b/vendor/github.com/moby/buildkit/util/system/path.go index 422651ec..cdfff680 100644 --- a/vendor/github.com/moby/buildkit/util/system/path.go +++ b/vendor/github.com/moby/buildkit/util/system/path.go @@ -89,7 +89,7 @@ func ToSlash(inputPath, inputOS string) string { if inputOS != "windows" { return inputPath } - return strings.Replace(inputPath, "\\", "/", -1) + return strings.ReplaceAll(inputPath, "\\", "/") } func FromSlash(inputPath, inputOS string) string { @@ -97,7 +97,7 @@ func FromSlash(inputPath, inputOS string) string { if inputOS == "windows" { separator = "\\" } - return strings.Replace(inputPath, "/", separator, -1) + return strings.ReplaceAll(inputPath, "/", separator) } // NormalizeWorkdir will return a normalized version of the new workdir, given diff --git a/vendor/github.com/moby/buildkit/util/testutil/integration/run.go b/vendor/github.com/moby/buildkit/util/testutil/integration/run.go index 208219de..a336b82f 100644 --- a/vendor/github.com/moby/buildkit/util/testutil/integration/run.go +++ b/vendor/github.com/moby/buildkit/util/testutil/integration/run.go @@ -21,6 +21,7 @@ import ( "github.com/moby/buildkit/util/appcontext" "github.com/moby/buildkit/util/contentutil" ocispecs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/pkg/errors" "github.com/stretchr/testify/require" "golang.org/x/sync/semaphore" ) @@ -197,6 +198,9 @@ func Run(t *testing.T, testCases []Test, opt ...TestOpt) { require.NoError(t, sandboxLimiter.Acquire(context.TODO(), 1)) defer sandboxLimiter.Release(1) + ctx, cancel := context.WithCancelCause(ctx) + defer cancel(errors.WithStack(context.Canceled)) + sb, closer, err := newSandbox(ctx, br, mirror, mv) require.NoError(t, err) t.Cleanup(func() { _ = closer() }) diff --git a/vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go b/vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go index 585a8baa..685458b1 100644 --- a/vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go +++ b/vendor/github.com/moby/buildkit/util/testutil/integration/sandbox.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "strings" "testing" @@ -65,6 +66,10 @@ func (sb *sandbox) Cmd(args ...string) *exec.Cmd { cmd := exec.Command("buildctl", args...) cmd.Env = append(cmd.Env, os.Environ()...) cmd.Env = append(cmd.Env, "BUILDKIT_HOST="+sb.Address()) + if v := os.Getenv("GO_TEST_COVERPROFILE"); v != "" { + coverDir := filepath.Join(filepath.Dir(v), "helpers") + cmd.Env = append(cmd.Env, "GOCOVERDIR="+coverDir) + } return cmd } diff --git a/vendor/github.com/moby/buildkit/util/testutil/workers/util.go b/vendor/github.com/moby/buildkit/util/testutil/workers/util.go index 9a10cb46..4db40cef 100644 --- a/vendor/github.com/moby/buildkit/util/testutil/workers/util.go +++ b/vendor/github.com/moby/buildkit/util/testutil/workers/util.go @@ -79,6 +79,10 @@ func runBuildkitd( "BUILDKIT_DEBUG_EXEC_OUTPUT=1", "BUILDKIT_DEBUG_PANIC_ON_ERROR=1", "TMPDIR="+filepath.Join(tmpdir, "tmp")) + if v := os.Getenv("GO_TEST_COVERPROFILE"); v != "" { + coverDir := filepath.Join(filepath.Dir(v), "helpers") + cmd.Env = append(cmd.Env, "GOCOVERDIR="+coverDir) + } cmd.Env = append(cmd.Env, extraEnv...) cmd.SysProcAttr = getSysProcAttr() diff --git a/vendor/github.com/moby/buildkit/util/tracing/detect/delegated/delegated.go b/vendor/github.com/moby/buildkit/util/tracing/delegated/delegated.go similarity index 80% rename from vendor/github.com/moby/buildkit/util/tracing/detect/delegated/delegated.go rename to vendor/github.com/moby/buildkit/util/tracing/delegated/delegated.go index f32f1737..9d280592 100644 --- a/vendor/github.com/moby/buildkit/util/tracing/detect/delegated/delegated.go +++ b/vendor/github.com/moby/buildkit/util/tracing/delegated/delegated.go @@ -4,19 +4,13 @@ import ( "context" "sync" - "github.com/moby/buildkit/util/tracing/detect" + "github.com/moby/buildkit/client" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) const maxBuffer = 256 -var exp = &Exporter{} - -func init() { - detect.Register("delegated", detect.TraceExporterDetector(func() (sdktrace.SpanExporter, error) { - return exp, nil - }), 100) -} +var DefaultExporter = &Exporter{} type Exporter struct { mu sync.Mutex @@ -24,7 +18,10 @@ type Exporter struct { buffer []sdktrace.ReadOnlySpan } -var _ sdktrace.SpanExporter = &Exporter{} +var ( + _ sdktrace.SpanExporter = (*Exporter)(nil) + _ client.TracerDelegate = (*Exporter)(nil) +) func (e *Exporter) ExportSpans(ctx context.Context, ss []sdktrace.ReadOnlySpan) error { e.mu.Lock() diff --git a/vendor/github.com/moby/buildkit/util/tracing/detect/detect.go b/vendor/github.com/moby/buildkit/util/tracing/detect/detect.go index 5d1fc036..b32cc71f 100644 --- a/vendor/github.com/moby/buildkit/util/tracing/detect/detect.go +++ b/vendor/github.com/moby/buildkit/util/tracing/detect/detect.go @@ -3,22 +3,13 @@ package detect import ( "context" "os" - "path/filepath" "sort" "strconv" - "sync" - "github.com/moby/buildkit/util/bklog" "github.com/pkg/errors" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/prometheus" - "go.opentelemetry.io/otel/metric" sdkmetric "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/resource" + "go.opentelemetry.io/otel/sdk/metric/metricdata" sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.21.0" - "go.opentelemetry.io/otel/trace" - "go.opentelemetry.io/otel/trace/noop" ) type ExporterDetector interface { @@ -31,18 +22,7 @@ type detector struct { priority int } -var ServiceName string - var detectors map[string]detector -var once sync.Once -var tp trace.TracerProvider -var mp metric.MeterProvider -var exporter struct { - SpanExporter sdktrace.SpanExporter - MetricExporter sdkmetric.Exporter -} -var closers []func(context.Context) error -var err error func Register(name string, exp ExporterDetector, priority int) { if detectors == nil { @@ -64,32 +44,21 @@ func (fn TraceExporterDetector) DetectMetricExporter() (sdkmetric.Exporter, erro return nil, nil } -func detectExporters() (texp sdktrace.SpanExporter, mexp sdkmetric.Exporter, err error) { - texp, err = detectExporter("OTEL_TRACES_EXPORTER", func(d ExporterDetector) (sdktrace.SpanExporter, bool, error) { - exp, err := d.DetectTraceExporter() - return exp, exp != nil, err - }) - if err != nil { - return nil, nil, err - } - - mexp, err = detectExporter("OTEL_METRICS_EXPORTER", func(d ExporterDetector) (sdkmetric.Exporter, bool, error) { - exp, err := d.DetectMetricExporter() - return exp, exp != nil, err - }) - if err != nil { - return nil, nil, err - } - return texp, mexp, nil -} - func detectExporter[T any](envVar string, fn func(d ExporterDetector) (T, bool, error)) (exp T, err error) { + ignoreErrors, _ := strconv.ParseBool("OTEL_IGNORE_ERROR") + if n := os.Getenv(envVar); n != "" { d, ok := detectors[n] if !ok { - return exp, errors.Errorf("unsupported opentelemetry exporter %v", n) + if !ignoreErrors { + err = errors.Errorf("unsupported opentelemetry exporter %v", n) + } + return exp, err } exp, _, err = fn(d.f) + if err != nil && ignoreErrors { + err = nil + } return exp, err } @@ -104,7 +73,7 @@ func detectExporter[T any](envVar string, fn func(d ExporterDetector) (T, bool, var ok bool for _, d := range arr { exp, ok, err = fn(d.f) - if err != nil { + if err != nil && !ignoreErrors { return exp, err } @@ -115,164 +84,70 @@ func detectExporter[T any](envVar string, fn func(d ExporterDetector) (T, bool, return exp, nil } -func detect() error { - tp = noop.NewTracerProvider() - mp = sdkmetric.NewMeterProvider() - - texp, mexp, err := detectExporters() - if err != nil || (texp == nil && mexp == nil) { - return err - } - - res := Resource() - - if texp != nil || Recorder != nil { - // enable log with traceID when a valid exporter is used - bklog.EnableLogWithTraceID(true) - - sdktpopts := []sdktrace.TracerProviderOption{ - sdktrace.WithResource(res), - } - if texp != nil { - sdktpopts = append(sdktpopts, sdktrace.WithBatcher(texp)) - } - if Recorder != nil { - sp := sdktrace.NewSimpleSpanProcessor(Recorder) - sdktpopts = append(sdktpopts, sdktrace.WithSpanProcessor(sp)) - } - sdktp := sdktrace.NewTracerProvider(sdktpopts...) - closers = append(closers, sdktp.Shutdown) - - exporter.SpanExporter = texp - tp = sdktp - } - - var readers []sdkmetric.Reader - if mexp != nil { - // Create a new periodic reader using any configured metric exporter. - readers = append(readers, sdkmetric.NewPeriodicReader(mexp)) - } - - if r, err := prometheus.New(); err != nil { - // Log the error but do not fail if we could not configure the prometheus metrics. - bklog.G(context.Background()). - WithError(err). - Error("failed prometheus metrics configuration") - } else { - // Register the prometheus reader if there was no error. - readers = append(readers, r) - } - - if len(readers) > 0 { - opts := make([]sdkmetric.Option, 0, len(readers)+1) - opts = append(opts, sdkmetric.WithResource(res)) - for _, r := range readers { - opts = append(opts, sdkmetric.WithReader(r)) - } - sdkmp := sdkmetric.NewMeterProvider(opts...) - closers = append(closers, sdkmp.Shutdown) - - exporter.MetricExporter = mexp - mp = sdkmp - } - return nil -} - -func TracerProvider() (trace.TracerProvider, error) { - if err := detectOnce(); err != nil { - return nil, err - } - return tp, nil -} - -func MeterProvider() (metric.MeterProvider, error) { - if err := detectOnce(); err != nil { - return nil, err - } - return mp, nil -} - -func detectOnce() error { - once.Do(func() { - if err1 := detect(); err1 != nil { - b, _ := strconv.ParseBool(os.Getenv("OTEL_IGNORE_ERROR")) - if !b { - err = err1 - } - } - }) - return err -} - -func Exporter() (sdktrace.SpanExporter, sdkmetric.Exporter, error) { - _, err := TracerProvider() - if err != nil { - return nil, nil, err - } - return exporter.SpanExporter, exporter.MetricExporter, nil -} - -func Shutdown(ctx context.Context) error { - for _, c := range closers { - if err := c(ctx); err != nil { - return err - } - } - return nil -} - -var ( - detectedResource *resource.Resource - detectedResourceOnce sync.Once -) - -func Resource() *resource.Resource { - detectedResourceOnce.Do(func() { - res, err := resource.New(context.Background(), - resource.WithDetectors(serviceNameDetector{}), - resource.WithFromEnv(), - resource.WithTelemetrySDK(), - ) - if err != nil { - otel.Handle(err) - } - detectedResource = res - }) - return detectedResource -} - -// OverrideResource overrides the resource returned from Resource. -// -// This must be invoked before Resource is called otherwise it is a no-op. -func OverrideResource(res *resource.Resource) { - detectedResourceOnce.Do(func() { - detectedResource = res +func NewSpanExporter(_ context.Context) (sdktrace.SpanExporter, error) { + return detectExporter("OTEL_TRACES_EXPORTER", func(d ExporterDetector) (sdktrace.SpanExporter, bool, error) { + exp, err := d.DetectTraceExporter() + return exp, exp != nil, err }) } -type serviceNameDetector struct{} - -func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, error) { - return resource.StringDetector( - semconv.SchemaURL, - semconv.ServiceNameKey, - func() (string, error) { - if ServiceName != "" { - return ServiceName, nil - } - return filepath.Base(os.Args[0]), nil - }, - ).Detect(ctx) +func NewMetricExporter(_ context.Context) (sdkmetric.Exporter, error) { + return detectExporter("OTEL_METRICS_EXPORTER", func(d ExporterDetector) (sdkmetric.Exporter, bool, error) { + exp, err := d.DetectMetricExporter() + return exp, exp != nil, err + }) } type noneDetector struct{} func (n noneDetector) DetectTraceExporter() (sdktrace.SpanExporter, error) { - return nil, nil + return noneSpanExporter{}, nil } func (n noneDetector) DetectMetricExporter() (sdkmetric.Exporter, error) { - return nil, nil + return noneMetricExporter{}, nil +} + +type noneSpanExporter struct{} + +func (n noneSpanExporter) ExportSpans(_ context.Context, _ []sdktrace.ReadOnlySpan) error { + return nil +} + +func (n noneSpanExporter) Shutdown(_ context.Context) error { + return nil +} + +func IsNoneSpanExporter(exp sdktrace.SpanExporter) bool { + _, ok := exp.(noneSpanExporter) + return ok +} + +type noneMetricExporter struct{} + +func (n noneMetricExporter) Temporality(kind sdkmetric.InstrumentKind) metricdata.Temporality { + return sdkmetric.DefaultTemporalitySelector(kind) +} + +func (n noneMetricExporter) Aggregation(kind sdkmetric.InstrumentKind) sdkmetric.Aggregation { + return sdkmetric.DefaultAggregationSelector(kind) +} + +func (n noneMetricExporter) Export(_ context.Context, _ *metricdata.ResourceMetrics) error { + return nil +} + +func (n noneMetricExporter) ForceFlush(_ context.Context) error { + return nil +} + +func (n noneMetricExporter) Shutdown(_ context.Context) error { + return nil +} + +func IsNoneMetricExporter(exp sdkmetric.Exporter) bool { + _, ok := exp.(noneMetricExporter) + return ok } func init() { diff --git a/vendor/github.com/moby/buildkit/util/tracing/detect/resource.go b/vendor/github.com/moby/buildkit/util/tracing/detect/resource.go new file mode 100644 index 00000000..79abea95 --- /dev/null +++ b/vendor/github.com/moby/buildkit/util/tracing/detect/resource.go @@ -0,0 +1,58 @@ +package detect + +import ( + "context" + "os" + "path/filepath" + "sync" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" +) + +var ( + ServiceName string + + detectedResource *resource.Resource + detectedResourceOnce sync.Once +) + +func Resource() *resource.Resource { + detectedResourceOnce.Do(func() { + res, err := resource.New(context.Background(), + resource.WithDetectors(serviceNameDetector{}), + resource.WithFromEnv(), + resource.WithTelemetrySDK(), + ) + if err != nil { + otel.Handle(err) + } + detectedResource = res + }) + return detectedResource +} + +// OverrideResource overrides the resource returned from Resource. +// +// This must be invoked before Resource is called otherwise it is a no-op. +func OverrideResource(res *resource.Resource) { + detectedResourceOnce.Do(func() { + detectedResource = res + }) +} + +type serviceNameDetector struct{} + +func (serviceNameDetector) Detect(ctx context.Context) (*resource.Resource, error) { + return resource.StringDetector( + semconv.SchemaURL, + semconv.ServiceNameKey, + func() (string, error) { + if ServiceName != "" { + return ServiceName, nil + } + return filepath.Base(os.Args[0]), nil + }, + ).Detect(ctx) +} diff --git a/vendor/github.com/moby/buildkit/util/tracing/multi_span_exporter.go b/vendor/github.com/moby/buildkit/util/tracing/multi_span_exporter.go new file mode 100644 index 00000000..d856de3b --- /dev/null +++ b/vendor/github.com/moby/buildkit/util/tracing/multi_span_exporter.go @@ -0,0 +1,36 @@ +package tracing + +import ( + "context" + + "github.com/hashicorp/go-multierror" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +type MultiSpanExporter []sdktrace.SpanExporter + +func (m MultiSpanExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) (err error) { + for _, exp := range m { + if e := exp.ExportSpans(ctx, spans); e != nil { + if err != nil { + err = multierror.Append(err, e) + continue + } + err = e + } + } + return err +} + +func (m MultiSpanExporter) Shutdown(ctx context.Context) (err error) { + for _, exp := range m { + if e := exp.Shutdown(ctx); e != nil { + if err != nil { + err = multierror.Append(err, e) + continue + } + err = e + } + } + return err +} diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go index 892ba3de..ce8313e7 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go @@ -21,12 +21,20 @@ const ( // MediaTypeLayoutHeader specifies the media type for the oci-layout. MediaTypeLayoutHeader = "application/vnd.oci.layout.header.v1+json" - // MediaTypeImageManifest specifies the media type for an image manifest. - MediaTypeImageManifest = "application/vnd.oci.image.manifest.v1+json" - // MediaTypeImageIndex specifies the media type for an image index. MediaTypeImageIndex = "application/vnd.oci.image.index.v1+json" + // MediaTypeImageManifest specifies the media type for an image manifest. + MediaTypeImageManifest = "application/vnd.oci.image.manifest.v1+json" + + // MediaTypeImageConfig specifies the media type for the image configuration. + MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" + + // MediaTypeEmptyJSON specifies the media type for an unused blob containing the value "{}". + MediaTypeEmptyJSON = "application/vnd.oci.empty.v1+json" +) + +const ( // MediaTypeImageLayer is the media type used for layers referenced by the manifest. MediaTypeImageLayer = "application/vnd.oci.image.layer.v1.tar" @@ -37,7 +45,15 @@ const ( // MediaTypeImageLayerZstd is the media type used for zstd compressed // layers referenced by the manifest. MediaTypeImageLayerZstd = "application/vnd.oci.image.layer.v1.tar+zstd" +) +// Non-distributable layer media-types. +// +// Deprecated: Non-distributable layers are deprecated, and not recommended +// for future use. Implementations SHOULD NOT produce new non-distributable +// layers. +// https://github.com/opencontainers/image-spec/pull/965 +const ( // MediaTypeImageLayerNonDistributable is the media type for layers referenced by // the manifest but with distribution restrictions. // @@ -66,10 +82,4 @@ const ( // layers. // https://github.com/opencontainers/image-spec/pull/965 MediaTypeImageLayerNonDistributableZstd = "application/vnd.oci.image.layer.nondistributable.v1.tar+zstd" - - // MediaTypeImageConfig specifies the media type for the image configuration. - MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json" - - // MediaTypeEmptyJSON specifies the media type for an unused blob containing the value `{}` - MediaTypeEmptyJSON = "application/vnd.oci.empty.v1+json" ) diff --git a/vendor/github.com/opencontainers/image-spec/specs-go/version.go b/vendor/github.com/opencontainers/image-spec/specs-go/version.go index 11e09b58..7069ae44 100644 --- a/vendor/github.com/opencontainers/image-spec/specs-go/version.go +++ b/vendor/github.com/opencontainers/image-spec/specs-go/version.go @@ -25,7 +25,7 @@ const ( VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. - VersionDev = "-rc.5" + VersionDev = "" ) // Version is the specification version that the package types support. diff --git a/vendor/github.com/tonistiigi/fsutil/diff_containerd.go b/vendor/github.com/tonistiigi/fsutil/diff_containerd.go index 84fdc89d..86d64602 100644 --- a/vendor/github.com/tonistiigi/fsutil/diff_containerd.go +++ b/vendor/github.com/tonistiigi/fsutil/diff_containerd.go @@ -111,7 +111,7 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn, fil if filter != nil { filter(f2.path, &statCopy) } - f2copy = ¤tPath{path: filepath.FromSlash(f2.path), stat: &statCopy} + f2copy = ¤tPath{path: f2.path, stat: &statCopy} } k, p := pathChange(f1, f2copy) switch k { diff --git a/vendor/github.com/tonistiigi/fsutil/diskwriter.go b/vendor/github.com/tonistiigi/fsutil/diskwriter.go index 10b60851..a62c6b0c 100644 --- a/vendor/github.com/tonistiigi/fsutil/diskwriter.go +++ b/vendor/github.com/tonistiigi/fsutil/diskwriter.go @@ -37,6 +37,7 @@ type DiskWriter struct { ctx context.Context cancel func() eg *errgroup.Group + egCtx context.Context filter FilterFunc dirModTimes map[string]int64 } @@ -50,13 +51,14 @@ func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWr } ctx, cancel := context.WithCancel(ctx) - eg, ctx := errgroup.WithContext(ctx) + eg, egCtx := errgroup.WithContext(ctx) return &DiskWriter{ opt: opt, dest: dest, eg: eg, ctx: ctx, + egCtx: egCtx, cancel: cancel, filter: opt.Filter, dirModTimes: map[string]int64{}, @@ -98,7 +100,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er } }() - destPath := filepath.Join(dw.dest, filepath.FromSlash(p)) + destPath := filepath.Join(dw.dest, p) if kind == ChangeKindDelete { if dw.filter != nil { @@ -183,12 +185,12 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er } default: isRegularFile = true - file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, fi.Mode()) //todo: windows + file, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, fi.Mode()) if err != nil { return errors.Wrapf(err, "failed to create %s", newPath) } if dw.opt.SyncDataCb != nil { - if err := dw.processChange(ChangeKindAdd, p, fi, file); err != nil { + if err := dw.processChange(dw.ctx, ChangeKindAdd, p, fi, file); err != nil { file.Close() return err } @@ -219,7 +221,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er dw.requestAsyncFileData(p, destPath, fi, &statCopy) } } else { - return dw.processChange(kind, p, fi, nil) + return dw.processChange(dw.ctx, kind, p, fi, nil) } return nil @@ -228,7 +230,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo, st *types.Stat) { // todo: limit worker threads dw.eg.Go(func() error { - if err := dw.processChange(ChangeKindAdd, p, fi, &lazyFileWriter{ + if err := dw.processChange(dw.egCtx, ChangeKindAdd, p, fi, &lazyFileWriter{ dest: dest, }); err != nil { return err @@ -237,7 +239,7 @@ func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo, st *t }) } -func (dw *DiskWriter) processChange(kind ChangeKind, p string, fi os.FileInfo, w io.WriteCloser) error { +func (dw *DiskWriter) processChange(ctx context.Context, kind ChangeKind, p string, fi os.FileInfo, w io.WriteCloser) error { origw := w var hw *hashedWriter if dw.opt.NotifyCb != nil { @@ -252,7 +254,7 @@ func (dw *DiskWriter) processChange(kind ChangeKind, p string, fi os.FileInfo, w if fn == nil && dw.opt.AsyncDataCb != nil { fn = dw.opt.AsyncDataCb } - if err := fn(dw.ctx, p, w); err != nil { + if err := fn(ctx, p, w); err != nil { return err } } else { @@ -313,7 +315,7 @@ type lazyFileWriter struct { func (lfw *lazyFileWriter) Write(dt []byte) (int, error) { if lfw.f == nil { - file, err := os.OpenFile(lfw.dest, os.O_WRONLY, 0) //todo: windows + file, err := os.OpenFile(lfw.dest, os.O_WRONLY, 0) if os.IsPermission(err) { // retry after chmod fi, er := os.Stat(lfw.dest) diff --git a/vendor/github.com/tonistiigi/fsutil/hardlinks.go b/vendor/github.com/tonistiigi/fsutil/hardlinks.go index ef8bbfb5..d9bf2fc1 100644 --- a/vendor/github.com/tonistiigi/fsutil/hardlinks.go +++ b/vendor/github.com/tonistiigi/fsutil/hardlinks.go @@ -1,6 +1,9 @@ package fsutil import ( + "context" + "io" + gofs "io/fs" "os" "syscall" @@ -46,3 +49,68 @@ func (v *Hardlinks) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err return nil } + +// WithHardlinkReset returns a FS that fixes hardlinks for FS that has been filtered +// so that original hardlink sources might be missing +func WithHardlinkReset(fs FS) FS { + return &hardlinkFilter{fs: fs} +} + +type hardlinkFilter struct { + fs FS +} + +var _ FS = &hardlinkFilter{} + +func (r *hardlinkFilter) Walk(ctx context.Context, target string, fn gofs.WalkDirFunc) error { + seenFiles := make(map[string]string) + return r.fs.Walk(ctx, target, func(path string, entry gofs.DirEntry, err error) error { + if err != nil { + return err + } + + fi, err := entry.Info() + if err != nil { + return err + } + + if fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 { + return fn(path, entry, nil) + } + + stat, ok := fi.Sys().(*types.Stat) + if !ok { + return errors.WithStack(&os.PathError{Path: path, Err: syscall.EBADMSG, Op: "fileinfo without stat info"}) + } + + if stat.Linkname != "" { + if v, ok := seenFiles[stat.Linkname]; !ok { + seenFiles[stat.Linkname] = stat.Path + stat.Linkname = "" + entry = &dirEntryWithStat{DirEntry: entry, stat: stat} + } else { + if v != stat.Path { + stat.Linkname = v + entry = &dirEntryWithStat{DirEntry: entry, stat: stat} + } + } + } + + seenFiles[path] = stat.Path + + return fn(path, entry, nil) + }) +} + +func (r *hardlinkFilter) Open(p string) (io.ReadCloser, error) { + return r.fs.Open(p) +} + +type dirEntryWithStat struct { + gofs.DirEntry + stat *types.Stat +} + +func (d *dirEntryWithStat) Info() (gofs.FileInfo, error) { + return &StatInfo{d.stat}, nil +} diff --git a/vendor/github.com/tonistiigi/fsutil/receive.go b/vendor/github.com/tonistiigi/fsutil/receive.go index 209d1d2f..6a82d205 100644 --- a/vendor/github.com/tonistiigi/fsutil/receive.go +++ b/vendor/github.com/tonistiigi/fsutil/receive.go @@ -1,10 +1,42 @@ +// send.go and receive.go describe the fsutil file-transfer protocol, which +// allows transferring file trees across a network connection. +// +// The protocol operates as follows: +// - The client (the receiver) connects to the server (the sender). +// - The sender walks the target tree lexicographically and sends a series of +// STAT packets that describe each file (an empty stat indicates EOF). +// - The receiver sends a REQ packet for each file it requires the contents for, +// using the ID for the file (determined as its index in the STAT sequence). +// - The sender sends a DATA packet with byte arrays for the contents of the +// file, associated with an ID (an empty array indicates EOF). +// - Once the receiver has received all files it wants, it sends a FIN packet, +// and the file transfer is complete. +// If an error is encountered on either side, an ERR packet is sent containing +// a human-readable error. +// +// All paths transferred over the protocol are normalized to unix-style paths, +// regardless of which platforms are present on either side. These path +// conversions are performed right before sending a STAT packet (for the +// sender) or right after receiving the corresponding STAT packet (for the +// receiver); this abstraction doesn't leak into the rest of fsutil, which +// operates on native platform-specific paths. +// +// Note that in the case of cross-platform file transfers, the transfer is +// best-effort. Some filenames that are valid on a unix sender would not be +// valid on a windows receiver, so these paths are rejected as they are +// received. Additionally, file metadata, like user/group owners and xattrs do +// not have an exact correspondence on windows, and so would be discarded by +// a windows receiver. + package fsutil import ( "context" "io" "os" + "path/filepath" "sync" + "syscall" "github.com/pkg/errors" "github.com/tonistiigi/fsutil/types" @@ -184,13 +216,24 @@ func (r *receiver) run(ctx context.Context) error { } break } + + // normalize unix wire-specific paths to platform-specific paths + path := filepath.FromSlash(p.Stat.Path) + if filepath.ToSlash(path) != p.Stat.Path { + // e.g. a linux path foo/bar\baz cannot be represented on windows + return errors.WithStack(&os.PathError{Path: p.Stat.Path, Err: syscall.EINVAL, Op: "unrepresentable path"}) + } + p.Stat.Path = path + p.Stat.Linkname = filepath.FromSlash(p.Stat.Linkname) + if fileCanRequestData(os.FileMode(p.Stat.Mode)) { r.mu.Lock() r.files[p.Stat.Path] = i r.mu.Unlock() } i++ - cp := ¤tPath{path: p.Stat.Path, stat: p.Stat} + + cp := ¤tPath{path: path, stat: p.Stat} if err := r.orderValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil { return err } diff --git a/vendor/github.com/tonistiigi/fsutil/send.go b/vendor/github.com/tonistiigi/fsutil/send.go index ba97ef7a..e4a31563 100644 --- a/vendor/github.com/tonistiigi/fsutil/send.go +++ b/vendor/github.com/tonistiigi/fsutil/send.go @@ -29,7 +29,7 @@ type Stream interface { func Send(ctx context.Context, conn Stream, fs FS, progressCb func(int, bool)) error { s := &sender{ conn: &syncStream{Stream: conn}, - fs: fs, + fs: WithHardlinkReset(fs), files: make(map[uint32]string), progressCb: progressCb, sendpipeline: make(chan *sendHandle, 128), @@ -161,6 +161,7 @@ func (s *sender) walk(ctx context.Context) error { return errors.WithStack(&os.PathError{Path: path, Err: syscall.EBADMSG, Op: "fileinfo without stat info"}) } stat.Path = filepath.ToSlash(stat.Path) + stat.Linkname = filepath.ToSlash(stat.Linkname) p := &types.Packet{ Type: types.PACKET_STAT, Stat: stat, diff --git a/vendor/github.com/tonistiigi/vt100/vt100.go b/vendor/github.com/tonistiigi/vt100/vt100.go index ab6ab020..edc90c87 100644 --- a/vendor/github.com/tonistiigi/vt100/vt100.go +++ b/vendor/github.com/tonistiigi/vt100/vt100.go @@ -200,6 +200,7 @@ func (v *VT100) Resize(y, x int) { v.Height = y } else if y < v.Height { v.Content = v.Content[:y] + v.Format = v.Format[:y] v.Height = y } diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE b/vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE deleted file mode 100644 index 261eeb9e..00000000 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go deleted file mode 100644 index 885fd8b8..00000000 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/config.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" - -import ( - "strings" - - "github.com/prometheus/client_golang/prometheus" - - "go.opentelemetry.io/otel/sdk/metric" -) - -// config contains options for the exporter. -type config struct { - registerer prometheus.Registerer - disableTargetInfo bool - withoutUnits bool - withoutCounterSuffixes bool - readerOpts []metric.ManualReaderOption - disableScopeInfo bool - namespace string -} - -// newConfig creates a validated config configured with options. -func newConfig(opts ...Option) config { - cfg := config{} - for _, opt := range opts { - cfg = opt.apply(cfg) - } - - if cfg.registerer == nil { - cfg.registerer = prometheus.DefaultRegisterer - } - - return cfg -} - -// Option sets exporter option values. -type Option interface { - apply(config) config -} - -type optionFunc func(config) config - -func (fn optionFunc) apply(cfg config) config { - return fn(cfg) -} - -// WithRegisterer configures which prometheus Registerer the Exporter will -// register with. If no registerer is used the prometheus DefaultRegisterer is -// used. -func WithRegisterer(reg prometheus.Registerer) Option { - return optionFunc(func(cfg config) config { - cfg.registerer = reg - return cfg - }) -} - -// WithAggregationSelector configure the Aggregation Selector the exporter will -// use. If no AggregationSelector is provided the DefaultAggregationSelector is -// used. -func WithAggregationSelector(agg metric.AggregationSelector) Option { - return optionFunc(func(cfg config) config { - cfg.readerOpts = append(cfg.readerOpts, metric.WithAggregationSelector(agg)) - return cfg - }) -} - -// WithProducer configure the metric Producer the exporter will use as a source -// of external metric data. -func WithProducer(producer metric.Producer) Option { - return optionFunc(func(cfg config) config { - cfg.readerOpts = append(cfg.readerOpts, metric.WithProducer(producer)) - return cfg - }) -} - -// WithoutTargetInfo configures the Exporter to not export the resource target_info metric. -// If not specified, the Exporter will create a target_info metric containing -// the metrics' resource.Resource attributes. -func WithoutTargetInfo() Option { - return optionFunc(func(cfg config) config { - cfg.disableTargetInfo = true - return cfg - }) -} - -// WithoutUnits disables exporter's addition of unit suffixes to metric names, -// and will also prevent unit comments from being added in OpenMetrics once -// unit comments are supported. -// -// By default, metric names include a unit suffix to follow Prometheus naming -// conventions. For example, the counter metric request.duration, with unit -// milliseconds would become request_duration_milliseconds_total. -// With this option set, the name would instead be request_duration_total. -func WithoutUnits() Option { - return optionFunc(func(cfg config) config { - cfg.withoutUnits = true - return cfg - }) -} - -// WithoutUnits disables exporter's addition _total suffixes on counters. -// -// By default, metric names include a _total suffix to follow Prometheus naming -// conventions. For example, the counter metric happy.people would become -// happy_people_total. With this option set, the name would instead be -// happy_people. -func WithoutCounterSuffixes() Option { - return optionFunc(func(cfg config) config { - cfg.withoutCounterSuffixes = true - return cfg - }) -} - -// WithoutScopeInfo configures the Exporter to not export the otel_scope_info metric. -// If not specified, the Exporter will create a otel_scope_info metric containing -// the metrics' Instrumentation Scope, and also add labels about Instrumentation Scope to all metric points. -func WithoutScopeInfo() Option { - return optionFunc(func(cfg config) config { - cfg.disableScopeInfo = true - return cfg - }) -} - -// WithNamespace configures the Exporter to prefix metric with the given namespace. -// Metadata metrics such as target_info and otel_scope_info are not prefixed since these -// have special behavior based on their name. -func WithNamespace(ns string) Option { - return optionFunc(func(cfg config) config { - ns = sanitizeName(ns) - if !strings.HasSuffix(ns, "_") { - // namespace and metric names should be separated with an underscore, - // adds a trailing underscore if there is not one already. - ns = ns + "_" - } - - cfg.namespace = ns - return cfg - }) -} diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go deleted file mode 100644 index f212c614..00000000 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package prometheus provides a Prometheus Exporter that converts -// OTLP metrics into the Prometheus exposition format and implements -// prometheus.Collector to provide a handler for these metrics. -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" diff --git a/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go b/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go deleted file mode 100644 index 8973b202..00000000 --- a/vendor/go.opentelemetry.io/otel/exporters/prometheus/exporter.go +++ /dev/null @@ -1,533 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus" - -import ( - "context" - "errors" - "fmt" - "sort" - "strings" - "sync" - "unicode" - "unicode/utf8" - - "github.com/prometheus/client_golang/prometheus" - dto "github.com/prometheus/client_model/go" - "google.golang.org/protobuf/proto" - - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/internal/global" - "go.opentelemetry.io/otel/sdk/instrumentation" - "go.opentelemetry.io/otel/sdk/metric" - "go.opentelemetry.io/otel/sdk/metric/metricdata" - "go.opentelemetry.io/otel/sdk/resource" -) - -const ( - targetInfoMetricName = "target_info" - targetInfoDescription = "Target metadata" - - scopeInfoMetricName = "otel_scope_info" - scopeInfoDescription = "Instrumentation Scope metadata" -) - -var ( - scopeInfoKeys = [2]string{"otel_scope_name", "otel_scope_version"} - - errScopeInvalid = errors.New("invalid scope") -) - -// Exporter is a Prometheus Exporter that embeds the OTel metric.Reader -// interface for easy instantiation with a MeterProvider. -type Exporter struct { - metric.Reader -} - -// MarshalLog returns logging data about the Exporter. -func (e *Exporter) MarshalLog() interface{} { - const t = "Prometheus exporter" - - if r, ok := e.Reader.(*metric.ManualReader); ok { - under := r.MarshalLog() - if data, ok := under.(struct { - Type string - Registered bool - Shutdown bool - }); ok { - data.Type = t - return data - } - } - - return struct{ Type string }{Type: t} -} - -var _ metric.Reader = &Exporter{} - -// collector is used to implement prometheus.Collector. -type collector struct { - reader metric.Reader - - withoutUnits bool - withoutCounterSuffixes bool - disableScopeInfo bool - namespace string - - mu sync.Mutex // mu protects all members below from the concurrent access. - disableTargetInfo bool - targetInfo prometheus.Metric - scopeInfos map[instrumentation.Scope]prometheus.Metric - scopeInfosInvalid map[instrumentation.Scope]struct{} - metricFamilies map[string]*dto.MetricFamily -} - -// prometheus counters MUST have a _total suffix by default: -// https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/compatibility/prometheus_and_openmetrics.md -const counterSuffix = "_total" - -// New returns a Prometheus Exporter. -func New(opts ...Option) (*Exporter, error) { - cfg := newConfig(opts...) - - // this assumes that the default temporality selector will always return cumulative. - // we only support cumulative temporality, so building our own reader enforces this. - // TODO (#3244): Enable some way to configure the reader, but not change temporality. - reader := metric.NewManualReader(cfg.readerOpts...) - - collector := &collector{ - reader: reader, - disableTargetInfo: cfg.disableTargetInfo, - withoutUnits: cfg.withoutUnits, - withoutCounterSuffixes: cfg.withoutCounterSuffixes, - disableScopeInfo: cfg.disableScopeInfo, - scopeInfos: make(map[instrumentation.Scope]prometheus.Metric), - scopeInfosInvalid: make(map[instrumentation.Scope]struct{}), - metricFamilies: make(map[string]*dto.MetricFamily), - namespace: cfg.namespace, - } - - if err := cfg.registerer.Register(collector); err != nil { - return nil, fmt.Errorf("cannot register the collector: %w", err) - } - - e := &Exporter{ - Reader: reader, - } - - return e, nil -} - -// Describe implements prometheus.Collector. -func (c *collector) Describe(ch chan<- *prometheus.Desc) { - // The Opentelemetry SDK doesn't have information on which will exist when the collector - // is registered. By returning nothing we are an "unchecked" collector in Prometheus, - // and assume responsibility for consistency of the metrics produced. - // - // See https://pkg.go.dev/github.com/prometheus/client_golang@v1.13.0/prometheus#hdr-Custom_Collectors_and_constant_Metrics -} - -// Collect implements prometheus.Collector. -// -// This method is safe to call concurrently. -func (c *collector) Collect(ch chan<- prometheus.Metric) { - // TODO (#3047): Use a sync.Pool instead of allocating metrics every Collect. - metrics := metricdata.ResourceMetrics{} - err := c.reader.Collect(context.TODO(), &metrics) - if err != nil { - otel.Handle(err) - if err == metric.ErrReaderNotRegistered { - return - } - } - - global.Debug("Prometheus exporter export", "Data", metrics) - - // Initialize (once) targetInfo and disableTargetInfo. - func() { - c.mu.Lock() - defer c.mu.Unlock() - - if c.targetInfo == nil && !c.disableTargetInfo { - targetInfo, err := createInfoMetric(targetInfoMetricName, targetInfoDescription, metrics.Resource) - if err != nil { - // If the target info metric is invalid, disable sending it. - c.disableTargetInfo = true - otel.Handle(err) - return - } - - c.targetInfo = targetInfo - } - }() - - if !c.disableTargetInfo { - ch <- c.targetInfo - } - - for _, scopeMetrics := range metrics.ScopeMetrics { - var keys, values [2]string - - if !c.disableScopeInfo { - scopeInfo, err := c.scopeInfo(scopeMetrics.Scope) - if err == errScopeInvalid { - // Do not report the same error multiple times. - continue - } - if err != nil { - otel.Handle(err) - continue - } - - ch <- scopeInfo - - keys = scopeInfoKeys - values = [2]string{scopeMetrics.Scope.Name, scopeMetrics.Scope.Version} - } - - for _, m := range scopeMetrics.Metrics { - typ := c.metricType(m) - if typ == nil { - continue - } - name := c.getName(m, typ) - - drop, help := c.validateMetrics(name, m.Description, typ) - if drop { - continue - } - - if help != "" { - m.Description = help - } - - switch v := m.Data.(type) { - case metricdata.Histogram[int64]: - addHistogramMetric(ch, v, m, keys, values, name) - case metricdata.Histogram[float64]: - addHistogramMetric(ch, v, m, keys, values, name) - case metricdata.Sum[int64]: - addSumMetric(ch, v, m, keys, values, name) - case metricdata.Sum[float64]: - addSumMetric(ch, v, m, keys, values, name) - case metricdata.Gauge[int64]: - addGaugeMetric(ch, v, m, keys, values, name) - case metricdata.Gauge[float64]: - addGaugeMetric(ch, v, m, keys, values, name) - } - } - } -} - -func addHistogramMetric[N int64 | float64](ch chan<- prometheus.Metric, histogram metricdata.Histogram[N], m metricdata.Metrics, ks, vs [2]string, name string) { - // TODO(https://github.com/open-telemetry/opentelemetry-go/issues/3163): support exemplars - for _, dp := range histogram.DataPoints { - keys, values := getAttrs(dp.Attributes, ks, vs) - - desc := prometheus.NewDesc(name, m.Description, keys, nil) - buckets := make(map[float64]uint64, len(dp.Bounds)) - - cumulativeCount := uint64(0) - for i, bound := range dp.Bounds { - cumulativeCount += dp.BucketCounts[i] - buckets[bound] = cumulativeCount - } - m, err := prometheus.NewConstHistogram(desc, dp.Count, float64(dp.Sum), buckets, values...) - if err != nil { - otel.Handle(err) - continue - } - ch <- m - } -} - -func addSumMetric[N int64 | float64](ch chan<- prometheus.Metric, sum metricdata.Sum[N], m metricdata.Metrics, ks, vs [2]string, name string) { - valueType := prometheus.CounterValue - if !sum.IsMonotonic { - valueType = prometheus.GaugeValue - } - - for _, dp := range sum.DataPoints { - keys, values := getAttrs(dp.Attributes, ks, vs) - - desc := prometheus.NewDesc(name, m.Description, keys, nil) - m, err := prometheus.NewConstMetric(desc, valueType, float64(dp.Value), values...) - if err != nil { - otel.Handle(err) - continue - } - ch <- m - } -} - -func addGaugeMetric[N int64 | float64](ch chan<- prometheus.Metric, gauge metricdata.Gauge[N], m metricdata.Metrics, ks, vs [2]string, name string) { - for _, dp := range gauge.DataPoints { - keys, values := getAttrs(dp.Attributes, ks, vs) - - desc := prometheus.NewDesc(name, m.Description, keys, nil) - m, err := prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(dp.Value), values...) - if err != nil { - otel.Handle(err) - continue - } - ch <- m - } -} - -// getAttrs parses the attribute.Set to two lists of matching Prometheus-style -// keys and values. It sanitizes invalid characters and handles duplicate keys -// (due to sanitization) by sorting and concatenating the values following the spec. -func getAttrs(attrs attribute.Set, ks, vs [2]string) ([]string, []string) { - keysMap := make(map[string][]string) - itr := attrs.Iter() - for itr.Next() { - kv := itr.Attribute() - key := strings.Map(sanitizeRune, string(kv.Key)) - if _, ok := keysMap[key]; !ok { - keysMap[key] = []string{kv.Value.Emit()} - } else { - // if the sanitized key is a duplicate, append to the list of keys - keysMap[key] = append(keysMap[key], kv.Value.Emit()) - } - } - - keys := make([]string, 0, attrs.Len()) - values := make([]string, 0, attrs.Len()) - for key, vals := range keysMap { - keys = append(keys, key) - sort.Slice(vals, func(i, j int) bool { - return i < j - }) - values = append(values, strings.Join(vals, ";")) - } - - if ks[0] != "" { - keys = append(keys, ks[:]...) - values = append(values, vs[:]...) - } - return keys, values -} - -func createInfoMetric(name, description string, res *resource.Resource) (prometheus.Metric, error) { - keys, values := getAttrs(*res.Set(), [2]string{}, [2]string{}) - desc := prometheus.NewDesc(name, description, keys, nil) - return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), values...) -} - -func createScopeInfoMetric(scope instrumentation.Scope) (prometheus.Metric, error) { - keys := scopeInfoKeys[:] - desc := prometheus.NewDesc(scopeInfoMetricName, scopeInfoDescription, keys, nil) - return prometheus.NewConstMetric(desc, prometheus.GaugeValue, float64(1), scope.Name, scope.Version) -} - -func sanitizeRune(r rune) rune { - if unicode.IsLetter(r) || unicode.IsDigit(r) || r == ':' || r == '_' { - return r - } - return '_' -} - -var unitSuffixes = map[string]string{ - // Time - "d": "_days", - "h": "_hours", - "min": "_minutes", - "s": "_seconds", - "ms": "_milliseconds", - "us": "_microseconds", - "ns": "_nanoseconds", - - // Bytes - "By": "_bytes", - "KiBy": "_kibibytes", - "MiBy": "_mebibytes", - "GiBy": "_gibibytes", - "TiBy": "_tibibytes", - "KBy": "_kilobytes", - "MBy": "_megabytes", - "GBy": "_gigabytes", - "TBy": "_terabytes", - - // SI - "m": "_meters", - "V": "_volts", - "A": "_amperes", - "J": "_joules", - "W": "_watts", - "g": "_grams", - - // Misc - "Cel": "_celsius", - "Hz": "_hertz", - "1": "_ratio", - "%": "_percent", -} - -// getName returns the sanitized name, prefixed with the namespace and suffixed with unit. -func (c *collector) getName(m metricdata.Metrics, typ *dto.MetricType) string { - name := sanitizeName(m.Name) - addCounterSuffix := !c.withoutCounterSuffixes && *typ == dto.MetricType_COUNTER - if addCounterSuffix { - // Remove the _total suffix here, as we will re-add the total suffix - // later, and it needs to come after the unit suffix. - name = strings.TrimSuffix(name, counterSuffix) - } - if c.namespace != "" { - name = c.namespace + name - } - if suffix, ok := unitSuffixes[m.Unit]; ok && !c.withoutUnits && !strings.HasSuffix(name, suffix) { - name += suffix - } - if addCounterSuffix { - name += counterSuffix - } - return name -} - -func sanitizeName(n string) string { - // This algorithm is based on strings.Map from Go 1.19. - const replacement = '_' - - valid := func(i int, r rune) bool { - // Taken from - // https://github.com/prometheus/common/blob/dfbc25bd00225c70aca0d94c3c4bb7744f28ace0/model/metric.go#L92-L102 - if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || r == '_' || r == ':' || (r >= '0' && r <= '9' && i > 0) { - return true - } - return false - } - - // This output buffer b is initialized on demand, the first time a - // character needs to be replaced. - var b strings.Builder - for i, c := range n { - if valid(i, c) { - continue - } - - if i == 0 && c >= '0' && c <= '9' { - // Prefix leading number with replacement character. - b.Grow(len(n) + 1) - _ = b.WriteByte(byte(replacement)) - break - } - b.Grow(len(n)) - _, _ = b.WriteString(n[:i]) - _ = b.WriteByte(byte(replacement)) - width := utf8.RuneLen(c) - n = n[i+width:] - break - } - - // Fast path for unchanged input. - if b.Cap() == 0 { // b.Grow was not called above. - return n - } - - for _, c := range n { - // Due to inlining, it is more performant to invoke WriteByte rather then - // WriteRune. - if valid(1, c) { // We are guaranteed to not be at the start. - _ = b.WriteByte(byte(c)) - } else { - _ = b.WriteByte(byte(replacement)) - } - } - - return b.String() -} - -func (c *collector) metricType(m metricdata.Metrics) *dto.MetricType { - switch v := m.Data.(type) { - case metricdata.Histogram[int64], metricdata.Histogram[float64]: - return dto.MetricType_HISTOGRAM.Enum() - case metricdata.Sum[float64]: - if v.IsMonotonic { - return dto.MetricType_COUNTER.Enum() - } - return dto.MetricType_GAUGE.Enum() - case metricdata.Sum[int64]: - if v.IsMonotonic { - return dto.MetricType_COUNTER.Enum() - } - return dto.MetricType_GAUGE.Enum() - case metricdata.Gauge[int64], metricdata.Gauge[float64]: - return dto.MetricType_GAUGE.Enum() - } - return nil -} - -func (c *collector) scopeInfo(scope instrumentation.Scope) (prometheus.Metric, error) { - c.mu.Lock() - defer c.mu.Unlock() - - scopeInfo, ok := c.scopeInfos[scope] - if ok { - return scopeInfo, nil - } - - if _, ok := c.scopeInfosInvalid[scope]; ok { - return nil, errScopeInvalid - } - - scopeInfo, err := createScopeInfoMetric(scope) - if err != nil { - c.scopeInfosInvalid[scope] = struct{}{} - return nil, fmt.Errorf("cannot create scope info metric: %w", err) - } - - c.scopeInfos[scope] = scopeInfo - - return scopeInfo, nil -} - -func (c *collector) validateMetrics(name, description string, metricType *dto.MetricType) (drop bool, help string) { - c.mu.Lock() - defer c.mu.Unlock() - - emf, exist := c.metricFamilies[name] - - if !exist { - c.metricFamilies[name] = &dto.MetricFamily{ - Name: proto.String(name), - Help: proto.String(description), - Type: metricType, - } - return false, "" - } - - if emf.GetType() != *metricType { - global.Error( - errors.New("instrument type conflict"), - "Using existing type definition.", - "instrument", name, - "existing", emf.GetType(), - "dropped", *metricType, - ) - return true, "" - } - if emf.GetHelp() != description { - global.Info( - "Instrument description conflict, using existing", - "instrument", name, - "existing", emf.GetHelp(), - "dropped", description, - ) - return false, emf.GetHelp() - } - - return false, "" -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7b21d993..c55787c9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,15 +8,15 @@ github.com/Azure/go-ansiterm/winterm # github.com/Masterminds/semver/v3 v3.2.1 ## explicit; go 1.18 github.com/Masterminds/semver/v3 -# github.com/Microsoft/go-winio v0.6.1 -## explicit; go 1.17 +# github.com/Microsoft/go-winio v0.6.2 +## explicit; go 1.21 github.com/Microsoft/go-winio github.com/Microsoft/go-winio/internal/fs github.com/Microsoft/go-winio/internal/socket github.com/Microsoft/go-winio/internal/stringbuffer github.com/Microsoft/go-winio/pkg/guid -# github.com/Microsoft/hcsshim v0.11.4 -## explicit; go 1.18 +# github.com/Microsoft/hcsshim v0.11.5 +## explicit; go 1.21 github.com/Microsoft/hcsshim/osversion # github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d ## explicit @@ -153,7 +153,7 @@ github.com/compose-spec/compose-go/v2/validation # github.com/containerd/console v1.0.4 ## explicit; go 1.13 github.com/containerd/console -# github.com/containerd/containerd v1.7.15 +# github.com/containerd/containerd v1.7.17 ## explicit; go 1.21 github.com/containerd/containerd/api/services/content/v1 github.com/containerd/containerd/archive/compression @@ -200,7 +200,7 @@ github.com/containerd/continuity/sysx # github.com/containerd/log v0.1.0 ## explicit; go 1.20 github.com/containerd/log -# github.com/containerd/ttrpc v1.2.3 +# github.com/containerd/ttrpc v1.2.4 ## explicit; go 1.19 github.com/containerd/ttrpc # github.com/containerd/typeurl/v2 v2.1.1 @@ -269,7 +269,7 @@ github.com/docker/distribution/registry/client/transport github.com/docker/distribution/registry/storage/cache github.com/docker/distribution/registry/storage/cache/memory github.com/docker/distribution/uuid -# github.com/docker/docker v26.0.0+incompatible +# github.com/docker/docker v26.1.3+incompatible ## explicit github.com/docker/docker/api github.com/docker/docker/api/types @@ -433,6 +433,9 @@ github.com/gorilla/websocket github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule github.com/grpc-ecosystem/grpc-gateway/v2/runtime github.com/grpc-ecosystem/grpc-gateway/v2/utilities +# github.com/hashicorp/errwrap v1.1.0 +## explicit +github.com/hashicorp/errwrap # github.com/hashicorp/go-cleanhttp v0.5.2 ## explicit; go 1.13 github.com/hashicorp/go-cleanhttp @@ -442,6 +445,9 @@ github.com/hashicorp/go-cty-funcs/cidr github.com/hashicorp/go-cty-funcs/crypto github.com/hashicorp/go-cty-funcs/encoding github.com/hashicorp/go-cty-funcs/uuid +# github.com/hashicorp/go-multierror v1.1.1 +## explicit; go 1.13 +github.com/hashicorp/go-multierror # github.com/hashicorp/hcl/v2 v2.20.1 ## explicit; go 1.18 github.com/hashicorp/hcl/v2 @@ -509,7 +515,7 @@ github.com/mitchellh/mapstructure # github.com/mitchellh/reflectwalk v1.0.2 ## explicit github.com/mitchellh/reflectwalk -# github.com/moby/buildkit v0.13.0-rc3.0.20240417151852-71f99c52a669 +# github.com/moby/buildkit v0.14.0-rc1 ## explicit; go 1.21 github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/types @@ -584,8 +590,8 @@ github.com/moby/buildkit/util/testutil/dockerd github.com/moby/buildkit/util/testutil/integration github.com/moby/buildkit/util/testutil/workers github.com/moby/buildkit/util/tracing +github.com/moby/buildkit/util/tracing/delegated github.com/moby/buildkit/util/tracing/detect -github.com/moby/buildkit/util/tracing/detect/delegated github.com/moby/buildkit/util/tracing/env github.com/moby/buildkit/util/tracing/otlptracegrpc github.com/moby/buildkit/version @@ -637,7 +643,7 @@ github.com/mxk/go-flowrate/flowrate # github.com/opencontainers/go-digest v1.0.0 ## explicit; go 1.13 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.1.0-rc5 +# github.com/opencontainers/image-spec v1.1.0 ## explicit; go 1.18 github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go/v1 @@ -710,14 +716,14 @@ github.com/theupdateframework/notary/tuf/data github.com/theupdateframework/notary/tuf/signed github.com/theupdateframework/notary/tuf/utils github.com/theupdateframework/notary/tuf/validation -# github.com/tonistiigi/fsutil v0.0.0-20240301111122-7525a1af2bb5 +# github.com/tonistiigi/fsutil v0.0.0-20240424095704-91a3fc46842c ## explicit; go 1.20 github.com/tonistiigi/fsutil github.com/tonistiigi/fsutil/types # github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea ## explicit github.com/tonistiigi/units -# github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 +# github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab ## explicit; go 1.12 github.com/tonistiigi/vt100 # github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb @@ -801,9 +807,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/envconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal/retry -# go.opentelemetry.io/otel/exporters/prometheus v0.42.0 -## explicit; go 1.20 -go.opentelemetry.io/otel/exporters/prometheus # go.opentelemetry.io/otel/metric v1.21.0 ## explicit; go 1.20 go.opentelemetry.io/otel/metric From 9a30215886dbd8f5c2c089f1815f8aa3e29384e2 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Fri, 31 May 2024 17:38:32 -0700 Subject: [PATCH 2/2] tests: avoid early shutdown of sandbox Because sandbox is closed down when the main test that created the sandbox returns it can't have subtests that set themselves as parallel as they would continue to run in a different lifecycle. Signed-off-by: Tonis Tiigi --- tests/dialstdio.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/dialstdio.go b/tests/dialstdio.go index 4a034a5f..a18e6178 100644 --- a/tests/dialstdio.go +++ b/tests/dialstdio.go @@ -113,13 +113,10 @@ func testDialStdio(t *testing.T, sb integration.Sandbox) { require.Equal(t, "world", string(dt)) } - t.Run("conn=netpipe", func(t *testing.T) { - t.Parallel() - do(t, func(t *testing.T, cmd *exec.Cmd) net.Conn { - c1, c2 := net.Pipe() - cmd.Stdin = c1 - cmd.Stdout = c1 - return c2 - }) + do(t, func(t *testing.T, cmd *exec.Cmd) net.Conn { + c1, c2 := net.Pipe() + cmd.Stdin = c1 + cmd.Stdout = c1 + return c2 }) }