Compare commits

..

25 Commits

Author SHA1 Message Date
Tõnis Tiigi
e273a53c88 Merge pull request #2194 from LaurentGoderre/sbom-dsse
Add support for DSSE envelope for attestation in imagetools
2024-02-28 20:08:07 -08:00
Tonis Tiigi
dcdcce6c52 imagetools: supress warnings for dsse mediatypes
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-02-28 19:25:42 -08:00
Tõnis Tiigi
c5b4ce9e7b Merge pull request #2292 from crazy-max/go-minor
pin to go 1.21
2024-02-28 14:26:28 -08:00
Tõnis Tiigi
8f484f6ac1 Merge pull request #2290 from tonistiigi/multi-export
build: allow multiple exports if supported by buildkit
2024-02-28 14:20:21 -08:00
Laurent Goderre
b748185f48 Add support for DSSE envelope for attestation and provenance in imagetools
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-02-28 16:45:51 -05:00
CrazyMax
a6228ed78f Merge pull request #2293 from docker/dependabot/github_actions/peter-evans/create-pull-request-6.0.1
build(deps): bump peter-evans/create-pull-request from 6.0.0 to 6.0.1
2024-02-28 22:31:55 +01:00
Tonis Tiigi
fcbe2803c8 build: allow multiple exports if supported by buildkit
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-02-28 13:16:15 -08:00
Tõnis Tiigi
83c30c6c5a Merge pull request #2291 from crazy-max/update-buildkit
vendor: github.com/moby/buildkit v0.13.0-rc3
2024-02-28 13:13:06 -08:00
Tõnis Tiigi
8db86e4031 Merge pull request #2287 from iankingori/fix-dialer
remote: use winio DialPipeContext for named pipes
2024-02-28 13:12:29 -08:00
Tõnis Tiigi
e705cafcd5 Merge pull request #2289 from tonistiigi/prompt-cancel
commands: handle ctrl-c on active prompt
2024-02-28 13:11:48 -08:00
dependabot[bot]
32f17b0de1 build(deps): bump peter-evans/create-pull-request from 6.0.0 to 6.0.1
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](b1ddad2c99...a4f52f8033)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-28 18:23:29 +00:00
Ian King'ori
d40c4bb046 remote: use winio DialPipeContext for named pipes
Signed-off-by: Ian King'ori <kingorim.ian@gmail.com>
2024-02-28 16:19:58 +03:00
CrazyMax
25f8011825 pin to go 1.21
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-28 13:18:42 +01:00
CrazyMax
d0f9655aa2 vendor: github.com/moby/buildkit v0.13.0-rc3
full diff: https://github.com/moby/buildkit/compare/v0.13.0-rc2...v0.13.0-rc3

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-28 09:46:36 +01:00
Tonis Tiigi
ce9a486a0e commands: handle ctrl-c on active prompt
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2024-02-27 17:35:27 -08:00
CrazyMax
85abcc413e Merge pull request #2283 from crazy-max/update-compose
vendor: update compose-go to v2.0.0-rc.8
2024-02-27 08:55:04 +01:00
Tõnis Tiigi
e5acb010c9 Merge pull request #2284 from crazy-max/update-uuid
vendor: update github.com/google/uuid to v1.6.0
2024-02-26 08:39:01 -08:00
Akihiro Suda
79f50ad924 Merge pull request #2285 from crazy-max/update-hashring
vendor: github.com/serialx/hashring 22c0c7ab6b1b (master)
2024-02-26 21:00:42 +09:00
Tõnis Tiigi
5723ceefb6 Merge pull request #2281 from crazy-max/update-buildkit
vendor: github.com/moby/buildkit v0.13.0-rc2
2024-02-25 22:19:45 -08:00
CrazyMax
95185e9525 vendor: update compose-go to v2.0.0-rc.8
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-24 17:15:27 +01:00
CrazyMax
e423a67f7b vendor: github.com/moby/buildkit v0.13.0-rc2
full diff: https://github.com/moby/buildkit/compare/8e3fe35738c2...v0.13.0-rc2

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-24 17:14:01 +01:00
CrazyMax
545a5c97c6 Merge pull request #2282 from crazy-max/update-k8s
vendor: bump k8s dependencies to v0.29.2
2024-02-24 17:12:39 +01:00
CrazyMax
625d90b983 vendor: github.com/serialx/hashring 22c0c7ab6b1b (master)
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-24 16:56:59 +01:00
CrazyMax
9999fc63e8 vendor: update github.com/google/uuid to v1.6.0
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-24 16:52:21 +01:00
CrazyMax
303e509bbf vendor: bump k8s dependencies to v0.29.2
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
2024-02-24 16:41:41 +01:00
903 changed files with 69112 additions and 30552 deletions

View File

@@ -26,7 +26,7 @@ env:
TEST_CACHE_SCOPE: "test"
TESTFLAGS: "-v --parallel=6 --timeout=30m"
GOTESTSUM_FORMAT: "standard-verbose"
GO_VERSION: "1.21.6"
GO_VERSION: "1.21"
GOTESTSUM_VERSION: "v1.9.0" # same as one in Dockerfile
jobs:

View File

@@ -13,7 +13,7 @@ permissions:
security-events: write
env:
GO_VERSION: 1.21.6
GO_VERSION: "1.21"
jobs:
codeql:

View File

@@ -44,7 +44,7 @@ jobs:
git add -A .
-
name: Create PR on docs repo
uses: peter-evans/create-pull-request@b1ddad2c994a25fbc81a28b3ec0e368bb2021c50
uses: peter-evans/create-pull-request@a4f52f8033a6168103c2538976c07b467e8163bc
with:
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
push-to-fork: docker-tools-robot/docker.github.io

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.6
ARG GO_VERSION=1.21
ARG XX_VERSION=1.4.0
ARG DOCKER_VERSION=25.0.2

View File

@@ -290,7 +290,9 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
opt.Exports = []client.ExportEntry{{Type: "image", Attrs: map[string]string{}}}
}
default:
return nil, nil, errors.Errorf("multiple outputs currently unsupported")
if err := bopts.LLBCaps.Supports(pb.CapMultipleExporters); err != nil {
return nil, nil, errors.Errorf("multiple outputs currently unsupported by the current BuildKit daemon, please upgrade to version v0.13+ or use a single output")
}
}
// fill in image exporter names from tags

View File

@@ -49,8 +49,12 @@ func runPrune(ctx context.Context, dockerCli command.Cli, opts pruneOptions) err
warning = allCacheWarning
}
if !opts.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) {
return nil
if !opts.force {
if ok, err := prompt(ctx, dockerCli.In(), dockerCli.Out(), warning); err != nil {
return err
} else if !ok {
return nil
}
}
b, err := builder.New(dockerCli, builder.WithName(opts.builder))

View File

@@ -28,8 +28,12 @@ const (
)
func runRm(ctx context.Context, dockerCli command.Cli, in rmOptions) error {
if in.allInactive && !in.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), rmInactiveWarning) {
return nil
if in.allInactive && !in.force {
if ok, err := prompt(ctx, dockerCli.In(), dockerCli.Out(), rmInactiveWarning); err != nil {
return err
} else if !ok {
return nil
}
}
txn, release, err := storeutil.GetStore(dockerCli)

23
commands/util.go Normal file
View File

@@ -0,0 +1,23 @@
package commands
import (
"context"
"io"
"github.com/docker/cli/cli/command"
)
func prompt(ctx context.Context, ins io.Reader, out io.Writer, msg string) (bool, error) {
done := make(chan struct{})
var ok bool
go func() {
ok = command.PromptForConfirmation(ins, out, msg)
close(done)
}()
select {
case <-ctx.Done():
return false, context.Cause(ctx)
case <-done:
return ok, nil
}
}

View File

@@ -15,6 +15,7 @@ func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) {
if len(entries) == 0 {
return nil, nil
}
var stdoutUsed bool
for _, entry := range entries {
if entry.Type == "" {
return nil, errors.Errorf("type is required for output")
@@ -68,10 +69,14 @@ func CreateExports(entries []*ExportEntry) ([]client.ExportEntry, error) {
entry.Destination = "-"
}
if entry.Destination == "-" {
if stdoutUsed {
return nil, errors.Errorf("multiple outputs configured to write to stdout")
}
if _, err := console.ConsoleFromFile(os.Stdout); err == nil {
return nil, errors.Errorf("dest file is required for %s exporter. refusing to write to console", out.Type)
}
out.Output = wrapWriteCloser(os.Stdout)
stdoutUsed = true
} else if entry.Destination != "" {
fi, err := os.Stat(entry.Destination)
if err != nil && !os.IsNotExist(err) {

View File

@@ -424,6 +424,10 @@ $ docker buildx build -o type=docker,dest=- . > myimage.tar
$ docker buildx build -t tonistiigi/foo -o type=registry
```
> **Note **
>
> Since BuildKit v0.13.0 multiple outputs can be specified by repeating the flag.
Supported exported types are:
#### `local`

View File

@@ -10,6 +10,7 @@ import (
"time"
"github.com/docker/buildx/driver"
util "github.com/docker/buildx/driver/remote/util"
"github.com/docker/buildx/util/progress"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/tracing/detect"
@@ -99,9 +100,8 @@ func (d *Driver) Dial(ctx context.Context) (net.Conn, error) {
return nil, errors.Errorf("invalid endpoint address: %s", d.InitConfig.EndpointAddr)
}
dialer := &net.Dialer{}
conn, err := util.DialContext(ctx, network, addr)
conn, err := dialer.DialContext(ctx, network, addr)
if err != nil {
return nil, errors.WithStack(err)
}

View File

@@ -0,0 +1,17 @@
//go:build !windows
// +build !windows
package remote
import (
"context"
"net"
)
func DialContext(ctx context.Context, network string, addr string) (net.Conn, error) {
dialer := &net.Dialer{}
conn, err := dialer.DialContext(ctx, network, addr)
return conn, err
}

View File

@@ -0,0 +1,23 @@
package remote
import (
"context"
"net"
"github.com/Microsoft/go-winio"
)
func DialContext(ctx context.Context, network string, addr string) (net.Conn, error) {
var conn net.Conn
var err error
// dial context doesn't support named pipes
if network == "npipe" {
conn, err = winio.DialPipeContext(ctx, addr)
} else {
dialer := &net.Dialer{}
conn, err = dialer.DialContext(ctx, network, addr)
}
return conn, err
}

80
go.mod
View File

@@ -4,8 +4,9 @@ go 1.21
require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/Microsoft/go-winio v0.6.1
github.com/aws/aws-sdk-go-v2/config v1.26.6
github.com/compose-spec/compose-go/v2 v2.0.0-rc.3
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8
github.com/containerd/console v1.0.4
github.com/containerd/containerd v1.7.13
github.com/containerd/continuity v0.4.3
@@ -21,10 +22,10 @@ require (
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.3
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.5.0
github.com/google/uuid v1.6.0
github.com/hashicorp/go-cty-funcs v0.0.0-20230405223818-a090f58aa992
github.com/hashicorp/hcl/v2 v2.19.1
github.com/moby/buildkit v0.13.0-rc1.0.20240222164755-8e3fe35738c2 // master (v0.13.0-dev)
github.com/moby/buildkit v0.13.0-rc3
github.com/moby/sys/mountinfo v0.7.1
github.com/moby/sys/signal v0.7.0
github.com/morikuni/aec v1.0.0
@@ -32,35 +33,34 @@ require (
github.com/opencontainers/image-spec v1.1.0-rc5
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/zclconf/go-cty v1.14.1
go.opentelemetry.io/otel v1.19.0
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0
go.opentelemetry.io/otel/metric v1.19.0
go.opentelemetry.io/otel/sdk v1.19.0
go.opentelemetry.io/otel/sdk/metric v1.19.0
go.opentelemetry.io/otel/trace v1.19.0
golang.org/x/mod v0.13.0
golang.org/x/sync v0.4.0
go.opentelemetry.io/otel/metric v1.21.0
go.opentelemetry.io/otel/sdk v1.21.0
go.opentelemetry.io/otel/sdk/metric 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
golang.org/x/sys v0.16.0
golang.org/x/term v0.15.0
golang.org/x/term v0.16.0
google.golang.org/grpc v1.59.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.26.7
k8s.io/apimachinery v0.26.7
k8s.io/apiserver v0.26.7
k8s.io/client-go v0.26.7
k8s.io/api v0.29.2
k8s.io/apimachinery v0.29.2
k8s.io/apiserver v0.29.2
k8s.io/client-go v0.29.2
)
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/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d // indirect
github.com/agext/levenshtein v1.2.3 // indirect
@@ -88,19 +88,20 @@ require (
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
github.com/go-openapi/swag v0.19.14 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -110,7 +111,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
@@ -129,6 +130,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
@@ -138,28 +140,28 @@ require (
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
github.com/shibumi/go-pathspec v1.3.0 // indirect
github.com/theupdateframework/notary v0.7.0 // indirect
github.com/tonistiigi/fsutil v0.0.0-20230825212630-f09800878302 // indirect
github.com/tonistiigi/fsutil v0.0.0-20240223190444-7a889f53dbf6 // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // 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
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect
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/proto/otlp v1.0.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.11.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
@@ -167,10 +169,10 @@ require (
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

214
go.sum
View File

@@ -88,8 +88,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.3 h1:t0qajSNkH3zR4HEN2CM+GVU7GBx5AwqiYJk5w800M7w=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.3/go.mod h1:r7CJHU0GaLtRVLm2ch8RCNkJh3GHyaqqc2rSti7VP44=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8 h1:b7l+GqFF+2W4M4kLQUDRTGhqmTiRwT3bYd9X7xrxp5Q=
github.com/compose-spec/compose-go/v2 v2.0.0-rc.8/go.mod h1:bEPizBkIojlQ20pi2vNluBa58tevvj0Y18oUSHPyfdc=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
@@ -146,12 +146,9 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -168,23 +165,22 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-sql-driver/mysql v1.3.0 h1:pgwjLi/dvffoP9aabwkT3AKpXQM93QARkjFhDDqC1UE=
github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
@@ -208,40 +204,37 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI=
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
@@ -283,7 +276,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -295,10 +288,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+
github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.5.3 h1:C8fxWnhYyME3n0klPOhVM7PtYUB3eV1W3DeFmN3j53Y=
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
@@ -320,8 +311,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-rc1.0.20240222164755-8e3fe35738c2 h1:e3FYb+yyx1SM1w4Mjn8L9WP5h/6u23P/xCAPZXx4m2Y=
github.com/moby/buildkit v0.13.0-rc1.0.20240222164755-8e3fe35738c2/go.mod h1:XaLDo1L55QqXS/04FE91+mAbwjkr0vZu9g6zZlzvXL8=
github.com/moby/buildkit v0.13.0-rc3 h1:Dns5Ixnv4OH1MyLZy7S4G2m+MLwp2YEqrPPzEzfw7Tw=
github.com/moby/buildkit v0.13.0-rc3/go.mod h1:5pRtk7Wuv929XRIp9tqPdq07mrnBpXAUoOYYfOj0nhA=
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=
@@ -352,16 +343,18 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=
github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
@@ -415,8 +408,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/
github.com/secure-systems-lab/go-securesystemslib v0.4.0/go.mod h1:FGBZgq2tXWICsxWQW1msNf49F0Pf2Op5Htayx335Qbs=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 h1:ka9QPuQg2u4LGipiZGsgkg3rJCo4iIUCy75FddM0GRQ=
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU=
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
@@ -426,8 +419,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spdx/tools-golang v0.5.1 h1:fJg3SVOGG+eIva9ZUBm/hvyA7PIPVFjRxUKe6fdAgwE=
github.com/spdx/tools-golang v0.5.1/go.mod h1:/DRDQuBfB37HctM29YtrX1v+bXiVmT2OpQDalRmX9aU=
github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQraY=
github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI=
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk=
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -440,22 +433,25 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c h1:2EejZtjFjKJGk71ANb+wtFK5EjUzUkEM3R0xnp559xg=
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
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-20230825212630-f09800878302 h1:ZT8ibgassurSISJ1Pj26NsM3vY2jxFZn63Nd/TpHmRw=
github.com/tonistiigi/fsutil v0.0.0-20230825212630-f09800878302/go.mod h1:9kMVqMyQ/Sx2df5LtnGG+nbrmiZzCS7V6gjW3oGHsvI=
github.com/tonistiigi/fsutil v0.0.0-20240223190444-7a889f53dbf6 h1:v9u6pmdUkarXL/1S/6LGcG9wsiBLd9N/WyJq/Y9WPcg=
github.com/tonistiigi/fsutil v0.0.0-20240223190444-7a889f53dbf6/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=
@@ -477,41 +473,41 @@ github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA
github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 h1:RsQi0qJ2imFfCvZabqzM9cNXBG8k6gXMv1A0cXRmH6A=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 h1:2ea0IkZBsWH+HA2GkD+7+hRw2u97jzdFyRtXuO14a1s=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0/go.mod h1:4m3RnBBb+7dB9d21y510oO1pdB1V4J6smNf14WXcBFQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 h1:gbhw/u49SS3gkPWiYweQNJGm/uJN5GkI/FrosxSHT7A=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1/go.mod h1:GnOaBaFQ2we3b9AGWJpsBa7v1S5RlQzlC3O7dRMxZhM=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 h1:ZtfnDL+tUrs1F0Pzfwbg2d59Gru9NCH3bgSHBM6LDwU=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0/go.mod h1:hG4Fj/y8TR/tlEDREo8tWstl9fO9gcFkn4xrx0Io8xU=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 h1:NmnYCiR0qNufkldjVvyQfZTHSdzeHoZ41zggMsdMcLM=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0/go.mod h1:UVAO61+umUsHLtYb8KXXRoHtxUkdOPkYidzW3gipRLQ=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 h1:wNMDy/LVGLj2h3p6zg4d0gypKfWKSWI14E1C4smOgl8=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0/go.mod h1:YfbDdXAAkemWJK3H/DshvlrxqFB2rtW4rY6ky/3x/H0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
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.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8Ni+hx+8i1k=
go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
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=
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0=
go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q=
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -522,18 +518,18 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -546,8 +542,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
@@ -558,8 +554,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -580,8 +576,8 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -597,8 +593,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -611,8 +607,6 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA=
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI=
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k=
@@ -628,14 +622,6 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
@@ -647,7 +633,6 @@ gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9a
gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -665,30 +650,29 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.26.7 h1:Lf4iEBEJb5OFNmawtBfSZV/UNi9riSJ0t1qdhyZqI40=
k8s.io/api v0.26.7/go.mod h1:Vk9bMadzA49UHPmHB//lX7VRCQSXGoVwfLd3Sc1SSXI=
k8s.io/apimachinery v0.26.7 h1:590jSBwaSHCAFCqltaEogY/zybFlhGsnLteLpuF2wig=
k8s.io/apimachinery v0.26.7/go.mod h1:qYzLkrQ9lhrZRh0jNKo2cfvf/R1/kQONnSiyB7NUJU0=
k8s.io/apiserver v0.26.7 h1:NX/zBZZn4R+Cq6shwyn8Pn8REd0yJJ16dbtv9WkEVEU=
k8s.io/apiserver v0.26.7/go.mod h1:r0wDRWHI7VL/KlQLTkJJBVGZ3KeNfv+VetlyRtr86xs=
k8s.io/client-go v0.26.7 h1:hyU9aKHlwVOykgyxzGYkrDSLCc4+mimZVyUJjPyUn1E=
k8s.io/client-go v0.26.7/go.mod h1:okYjy0jtq6sdeztALDvCh24tg4opOQS1XNvsJlERDAo=
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk=
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A=
k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0=
k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8=
k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU=
k8s.io/apiserver v0.29.2 h1:+Z9S0dSNr+CjnVXQePG8TcBWHr3Q7BmAr7NraHvsMiQ=
k8s.io/apiserver v0.29.2/go.mod h1:B0LieKVoyU7ykQvPFm7XSdIHaCHSzCzQWPFa5bqbeMQ=
k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg=
k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA=
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.6
ARG GO_VERSION=1.21
ARG FORMATS=md,yaml
FROM golang:${GO_VERSION}-alpine AS docsgen

View File

@@ -5,7 +5,7 @@
# Copyright The Buildx Authors.
# Licensed under the Apache License, Version 2.0
ARG GO_VERSION="1.21.6"
ARG GO_VERSION="1.21"
ARG PROTOC_VERSION="3.11.4"
# protoc is dynamically linked to glibc so can't use alpine base

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.6
ARG GO_VERSION=1.21
ARG XX_VERSION=1.3.0
ARG GOLANGCI_LINT_VERSION=1.54.2

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1
ARG GO_VERSION=1.21.6
ARG GO_VERSION=1.21
ARG MODOUTDATED_VERSION=v0.8.0
FROM golang:${GO_VERSION}-alpine AS base

View File

@@ -4,7 +4,9 @@ package imagetools
import (
"context"
"encoding/base64"
"encoding/json"
"regexp"
"sort"
"strings"
"sync"
@@ -21,6 +23,12 @@ import (
"golang.org/x/sync/errgroup"
)
const (
inTotoGenericMime = "application/vnd.in-toto+json"
inTotoSPDXDSSEMime = "application/vnd.in-toto.spdx+dsse"
inTotoProvenanceDSSEMime = "application/vnd.in-toto.provenance+dsse"
)
var (
annotationReferences = []string{
"com.docker.reference.digest",
@@ -274,7 +282,7 @@ type sbomStub struct {
}
func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
ctx = withIntotoMediaTypes(ctx)
as.deferredSbom = func() (*sbomStub, error) {
var sbom *sbomStub
for _, dgst := range refs {
@@ -283,7 +291,8 @@ func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *resul
return nil, errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && layer.Annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document" {
if (layer.MediaType == inTotoGenericMime || isInTotoDSSE(layer.MediaType)) &&
layer.Annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document" {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return nil, err
@@ -292,6 +301,12 @@ func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *resul
if err != nil {
return nil, err
}
dt, err = decodeDSSE(dt, layer.MediaType)
if err != nil {
return nil, err
}
var spdx struct {
Predicate interface{} `json:"predicate"`
}
@@ -318,7 +333,7 @@ type provenanceStub struct {
}
func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
ctx = withIntotoMediaTypes(ctx)
as.deferredProvenance = func() (*provenanceStub, error) {
var provenance *provenanceStub
for _, dgst := range refs {
@@ -327,7 +342,8 @@ func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r
return nil, errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && strings.HasPrefix(layer.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
if (layer.MediaType == inTotoGenericMime || isInTotoDSSE(layer.MediaType)) &&
strings.HasPrefix(layer.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return nil, err
@@ -336,6 +352,12 @@ func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r
if err != nil {
return nil, err
}
dt, err = decodeDSSE(dt, layer.MediaType)
if err != nil {
return nil, err
}
var slsa struct {
Predicate interface{} `json:"predicate"`
}
@@ -415,3 +437,36 @@ func (r *result) SBOM() (map[string]sbomStub, error) {
}
return res, nil
}
func isInTotoDSSE(mime string) bool {
isDSSE, _ := regexp.MatchString("application/vnd\\.in-toto\\..*\\+dsse", mime)
return isDSSE
}
func decodeDSSE(dt []byte, mime string) ([]byte, error) {
if isInTotoDSSE(mime) {
var dsse struct {
Payload string `json:"payload"`
}
if err := json.Unmarshal(dt, &dsse); err != nil {
return nil, err
}
decoded, err := base64.StdEncoding.DecodeString(dsse.Payload)
if err != nil {
return nil, err
}
dt = decoded
}
return dt, nil
}
func withIntotoMediaTypes(ctx context.Context) context.Context {
for _, mime := range []string{inTotoGenericMime, inTotoSPDXDSSEMime, inTotoProvenanceDSSEMime} {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, mime, "intoto")
}
return ctx
}

View File

@@ -37,8 +37,6 @@ import (
// ProjectOptions provides common configuration for loading a project.
type ProjectOptions struct {
ctx context.Context
// Name is a valid Compose project name to be used or empty.
//
// If empty, the project loader will automatically infer a reasonable
@@ -80,6 +78,10 @@ type ProjectOptions struct {
EnvFiles []string
loadOptions []func(*loader.Options)
// Callbacks to retrieve metadata information during parse defined before
// creating the project
Listeners []loader.Listener
}
type ProjectOptionsFn func(*ProjectOptions) error
@@ -89,6 +91,7 @@ func NewProjectOptions(configs []string, opts ...ProjectOptionsFn) (*ProjectOpti
options := &ProjectOptions{
ConfigPaths: configs,
Environment: map[string]string{},
Listeners: []loader.Listener{},
}
for _, o := range opts {
err := o(options)
@@ -334,14 +337,6 @@ func WithResolvedPaths(resolve bool) ProjectOptionsFn {
}
}
// WithContext sets the context used to load model and resources
func WithContext(ctx context.Context) ProjectOptionsFn {
return func(o *ProjectOptions) error {
o.ctx = ctx
return nil
}
}
// WithResourceLoader register support for ResourceLoader to manage remote resources
func WithResourceLoader(r loader.ResourceLoader) ProjectOptionsFn {
return func(o *ProjectOptions) error {
@@ -352,6 +347,24 @@ func WithResourceLoader(r loader.ResourceLoader) ProjectOptionsFn {
}
}
// WithExtension register a know extension `x-*` with the go struct type to decode into
func WithExtension(name string, typ any) ProjectOptionsFn {
return func(o *ProjectOptions) error {
o.loadOptions = append(o.loadOptions, func(options *loader.Options) {
if options.KnownExtensions == nil {
options.KnownExtensions = map[string]any{}
}
options.KnownExtensions[name] = typ
})
return nil
}
}
// Append listener to event
func (o *ProjectOptions) WithListeners(listeners ...loader.Listener) {
o.Listeners = append(o.Listeners, listeners...)
}
// WithoutEnvironmentResolution disable environment resolution
func WithoutEnvironmentResolution(o *ProjectOptions) error {
o.loadOptions = append(o.loadOptions, func(options *loader.Options) {
@@ -368,7 +381,7 @@ var DefaultOverrideFileNames = []string{"compose.override.yml", "compose.overrid
func (o ProjectOptions) GetWorkingDir() (string, error) {
if o.WorkingDir != "" {
return o.WorkingDir, nil
return filepath.Abs(o.WorkingDir)
}
for _, path := range o.ConfigPaths {
if path != "-" {
@@ -382,9 +395,8 @@ func (o ProjectOptions) GetWorkingDir() (string, error) {
return os.Getwd()
}
// ProjectFromOptions load a compose project based on command line options
func ProjectFromOptions(options *ProjectOptions) (*types.Project, error) {
configPaths, err := getConfigPathsFromOptions(options)
func (o ProjectOptions) GeConfigFiles() ([]types.ConfigFile, error) {
configPaths, err := o.getConfigPaths()
if err != nil {
return nil, err
}
@@ -412,24 +424,25 @@ func ProjectFromOptions(options *ProjectOptions) (*types.Project, error) {
Content: b,
})
}
return configs, err
}
// ProjectFromOptions load a compose project based on command line options
func ProjectFromOptions(ctx context.Context, options *ProjectOptions) (*types.Project, error) {
configs, err := options.GeConfigFiles()
if err != nil {
return nil, err
}
workingDir, err := options.GetWorkingDir()
if err != nil {
return nil, err
}
absWorkingDir, err := filepath.Abs(workingDir)
if err != nil {
return nil, err
}
options.loadOptions = append(options.loadOptions,
withNamePrecedenceLoad(absWorkingDir, options),
withConvertWindowsPaths(options))
ctx := options.ctx
if ctx == nil {
ctx = context.Background()
}
withNamePrecedenceLoad(workingDir, options),
withConvertWindowsPaths(options),
withListeners(options))
project, err := loader.LoadWithContext(ctx, types.ConfigDetails{
ConfigFiles: configs,
@@ -440,7 +453,10 @@ func ProjectFromOptions(options *ProjectOptions) (*types.Project, error) {
return nil, err
}
project.ComposeFiles = configPaths
for _, config := range configs {
project.ComposeFiles = append(project.ComposeFiles, config.Filename)
}
return project, nil
}
@@ -467,10 +483,17 @@ func withConvertWindowsPaths(options *ProjectOptions) func(*loader.Options) {
}
}
// getConfigPathsFromOptions retrieves the config files for project based on project options
func getConfigPathsFromOptions(options *ProjectOptions) ([]string, error) {
if len(options.ConfigPaths) != 0 {
return absolutePaths(options.ConfigPaths)
// save listeners from ProjectOptions (compose) to loader.Options
func withListeners(options *ProjectOptions) func(*loader.Options) {
return func(opts *loader.Options) {
opts.Listeners = append(opts.Listeners, options.Listeners...)
}
}
// getConfigPaths retrieves the config files for project based on project options
func (o *ProjectOptions) getConfigPaths() ([]string, error) {
if len(o.ConfigPaths) != 0 {
return absolutePaths(o.ConfigPaths)
}
return nil, fmt.Errorf("no configuration file provided: %w", errdefs.ErrNotFound)
}

View File

@@ -0,0 +1,59 @@
/*
Copyright 2020 The Compose Specification 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 loader
import (
"fmt"
"github.com/compose-spec/compose-go/v2/types"
)
// Will update the environment variables for the format {- VAR} (without interpolation)
// This function should resolve context environment vars for include (passed in env_file)
func resolveServicesEnvironment(dict map[string]any, config types.ConfigDetails) {
services, ok := dict["services"].(map[string]any)
if !ok {
return
}
for service, cfg := range services {
serviceConfig, ok := cfg.(map[string]any)
if !ok {
continue
}
serviceEnv, ok := serviceConfig["environment"].([]any)
if !ok {
continue
}
envs := []any{}
for _, env := range serviceEnv {
varEnv, ok := env.(string)
if !ok {
continue
}
if found, ok := config.Environment[varEnv]; ok {
envs = append(envs, fmt.Sprintf("%s=%s", varEnv, found))
} else {
// either does not exist or it was already resolved in interpolation
envs = append(envs, varEnv)
}
}
serviceConfig["environment"] = envs
services[service] = serviceConfig
}
dict["services"] = services
}

View File

@@ -20,6 +20,7 @@ import (
"context"
"fmt"
"path/filepath"
"strings"
"github.com/compose-spec/compose-go/v2/consts"
"github.com/compose-spec/compose-go/v2/override"
@@ -60,11 +61,8 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
return s, nil
}
filename := ctx.Value(consts.ComposeFileKey{}).(string)
tracker, err := tracker.Add(filename, name)
if err != nil {
return nil, err
}
var (
err error
ref string
file any
)
@@ -72,14 +70,16 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
case map[string]any:
ref = v["service"].(string)
file = v["file"]
opts.ProcessEvent("extends", v)
case string:
ref = v
opts.ProcessEvent("extends", map[string]any{"service": ref})
}
var base any
if file != nil {
path := file.(string)
services, err = getExtendsBaseFromFile(ctx, ref, path, opts, tracker)
filename = file.(string)
services, err = getExtendsBaseFromFile(ctx, ref, filename, opts, tracker)
if err != nil {
return nil, err
}
@@ -89,6 +89,12 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
return nil, fmt.Errorf("cannot extend service %q in %s: service not found", name, filename)
}
}
tracker, err = tracker.Add(filename, name)
if err != nil {
return nil, err
}
// recursively apply `extends`
base, err = applyServiceExtends(ctx, ref, services, opts, tracker, post...)
if err != nil {
@@ -99,6 +105,12 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
return service, nil
}
source := deepClone(base).(map[string]any)
err = validateExtendSource(source, ref)
if err != nil {
return nil, err
}
for _, processor := range post {
processor.Apply(map[string]any{
"services": map[string]any{
@@ -111,9 +123,34 @@ func applyServiceExtends(ctx context.Context, name string, services map[string]a
return nil, err
}
delete(merged, "extends")
services[name] = merged
return merged, nil
}
// validateExtendSource check the source for `extends` doesn't refer to another container/service
func validateExtendSource(source map[string]any, ref string) error {
forbidden := []string{"links", "volumes_from", "depends_on"}
for _, key := range forbidden {
if _, ok := source[key]; ok {
return fmt.Errorf("service %q can't be used with `extends` as it declare `%s`", ref, key)
}
}
sharedNamespace := []string{"network_mode", "ipc", "pid", "net", "cgroup", "userns_mode", "uts"}
for _, key := range sharedNamespace {
if v, ok := source[key]; ok {
val := v.(string)
if strings.HasPrefix(val, types.ContainerPrefix) {
return fmt.Errorf("service %q can't be used with `extends` as it shares `%s` with another container", ref, key)
}
if strings.HasPrefix(val, types.ServicePrefix) {
return fmt.Errorf("service %q can't be used with `extends` as it shares `%s` with another service", ref, key)
}
}
}
return nil
}
func getExtendsBaseFromFile(ctx context.Context, name string, path string, opts *Options, ct *cycleTracker) (map[string]any, error) {
for _, loader := range opts.ResourceLoaders {
if !loader.Accept(path) {
@@ -137,6 +174,7 @@ func getExtendsBaseFromFile(ctx context.Context, name string, path string, opts
extendsOpts.SkipInclude = true
extendsOpts.SkipExtends = true // we manage extends recursively based on raw service definition
extendsOpts.SkipValidation = true // we validate the merge result
extendsOpts.SkipDefaultValues = true
source, err := loadYamlModel(ctx, types.ConfigDetails{
WorkingDir: relworkingdir,
ConfigFiles: []types.ConfigFile{

View File

@@ -26,7 +26,8 @@ services:
additional_contexts:
foo: ./bar
secrets:
- secret1
- source: secret1
target: /run/secrets/secret1
- source: secret2
target: my_secret
uid: '103'
@@ -257,7 +258,8 @@ services:
restart: always
secrets:
- secret1
- source: secret1
target: /run/secrets/secret1
- source: secret2
target: my_secret
uid: '103'

View File

@@ -34,6 +34,14 @@ func loadIncludeConfig(source any) ([]types.IncludeConfig, error) {
if source == nil {
return nil, nil
}
configs := source.([]any)
for i, config := range configs {
if v, ok := config.(string); ok {
configs[i] = map[string]any{
"path": v,
}
}
}
var requires []types.IncludeConfig
err := Transform(source, &requires)
return requires, err
@@ -45,6 +53,13 @@ func ApplyInclude(ctx context.Context, configDetails types.ConfigDetails, model
return err
}
for _, r := range includeConfig {
for _, listener := range options.Listeners {
listener("include", map[string]any{
"path": r.Path,
"workingdir": configDetails.WorkingDir,
})
}
for i, p := range r.Path {
for _, loader := range options.ResourceLoaders {
if loader.Accept(p) {
@@ -56,7 +71,7 @@ func ApplyInclude(ctx context.Context, configDetails types.ConfigDetails, model
break
}
}
r.Path[i] = absPath(configDetails.WorkingDir, p)
r.Path[i] = p
}
mainFile := r.Path[0]
@@ -70,17 +85,41 @@ func ApplyInclude(ctx context.Context, configDetails types.ConfigDetails, model
if r.ProjectDirectory == "" {
r.ProjectDirectory = filepath.Dir(mainFile)
}
relworkingdir, err := filepath.Rel(configDetails.WorkingDir, r.ProjectDirectory)
if err != nil {
// included file path is not inside project working directory => use absolute path
relworkingdir = r.ProjectDirectory
}
loadOptions := options.clone()
loadOptions.ResolvePaths = true
loadOptions.SkipNormalization = true
loadOptions.SkipConsistencyCheck = true
loadOptions.ResourceLoaders = append(loadOptions.RemoteResourceLoaders(), localResourceLoader{
WorkingDir: relworkingdir,
})
if len(r.EnvFile) == 0 {
f := filepath.Join(r.ProjectDirectory, ".env")
if s, err := os.Stat(f); err == nil && !s.IsDir() {
r.EnvFile = types.StringList{f}
}
} else {
envFile := []string{}
for _, f := range r.EnvFile {
if !filepath.IsAbs(f) {
f = filepath.Join(configDetails.WorkingDir, f)
s, err := os.Stat(f)
if err != nil {
return err
}
if s.IsDir() {
return fmt.Errorf("%s is not a file", f)
}
}
envFile = append(envFile, f)
}
r.EnvFile = envFile
}
envFromFile, err := dotenv.GetEnvFromFile(configDetails.Environment, r.EnvFile)
@@ -89,7 +128,7 @@ func ApplyInclude(ctx context.Context, configDetails types.ConfigDetails, model
}
config := types.ConfigDetails{
WorkingDir: r.ProjectDirectory,
WorkingDir: relworkingdir,
ConfigFiles: types.ToConfigFiles(r.Path),
Environment: configDetails.Environment.Clone().Merge(envFromFile),
}

View File

@@ -64,6 +64,8 @@ type Options struct {
SkipInclude bool
// SkipResolveEnvironment will ignore computing `environment` for services
SkipResolveEnvironment bool
// SkipDefaultValues will ignore missing required attributes
SkipDefaultValues bool
// Interpolation options
Interpolate *interp.Options
// Discard 'env_file' entries after resolving to 'environment' section
@@ -76,6 +78,19 @@ type Options struct {
Profiles []string
// ResourceLoaders manages support for remote resources
ResourceLoaders []ResourceLoader
// KnownExtensions manages x-* attribute we know and the corresponding go structs
KnownExtensions map[string]any
// Metada for telemetry
Listeners []Listener
}
type Listener = func(event string, metadata map[string]any)
// Invoke all listeners for an event
func (o *Options) ProcessEvent(event string, metadata map[string]any) {
for _, l := range o.Listeners {
l(event, metadata)
}
}
// ResourceLoader is a plugable remote resource resolver
@@ -148,6 +163,8 @@ func (o *Options) clone() *Options {
projectNameImperativelySet: o.projectNameImperativelySet,
Profiles: o.Profiles,
ResourceLoaders: o.ResourceLoaders,
KnownExtensions: o.KnownExtensions,
Listeners: o.Listeners,
}
}
@@ -288,18 +305,17 @@ func LoadWithContext(ctx context.Context, configDetails types.ConfigDetails, opt
}
opts.ResourceLoaders = append(opts.ResourceLoaders, localResourceLoader{configDetails.WorkingDir})
projectName, err := projectName(configDetails, opts)
err := projectName(configDetails, opts)
if err != nil {
return nil, err
}
opts.projectName = projectName
// TODO(milas): this should probably ALWAYS set (overriding any existing)
if _, ok := configDetails.Environment[consts.ComposeProjectName]; !ok && projectName != "" {
if _, ok := configDetails.Environment[consts.ComposeProjectName]; !ok && opts.projectName != "" {
if configDetails.Environment == nil {
configDetails.Environment = map[string]string{}
}
configDetails.Environment[consts.ComposeProjectName] = projectName
configDetails.Environment[consts.ComposeProjectName] = opts.projectName
}
return load(ctx, configDetails, opts, nil)
@@ -312,7 +328,7 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
)
for _, file := range config.ConfigFiles {
fctx := context.WithValue(ctx, consts.ComposeFileKey{}, file.Filename)
if len(file.Content) == 0 && file.Config == nil {
if file.Content == nil && file.Config == nil {
content, err := os.ReadFile(file.Filename)
if err != nil {
return nil, err
@@ -352,6 +368,14 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
}
}
if !opts.SkipInclude {
included = append(included, config.ConfigFiles[0].Filename)
err = ApplyInclude(ctx, config, cfg, opts, included)
if err != nil {
return err
}
}
dict, err = override.Merge(dict, cfg)
if err != nil {
return err
@@ -400,9 +424,14 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
return nil, err
}
if !opts.SkipInclude {
included = append(included, config.ConfigFiles[0].Filename)
err = ApplyInclude(ctx, config, dict, opts, included)
// Canonical transformation can reveal duplicates, typically as ports can be a range and conflict with an override
dict, err = override.EnforceUnicity(dict)
if err != nil {
return nil, err
}
if !opts.SkipDefaultValues {
dict, err = transform.SetDefaultValues(dict)
if err != nil {
return nil, err
}
@@ -424,6 +453,7 @@ func loadYamlModel(ctx context.Context, config types.ConfigDetails, opts *Option
return nil, err
}
}
resolveServicesEnvironment(dict, config)
return dict, nil
}
@@ -438,8 +468,6 @@ func load(ctx context.Context, configDetails types.ConfigDetails, opts *Options,
}
loaded = append(loaded, mainFile)
includeRefs := make(map[string][]types.IncludeConfig)
dict, err := loadYamlModel(ctx, configDetails, opts, &cycleTracker{}, nil)
if err != nil {
return nil, err
@@ -449,6 +477,10 @@ func load(ctx context.Context, configDetails types.ConfigDetails, opts *Options,
return nil, errors.New("empty compose file")
}
if opts.projectName == "" {
return nil, errors.New("project name must not be empty")
}
project := &types.Project{
Name: opts.projectName,
WorkingDir: configDetails.WorkingDir,
@@ -456,14 +488,14 @@ func load(ctx context.Context, configDetails types.ConfigDetails, opts *Options,
}
delete(dict, "name") // project name set by yaml must be identified by caller as opts.projectName
dict = groupXFieldsIntoExtensions(dict, tree.NewPath())
err = Transform(dict, project)
dict, err = processExtensions(dict, tree.NewPath(), opts.KnownExtensions)
if err != nil {
return nil, err
}
if len(includeRefs) != 0 {
project.IncludeReferences = includeRefs
err = Transform(dict, project)
if err != nil {
return nil, err
}
if !opts.SkipNormalization {
@@ -516,69 +548,68 @@ func InvalidProjectNameErr(v string) error {
//
// TODO(milas): restructure loading so that we don't need to re-parse the YAML
// here, as it's both wasteful and makes this code error-prone.
func projectName(details types.ConfigDetails, opts *Options) (string, error) {
projectName, projectNameImperativelySet := opts.GetProjectName()
func projectName(details types.ConfigDetails, opts *Options) error {
if opts.projectNameImperativelySet {
if NormalizeProjectName(opts.projectName) != opts.projectName {
return InvalidProjectNameErr(opts.projectName)
}
return nil
}
type named struct {
Name string `yaml:"name"`
}
// if user did NOT provide a name explicitly, then see if one is defined
// in any of the config files
if !projectNameImperativelySet {
var pjNameFromConfigFile string
for _, configFile := range details.ConfigFiles {
content := configFile.Content
if content == nil {
// This can be hit when Filename is set but Content is not. One
// example is when using ToConfigFiles().
d, err := os.ReadFile(configFile.Filename)
if err != nil {
return "", fmt.Errorf("failed to read file %q: %w", configFile.Filename, err)
}
content = d
var pjNameFromConfigFile string
for _, configFile := range details.ConfigFiles {
content := configFile.Content
if content == nil {
// This can be hit when Filename is set but Content is not. One
// example is when using ToConfigFiles().
d, err := os.ReadFile(configFile.Filename)
if err != nil {
return fmt.Errorf("failed to read file %q: %w", configFile.Filename, err)
}
content = d
configFile.Content = d
}
var n named
r := bytes.NewReader(content)
decoder := yaml.NewDecoder(r)
for {
err := decoder.Decode(&n)
if err != nil && errors.Is(err, io.EOF) {
break
}
yml, err := ParseYAML(content)
if err != nil {
// HACK: the way that loading is currently structured, this is
// a duplicative parse just for the `name`. if it fails, we
// give up but don't return the error, knowing that it'll get
// caught downstream for us
return "", nil
break
}
if val, ok := yml["name"]; ok && val != "" {
sVal, ok := val.(string)
if !ok {
// HACK: see above - this is a temporary parsed version
// that hasn't been schema-validated, but we don't want
// to be the ones to actually report that, so give up,
// knowing that it'll get caught downstream for us
return "", nil
}
pjNameFromConfigFile = sVal
if n.Name != "" {
pjNameFromConfigFile = n.Name
}
}
if !opts.SkipInterpolation {
interpolated, err := interp.Interpolate(
map[string]interface{}{"name": pjNameFromConfigFile},
*opts.Interpolate,
)
if err != nil {
return "", err
}
pjNameFromConfigFile = interpolated["name"].(string)
}
pjNameFromConfigFile = NormalizeProjectName(pjNameFromConfigFile)
if pjNameFromConfigFile != "" {
projectName = pjNameFromConfigFile
}
if !opts.SkipInterpolation {
interpolated, err := interp.Interpolate(
map[string]interface{}{"name": pjNameFromConfigFile},
*opts.Interpolate,
)
if err != nil {
return err
}
pjNameFromConfigFile = interpolated["name"].(string)
}
if projectName == "" {
return "", errors.New("project name must not be empty")
pjNameFromConfigFile = NormalizeProjectName(pjNameFromConfigFile)
if pjNameFromConfigFile != "" {
opts.projectName = pjNameFromConfigFile
}
if NormalizeProjectName(projectName) != projectName {
return "", InvalidProjectNameErr(projectName)
}
return projectName, nil
return nil
}
func NormalizeProjectName(s string) string {
@@ -596,8 +627,9 @@ var userDefinedKeys = []tree.Path{
"configs",
}
func groupXFieldsIntoExtensions(dict map[string]interface{}, p tree.Path) map[string]interface{} {
extras := map[string]interface{}{}
func processExtensions(dict map[string]any, p tree.Path, extensions map[string]any) (map[string]interface{}, error) {
extras := map[string]any{}
var err error
for key, value := range dict {
skip := false
for _, uk := range userDefinedKeys {
@@ -613,19 +645,35 @@ func groupXFieldsIntoExtensions(dict map[string]interface{}, p tree.Path) map[st
}
switch v := value.(type) {
case map[string]interface{}:
dict[key] = groupXFieldsIntoExtensions(v, p.Next(key))
dict[key], err = processExtensions(v, p.Next(key), extensions)
if err != nil {
return nil, err
}
case []interface{}:
for i, e := range v {
if m, ok := e.(map[string]interface{}); ok {
v[i] = groupXFieldsIntoExtensions(m, p.Next(strconv.Itoa(i)))
v[i], err = processExtensions(m, p.Next(strconv.Itoa(i)), extensions)
if err != nil {
return nil, err
}
}
}
}
}
for name, val := range extras {
if typ, ok := extensions[name]; ok {
target := reflect.New(reflect.TypeOf(typ)).Elem().Interface()
err = Transform(val, &target)
if err != nil {
return nil, err
}
extras[name] = target
}
}
if len(extras) > 0 {
dict[consts.Extensions] = extras
}
return dict
return dict, nil
}
// Transform converts the source into the target struct with compose types transformer

View File

@@ -37,25 +37,6 @@ func ResolveRelativePaths(project *types.Project) error {
return err
}
project.ComposeFiles = absComposeFiles
// don't coerce a nil map to an empty map
if project.IncludeReferences != nil {
absIncludes := make(map[string][]types.IncludeConfig, len(project.IncludeReferences))
for filename, config := range project.IncludeReferences {
filename = absPath(project.WorkingDir, filename)
absConfigs := make([]types.IncludeConfig, len(config))
for i, c := range config {
absConfigs[i] = types.IncludeConfig{
Path: resolvePaths(project.WorkingDir, c.Path),
ProjectDirectory: absPath(project.WorkingDir, c.ProjectDirectory),
EnvFile: resolvePaths(project.WorkingDir, c.EnvFile),
}
}
absIncludes[filename] = absConfigs
}
project.IncludeReferences = absIncludes
}
return nil
}

View File

@@ -29,6 +29,7 @@ import (
// checkConsistency validate a compose model is consistent
func checkConsistency(project *types.Project) error {
containerNames := map[string]string{}
for _, s := range project.Services {
if s.Build == nil && s.Image == "" {
return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid)
@@ -123,6 +124,13 @@ func checkConsistency(project *types.Project) error {
s.Deploy.Replicas = s.Scale
}
if s.ContainerName != "" {
if existing, ok := containerNames[s.ContainerName]; ok {
return fmt.Errorf(`"services.%s": container name "%s" is already in use by "services.%s": %w`, s.Name, s.ContainerName, existing, errdefs.ErrInvalid)
}
containerNames[s.ContainerName] = s.Name
}
if s.GetScale() > 1 && s.ContainerName != "" {
attr := "scale"
if s.Scale == nil {
@@ -131,6 +139,15 @@ func checkConsistency(project *types.Project) error {
return fmt.Errorf("services.%s: can't set container_name and %s as container name must be unique: %w", attr,
s.Name, errdefs.ErrInvalid)
}
if s.Develop != nil && s.Develop.Watch != nil {
for _, watch := range s.Develop.Watch {
if watch.Action != types.WatchActionRebuild && watch.Target == "" {
return fmt.Errorf("services.%s.develop.watch: target is required for non-rebuild actions: %w", s.Name, errdefs.ErrInvalid)
}
}
}
}
for name, secret := range project.Secrets {

View File

@@ -17,6 +17,7 @@
package override
import (
"cmp"
"fmt"
"strings"
@@ -40,10 +41,13 @@ var mergeSpecials = map[tree.Path]merger{}
func init() {
mergeSpecials["networks.*.ipam.config"] = mergeIPAMConfig
mergeSpecials["networks.*.labels"] = mergeToSequence
mergeSpecials["volumes.*.labels"] = mergeToSequence
mergeSpecials["services.*.annotations"] = mergeToSequence
mergeSpecials["services.*.build"] = mergeBuild
mergeSpecials["services.*.build.args"] = mergeToSequence
mergeSpecials["services.*.build.additional_contexts"] = mergeToSequence
mergeSpecials["services.*.build.extra_hosts"] = mergeToSequence
mergeSpecials["services.*.build.labels"] = mergeToSequence
mergeSpecials["services.*.command"] = override
mergeSpecials["services.*.depends_on"] = mergeDependsOn
@@ -178,8 +182,8 @@ func convertIntoSequence(value any) []any {
}
i++
}
slices.SortFunc(seq, func(a, b any) bool {
return a.(string) < b.(string)
slices.SortFunc(seq, func(a, b any) int {
return cmp.Compare(a.(string), b.(string))
})
return seq
case []any:

View File

@@ -107,13 +107,17 @@ func enforceUnicity(value any, p tree.Path) (any, error) {
return value, nil
}
func keyValueIndexer(y any, _ tree.Path) (string, error) {
value := y.(string)
key, _, found := strings.Cut(value, "=")
if !found {
return value, nil
func keyValueIndexer(y any, p tree.Path) (string, error) {
switch value := y.(type) {
case string:
key, _, found := strings.Cut(value, "=")
if !found {
return value, nil
}
return key, nil
default:
return "", fmt.Errorf("%s: unexpected type %T", p, y)
}
return key, nil
}
func volumeIndexer(y any, p tree.Path) (string, error) {

View File

@@ -455,6 +455,7 @@
"type": "array",
"items": {
"type": "object",
"required": ["path", "action"],
"properties": {
"ignore": {"type": "array", "items": {"type": "string"}},
"path": {"type": "string"},
@@ -462,7 +463,6 @@
"target": {"type": "string"}
}
},
"required": ["path", "action"],
"additionalProperties": false,
"patternProperties": {"^x-": {}}
}

View File

@@ -258,7 +258,7 @@ func getFirstBraceClosingIndex(s string) int {
return i
}
}
if strings.HasPrefix(s[i:], "${") {
if s[i] == '{' {
openVariableBraces++
i++
}

View File

@@ -25,9 +25,6 @@ import (
func transformBuild(data any, p tree.Path) (any, error) {
switch v := data.(type) {
case map[string]any:
if _, ok := v["context"]; !ok {
v["context"] = "." // TODO(ndeloof) maybe we miss an explicit "set-defaults" loading phase
}
return transformMapping(v, p)
case string:
return map[string]any{
@@ -37,3 +34,15 @@ func transformBuild(data any, p tree.Path) (any, error) {
return data, fmt.Errorf("%s: invalid type %T for build", p, v)
}
}
func defaultBuildContext(data any, _ tree.Path) (any, error) {
switch v := data.(type) {
case map[string]any:
if _, ok := v["context"]; !ok {
v["context"] = "."
}
return v, nil
default:
return data, nil
}
}

View File

@@ -0,0 +1,87 @@
/*
Copyright 2020 The Compose Specification 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 transform
import (
"github.com/compose-spec/compose-go/v2/tree"
)
var defaultValues = map[tree.Path]transformFunc{}
func init() {
defaultValues["services.*.build"] = defaultBuildContext
defaultValues["services.*.secrets.*"] = defaultSecretMount
}
// SetDefaultValues transforms a compose model to set default values to missing attributes
func SetDefaultValues(yaml map[string]any) (map[string]any, error) {
result, err := setDefaults(yaml, tree.NewPath())
if err != nil {
return nil, err
}
return result.(map[string]any), nil
}
func setDefaults(data any, p tree.Path) (any, error) {
for pattern, transformer := range defaultValues {
if p.Matches(pattern) {
t, err := transformer(data, p)
if err != nil {
return nil, err
}
return t, nil
}
}
switch v := data.(type) {
case map[string]any:
a, err := setDefaultsMapping(v, p)
if err != nil {
return a, err
}
return v, nil
case []any:
a, err := setDefaultsSequence(v, p)
if err != nil {
return a, err
}
return v, nil
default:
return data, nil
}
}
func setDefaultsSequence(v []any, p tree.Path) ([]any, error) {
for i, e := range v {
t, err := setDefaults(e, p.Next("[]"))
if err != nil {
return nil, err
}
v[i] = t
}
return v, nil
}
func setDefaultsMapping(v map[string]any, p tree.Path) (map[string]any, error) {
for k, e := range v {
t, err := setDefaults(e, p.Next(k))
if err != nil {
return nil, err
}
v[k] = t
}
return v, nil
}

View File

@@ -48,7 +48,7 @@ func transformPorts(data any, p tree.Path) (any, error) {
case string:
parsed, err := types.ParsePortConfig(value)
if err != nil {
return data, err
return data, nil
}
if err != nil {
return nil, err

View File

@@ -34,3 +34,16 @@ func transformFileMount(data any, p tree.Path) (any, error) {
return nil, fmt.Errorf("%s: unsupported type %T", p, data)
}
}
func defaultSecretMount(data any, p tree.Path) (any, error) {
switch v := data.(type) {
case map[string]any:
source := v["source"]
if _, ok := v["target"]; !ok {
v["target"] = fmt.Sprintf("/run/secrets/%s", source)
}
return v, nil
default:
return nil, fmt.Errorf("%s: unsupported type %T", p, data)
}
}

View File

@@ -17,7 +17,7 @@
package types
type DevelopConfig struct {
Watch []Trigger `json:"watch,omitempty"`
Watch []Trigger `yaml:"watch,omitempty" json:"watch,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
}
@@ -31,8 +31,8 @@ const (
)
type Trigger struct {
Path string `json:"path,omitempty"`
Action WatchAction `json:"action,omitempty"`
Target string `json:"target,omitempty"`
Ignore []string `json:"ignore,omitempty"`
Path string `yaml:"path" json:"path"`
Action WatchAction `yaml:"action" json:"action"`
Target string `yaml:"target,omitempty" json:"target,omitempty"`
Ignore []string `yaml:"ignore,omitempty" json:"ignore,omitempty"`
}

View File

@@ -24,7 +24,33 @@ import (
)
// HostsList is a list of colon-separated host-ip mappings
type HostsList map[string]string
type HostsList map[string][]string
// NewHostsList creates a HostsList from a list of `host=ip` strings
func NewHostsList(hosts []string) (HostsList, error) {
list := HostsList{}
for _, s := range hosts {
var found bool
for _, sep := range hostListSerapators {
host, ip, ok := strings.Cut(s, sep)
if ok {
// Mapping found with this separator, stop here.
if ips, ok := list[host]; ok {
list[host] = append(ips, ip)
} else {
list[host] = []string{ip}
}
found = true
break
}
}
if !found {
return nil, fmt.Errorf("invalid additional host, missing IP: %s", s)
}
}
err := list.cleanup()
return list, err
}
// AsList returns host-ip mappings as a list of strings, using the given
// separator. The Docker Engine API expects ':' separators, the original format
@@ -34,7 +60,9 @@ type HostsList map[string]string
func (h HostsList) AsList(sep string) []string {
l := make([]string, 0, len(h))
for k, v := range h {
l = append(l, fmt.Sprintf("%s%s%s", k, sep, v))
for _, ip := range v {
l = append(l, fmt.Sprintf("%s%s%s", k, sep, ip))
}
}
return l
}
@@ -51,6 +79,8 @@ func (h HostsList) MarshalJSON() ([]byte, error) {
return json.Marshal(list)
}
var hostListSerapators = []string{"=", ":"}
func (h *HostsList) DecodeMapstructure(value interface{}) error {
switch v := value.(type) {
case map[string]interface{}:
@@ -59,25 +89,45 @@ func (h *HostsList) DecodeMapstructure(value interface{}) error {
if e == nil {
e = ""
}
list[i] = fmt.Sprint(e)
list[i] = []string{fmt.Sprint(e)}
}
err := list.cleanup()
if err != nil {
return err
}
*h = list
return nil
case []interface{}:
*h = decodeMapping(v, "=", ":")
s := make([]string, len(v))
for i, e := range v {
s[i] = fmt.Sprint(e)
}
list, err := NewHostsList(s)
if err != nil {
return err
}
*h = list
return nil
default:
return fmt.Errorf("unexpected value type %T for mapping", value)
}
for host, ip := range *h {
}
func (h HostsList) cleanup() error {
for host, ips := range h {
// Check that there is a hostname and that it doesn't contain either
// of the allowed separators, to generate a clearer error than the
// engine would do if it splits the string differently.
if host == "" || strings.ContainsAny(host, ":=") {
return fmt.Errorf("bad host name '%s'", host)
}
// Remove brackets from IP addresses (for example "[::1]" -> "::1").
if len(ip) > 2 && ip[0] == '[' && ip[len(ip)-1] == ']' {
(*h)[host] = ip[1 : len(ip)-1]
for i, ip := range ips {
// Remove brackets from IP addresses (for example "[::1]" -> "::1").
if len(ip) > 2 && ip[0] == '[' && ip[len(ip)-1] == ']' {
ips[i] = ip[1 : len(ip)-1]
}
}
h[host] = ips
}
return nil
}

View File

@@ -29,6 +29,7 @@ import (
"github.com/distribution/reference"
"github.com/mitchellh/copystructure"
godigest "github.com/opencontainers/go-digest"
"golang.org/x/exp/maps"
"golang.org/x/sync/errgroup"
"gopkg.in/yaml.v3"
)
@@ -46,13 +47,8 @@ type Project struct {
Configs Configs `yaml:"configs,omitempty" json:"configs,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` // https://github.com/golang/go/issues/6213
// IncludeReferences is keyed by Compose YAML filename and contains config for
// other Compose YAML files it directly triggered a load of via `include`.
//
// Note: this is
IncludeReferences map[string][]IncludeConfig `yaml:"-" json:"-"`
ComposeFiles []string `yaml:"-" json:"-"`
Environment Mapping `yaml:"-" json:"-"`
ComposeFiles []string `yaml:"-" json:"-"`
Environment Mapping `yaml:"-" json:"-"`
// DisabledServices track services which have been disable as profile is not active
DisabledServices Services `yaml:"-" json:"-"`
@@ -119,6 +115,58 @@ func (p *Project) ConfigNames() []string {
return names
}
func (p *Project) ServicesWithBuild() []string {
servicesBuild := p.Services.Filter(func(s ServiceConfig) bool {
return s.Build != nil && s.Build.Context != ""
})
return maps.Keys(servicesBuild)
}
func (p *Project) ServicesWithExtends() []string {
servicesExtends := p.Services.Filter(func(s ServiceConfig) bool {
return s.Extends != nil && *s.Extends != (ExtendsConfig{})
})
return maps.Keys(servicesExtends)
}
func (p *Project) ServicesWithDependsOn() []string {
servicesDependsOn := p.Services.Filter(func(s ServiceConfig) bool {
return len(s.DependsOn) > 0
})
return maps.Keys(servicesDependsOn)
}
func (p *Project) ServicesWithCapabilities() ([]string, []string, []string) {
capabilities := []string{}
gpu := []string{}
tpu := []string{}
for _, service := range p.Services {
deploy := service.Deploy
if deploy == nil {
continue
}
reservation := deploy.Resources.Reservations
if reservation == nil {
continue
}
devices := reservation.Devices
for _, d := range devices {
if len(d.Capabilities) > 0 {
capabilities = append(capabilities, service.Name)
}
for _, c := range d.Capabilities {
if c == "gpu" {
gpu = append(gpu, service.Name)
} else if c == "tpu" {
tpu = append(tpu, service.Name)
}
}
}
}
return utils.RemoveDuplicates(capabilities), utils.RemoveDuplicates(gpu), utils.RemoveDuplicates(tpu)
}
// GetServices retrieve services by names, or return all services if no name specified
func (p *Project) GetServices(names ...string) (Services, error) {
if len(names) == 0 {

View File

@@ -33,3 +33,13 @@ func (s Services) GetProfiles() []string {
}
return profiles
}
func (s Services) Filter(predicate func(ServiceConfig) bool) Services {
services := Services{}
for name, service := range s {
if predicate(service) {
services[name] = service
}
}
return services
}

View File

@@ -162,6 +162,9 @@ func (s *ServiceConfig) NetworksByPriority() []string {
})
}
sort.Slice(keys, func(i, j int) bool {
if keys[i].priority == keys[j].priority {
return keys[i].name < keys[j].name
}
return keys[i].priority > keys[j].priority
})
var sorted []string

View File

@@ -51,3 +51,18 @@ func ArrayContains[T comparable](source []T, toCheck []T) bool {
}
return true
}
func RemoveDuplicates[T comparable](slice []T) []T {
// Create a map to store unique elements
seen := make(map[T]bool)
result := []T{}
// Loop through the slice, adding elements to the map if they haven't been seen before
for _, val := range slice {
if _, ok := seen[val]; !ok {
seen[val] = true
result = append(result, val)
}
}
return result
}

View File

@@ -1,6 +1,15 @@
# Change history of go-restful
## [v3.10.1] - 2022-11-19
## [v3.11.0] - 2023-08-19
- restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled.
## [v3.10.2] - 2023-03-09 - DO NOT USE
- introduced MergePathStrategy to be able to revert behaviour of path concatenation to 3.9.0
see comment in Readme how to customize this behaviour.
## [v3.10.1] - 2022-11-19 - DO NOT USE
- fix broken 3.10.0 by using path package for joining paths

View File

@@ -79,7 +79,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
- Content encoding (gzip,deflate) of request and response payloads
- Automatic responses on OPTIONS (using a filter)
- Automatic CORS request handling (using a filter)
- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12))
- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi))
- Panic recovery to produce HTTP 500, customizable using RecoverHandler(...)
- Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...)
- Configurable (trace) logging
@@ -96,6 +96,7 @@ There are several hooks to customize the behavior of the go-restful package.
- Compression
- Encoders for other serializers
- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .`
- Use the package variable `TrimRightSlashEnabled` (default true) to control the behavior of matching routes that end with a slash `/`
## Resources
@@ -108,4 +109,4 @@ There are several hooks to customize the behavior of the go-restful package.
Type ```git shortlog -s``` for a full list of contributors.
© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome.
© 2012 - 2023, http://ernestmicklei.com. MIT License. Contributions are welcome.

View File

@@ -40,7 +40,8 @@ type Route struct {
ParameterDocs []*Parameter
ResponseErrors map[int]ResponseError
DefaultResponse *ResponseError
ReadSample, WriteSample interface{} // structs that model an example request or response payload
ReadSample, WriteSample interface{} // structs that model an example request or response payload
WriteSamples []interface{} // if more than one return types is possible (oneof) then this will contain multiple values
// Extra information used to store custom information about the route.
Metadata map[string]interface{}
@@ -164,7 +165,13 @@ func tokenizePath(path string) []string {
if "/" == path {
return nil
}
return strings.Split(strings.TrimLeft(path, "/"), "/")
if TrimRightSlashEnabled {
// 3.9.0
return strings.Split(strings.Trim(path, "/"), "/")
} else {
// 3.10.2
return strings.Split(strings.TrimLeft(path, "/"), "/")
}
}
// for debugging
@@ -177,4 +184,8 @@ func (r *Route) EnableContentEncoding(enabled bool) {
r.contentEncodingEnabled = &enabled
}
var TrimRightSlashEnabled = false
// TrimRightSlashEnabled controls whether
// - path on route building is using path.Join
// - the path of the incoming request is trimmed of its slash suffux.
// Value of true matches the behavior of <= 3.9.0
var TrimRightSlashEnabled = true

View File

@@ -31,17 +31,18 @@ type RouteBuilder struct {
typeNameHandleFunc TypeNameHandleFunction // required
// documentation
doc string
notes string
operation string
readSample, writeSample interface{}
parameters []*Parameter
errorMap map[int]ResponseError
defaultResponse *ResponseError
metadata map[string]interface{}
extensions map[string]interface{}
deprecated bool
contentEncodingEnabled *bool
doc string
notes string
operation string
readSample interface{}
writeSamples []interface{}
parameters []*Parameter
errorMap map[int]ResponseError
defaultResponse *ResponseError
metadata map[string]interface{}
extensions map[string]interface{}
deprecated bool
contentEncodingEnabled *bool
}
// Do evaluates each argument with the RouteBuilder itself.
@@ -135,9 +136,9 @@ func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) {
return p
}
// Writes tells what resource type will be written as the response payload. Optional.
func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder {
b.writeSample = sample
// Writes tells which one of the resource types will be written as the response payload. Optional.
func (b *RouteBuilder) Writes(samples ...interface{}) *RouteBuilder {
b.writeSamples = samples // oneof
return b
}
@@ -342,19 +343,29 @@ func (b *RouteBuilder) Build() Route {
ResponseErrors: b.errorMap,
DefaultResponse: b.defaultResponse,
ReadSample: b.readSample,
WriteSample: b.writeSample,
WriteSamples: b.writeSamples,
Metadata: b.metadata,
Deprecated: b.deprecated,
contentEncodingEnabled: b.contentEncodingEnabled,
allowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType,
}
// set WriteSample if one specified
if len(b.writeSamples) == 1 {
route.WriteSample = b.writeSamples[0]
}
route.Extensions = b.extensions
route.postBuild()
return route
}
func concatPath(path1, path2 string) string {
return path.Join(path1, path2)
// merge two paths using the current (package global) merge path strategy.
func concatPath(rootPath, routePath string) string {
if TrimRightSlashEnabled {
return strings.TrimRight(rootPath, "/") + "/" + strings.TrimLeft(routePath, "/")
} else {
return path.Join(rootPath, routePath)
}
}
var anonymousFuncCount int32

168
vendor/github.com/go-logr/logr/slogr/sloghandler.go generated vendored Normal file
View File

@@ -0,0 +1,168 @@
//go:build go1.21
// +build go1.21
/*
Copyright 2023 The logr 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 slogr
import (
"context"
"log/slog"
"github.com/go-logr/logr"
)
type slogHandler struct {
// May be nil, in which case all logs get discarded.
sink logr.LogSink
// Non-nil if sink is non-nil and implements SlogSink.
slogSink SlogSink
// groupPrefix collects values from WithGroup calls. It gets added as
// prefix to value keys when handling a log record.
groupPrefix string
// levelBias can be set when constructing the handler to influence the
// slog.Level of log records. A positive levelBias reduces the
// slog.Level value. slog has no API to influence this value after the
// handler got created, so it can only be set indirectly through
// Logger.V.
levelBias slog.Level
}
var _ slog.Handler = &slogHandler{}
// groupSeparator is used to concatenate WithGroup names and attribute keys.
const groupSeparator = "."
// GetLevel is used for black box unit testing.
func (l *slogHandler) GetLevel() slog.Level {
return l.levelBias
}
func (l *slogHandler) Enabled(ctx context.Context, level slog.Level) bool {
return l.sink != nil && (level >= slog.LevelError || l.sink.Enabled(l.levelFromSlog(level)))
}
func (l *slogHandler) Handle(ctx context.Context, record slog.Record) error {
if l.slogSink != nil {
// Only adjust verbosity level of log entries < slog.LevelError.
if record.Level < slog.LevelError {
record.Level -= l.levelBias
}
return l.slogSink.Handle(ctx, record)
}
// No need to check for nil sink here because Handle will only be called
// when Enabled returned true.
kvList := make([]any, 0, 2*record.NumAttrs())
record.Attrs(func(attr slog.Attr) bool {
if attr.Key != "" {
kvList = append(kvList, l.addGroupPrefix(attr.Key), attr.Value.Resolve().Any())
}
return true
})
if record.Level >= slog.LevelError {
l.sinkWithCallDepth().Error(nil, record.Message, kvList...)
} else {
level := l.levelFromSlog(record.Level)
l.sinkWithCallDepth().Info(level, record.Message, kvList...)
}
return nil
}
// sinkWithCallDepth adjusts the stack unwinding so that when Error or Info
// are called by Handle, code in slog gets skipped.
//
// This offset currently (Go 1.21.0) works for calls through
// slog.New(NewSlogHandler(...)). There's no guarantee that the call
// chain won't change. Wrapping the handler will also break unwinding. It's
// still better than not adjusting at all....
//
// This cannot be done when constructing the handler because NewLogr needs
// access to the original sink without this adjustment. A second copy would
// work, but then WithAttrs would have to be called for both of them.
func (l *slogHandler) sinkWithCallDepth() logr.LogSink {
if sink, ok := l.sink.(logr.CallDepthLogSink); ok {
return sink.WithCallDepth(2)
}
return l.sink
}
func (l *slogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
if l.sink == nil || len(attrs) == 0 {
return l
}
copy := *l
if l.slogSink != nil {
copy.slogSink = l.slogSink.WithAttrs(attrs)
copy.sink = copy.slogSink
} else {
kvList := make([]any, 0, 2*len(attrs))
for _, attr := range attrs {
if attr.Key != "" {
kvList = append(kvList, l.addGroupPrefix(attr.Key), attr.Value.Resolve().Any())
}
}
copy.sink = l.sink.WithValues(kvList...)
}
return &copy
}
func (l *slogHandler) WithGroup(name string) slog.Handler {
if l.sink == nil {
return l
}
copy := *l
if l.slogSink != nil {
copy.slogSink = l.slogSink.WithGroup(name)
copy.sink = l.slogSink
} else {
copy.groupPrefix = copy.addGroupPrefix(name)
}
return &copy
}
func (l *slogHandler) addGroupPrefix(name string) string {
if l.groupPrefix == "" {
return name
}
return l.groupPrefix + groupSeparator + name
}
// levelFromSlog adjusts the level by the logger's verbosity and negates it.
// It ensures that the result is >= 0. This is necessary because the result is
// passed to a logr.LogSink and that API did not historically document whether
// levels could be negative or what that meant.
//
// Some example usage:
// logrV0 := getMyLogger()
// logrV2 := logrV0.V(2)
// slogV2 := slog.New(slogr.NewSlogHandler(logrV2))
// slogV2.Debug("msg") // =~ logrV2.V(4) =~ logrV0.V(6)
// slogV2.Info("msg") // =~ logrV2.V(0) =~ logrV0.V(2)
// slogv2.Warn("msg") // =~ logrV2.V(-4) =~ logrV0.V(0)
func (l *slogHandler) levelFromSlog(level slog.Level) int {
result := -level
result += l.levelBias // in case the original logr.Logger had a V level
if result < 0 {
result = 0 // because logr.LogSink doesn't expect negative V levels
}
return int(result)
}

108
vendor/github.com/go-logr/logr/slogr/slogr.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
//go:build go1.21
// +build go1.21
/*
Copyright 2023 The logr 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 slogr enables usage of a slog.Handler with logr.Logger as front-end
// API and of a logr.LogSink through the slog.Handler and thus slog.Logger
// APIs.
//
// See the README in the top-level [./logr] package for a discussion of
// interoperability.
package slogr
import (
"context"
"log/slog"
"github.com/go-logr/logr"
)
// NewLogr returns a logr.Logger which writes to the slog.Handler.
//
// The logr verbosity level is mapped to slog levels such that V(0) becomes
// slog.LevelInfo and V(4) becomes slog.LevelDebug.
func NewLogr(handler slog.Handler) logr.Logger {
if handler, ok := handler.(*slogHandler); ok {
if handler.sink == nil {
return logr.Discard()
}
return logr.New(handler.sink).V(int(handler.levelBias))
}
return logr.New(&slogSink{handler: handler})
}
// NewSlogHandler returns a slog.Handler which writes to the same sink as the logr.Logger.
//
// The returned logger writes all records with level >= slog.LevelError as
// error log entries with LogSink.Error, regardless of the verbosity level of
// the logr.Logger:
//
// logger := <some logr.Logger with 0 as verbosity level>
// slog.New(NewSlogHandler(logger.V(10))).Error(...) -> logSink.Error(...)
//
// The level of all other records gets reduced by the verbosity
// level of the logr.Logger and the result is negated. If it happens
// to be negative, then it gets replaced by zero because a LogSink
// is not expected to handled negative levels:
//
// slog.New(NewSlogHandler(logger)).Debug(...) -> logger.GetSink().Info(level=4, ...)
// slog.New(NewSlogHandler(logger)).Warning(...) -> logger.GetSink().Info(level=0, ...)
// slog.New(NewSlogHandler(logger)).Info(...) -> logger.GetSink().Info(level=0, ...)
// slog.New(NewSlogHandler(logger.V(4))).Info(...) -> logger.GetSink().Info(level=4, ...)
func NewSlogHandler(logger logr.Logger) slog.Handler {
if sink, ok := logger.GetSink().(*slogSink); ok && logger.GetV() == 0 {
return sink.handler
}
handler := &slogHandler{sink: logger.GetSink(), levelBias: slog.Level(logger.GetV())}
if slogSink, ok := handler.sink.(SlogSink); ok {
handler.slogSink = slogSink
}
return handler
}
// SlogSink is an optional interface that a LogSink can implement to support
// logging through the slog.Logger or slog.Handler APIs better. It then should
// also support special slog values like slog.Group. When used as a
// slog.Handler, the advantages are:
//
// - stack unwinding gets avoided in favor of logging the pre-recorded PC,
// as intended by slog
// - proper grouping of key/value pairs via WithGroup
// - verbosity levels > slog.LevelInfo can be recorded
// - less overhead
//
// Both APIs (logr.Logger and slog.Logger/Handler) then are supported equally
// well. Developers can pick whatever API suits them better and/or mix
// packages which use either API in the same binary with a common logging
// implementation.
//
// This interface is necessary because the type implementing the LogSink
// interface cannot also implement the slog.Handler interface due to the
// different prototype of the common Enabled method.
//
// An implementation could support both interfaces in two different types, but then
// additional interfaces would be needed to convert between those types in NewLogr
// and NewSlogHandler.
type SlogSink interface {
logr.LogSink
Handle(ctx context.Context, record slog.Record) error
WithAttrs(attrs []slog.Attr) SlogSink
WithGroup(name string) SlogSink
}

122
vendor/github.com/go-logr/logr/slogr/slogsink.go generated vendored Normal file
View File

@@ -0,0 +1,122 @@
//go:build go1.21
// +build go1.21
/*
Copyright 2023 The logr 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 slogr
import (
"context"
"log/slog"
"runtime"
"time"
"github.com/go-logr/logr"
)
var (
_ logr.LogSink = &slogSink{}
_ logr.CallDepthLogSink = &slogSink{}
_ Underlier = &slogSink{}
)
// Underlier is implemented by the LogSink returned by NewLogr.
type Underlier interface {
// GetUnderlying returns the Handler used by the LogSink.
GetUnderlying() slog.Handler
}
const (
// nameKey is used to log the `WithName` values as an additional attribute.
nameKey = "logger"
// errKey is used to log the error parameter of Error as an additional attribute.
errKey = "err"
)
type slogSink struct {
callDepth int
name string
handler slog.Handler
}
func (l *slogSink) Init(info logr.RuntimeInfo) {
l.callDepth = info.CallDepth
}
func (l *slogSink) GetUnderlying() slog.Handler {
return l.handler
}
func (l *slogSink) WithCallDepth(depth int) logr.LogSink {
newLogger := *l
newLogger.callDepth += depth
return &newLogger
}
func (l *slogSink) Enabled(level int) bool {
return l.handler.Enabled(context.Background(), slog.Level(-level))
}
func (l *slogSink) Info(level int, msg string, kvList ...interface{}) {
l.log(nil, msg, slog.Level(-level), kvList...)
}
func (l *slogSink) Error(err error, msg string, kvList ...interface{}) {
l.log(err, msg, slog.LevelError, kvList...)
}
func (l *slogSink) log(err error, msg string, level slog.Level, kvList ...interface{}) {
var pcs [1]uintptr
// skip runtime.Callers, this function, Info/Error, and all helper functions above that.
runtime.Callers(3+l.callDepth, pcs[:])
record := slog.NewRecord(time.Now(), level, msg, pcs[0])
if l.name != "" {
record.AddAttrs(slog.String(nameKey, l.name))
}
if err != nil {
record.AddAttrs(slog.Any(errKey, err))
}
record.Add(kvList...)
l.handler.Handle(context.Background(), record)
}
func (l slogSink) WithName(name string) logr.LogSink {
if l.name != "" {
l.name = l.name + "/"
}
l.name += name
return &l
}
func (l slogSink) WithValues(kvList ...interface{}) logr.LogSink {
l.handler = l.handler.WithAttrs(kvListToAttrs(kvList...))
return &l
}
func kvListToAttrs(kvList ...interface{}) []slog.Attr {
// We don't need the record itself, only its Add method.
record := slog.NewRecord(time.Time{}, 0, "", 0)
record.Add(kvList...)
attrs := make([]slog.Attr, 0, record.NumAttrs())
record.Attrs(func(attr slog.Attr) bool {
attrs = append(attrs, attr)
return true
})
return attrs
}

View File

@@ -1,15 +0,0 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
- 1.14.x
- 1.15.x
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
env:
- GO111MODULE=on
language: go
notifications:
slack:
secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw=
script:
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...

View File

@@ -1,8 +1,6 @@
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0
gocyclo:
min-complexity: 30
maligned:
@@ -12,6 +10,8 @@ linters-settings:
goconst:
min-len: 2
min-occurrences: 4
paralleltest:
ignore-missing: true
linters:
enable-all: true
disable:
@@ -39,3 +39,12 @@ linters:
- nestif
- godot
- errorlint
- varcheck
- interfacer
- deadcode
- golint
- ifshort
- structcheck
- nosnakecase
- varnamelen
- exhaustruct

View File

@@ -1,24 +0,0 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
- 1.14.x
- 1.x
install:
- go get gotest.tools/gotestsum
jobs:
include:
# include linting job, but only for latest go version and amd64 arch
- go: 1.x
arch: amd64
install:
go get github.com/golangci/golangci-lint/cmd/golangci-lint
script:
- golangci-lint run --new-from-rev master
env:
- GO111MODULE=on
language: go
notifications:
slack:
secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ=
script:
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...

View File

@@ -7,8 +7,8 @@ import (
)
const (
defaultHttpPort = ":80"
defaultHttpsPort = ":443"
defaultHTTPPort = ":80"
defaultHTTPSPort = ":443"
)
// Regular expressions used by the normalizations
@@ -18,18 +18,24 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
// NormalizeURL will normalize the specified URL
// This was added to replace a previous call to the no longer maintained purell library:
// The call that was used looked like the following:
// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
//
// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
//
// To explain all that was included in the call above, purell.FlagsSafe was really just the following:
// - FlagLowercaseScheme
// - FlagLowercaseHost
// - FlagRemoveDefaultPort
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
// - FlagLowercaseScheme
// - FlagLowercaseHost
// - FlagRemoveDefaultPort
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
//
// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
func NormalizeURL(u *url.URL) {
lowercaseScheme(u)
lowercaseHost(u)
removeDefaultPort(u)
removeDuplicateSlashes(u)
u.RawPath = ""
u.RawFragment = ""
}
func lowercaseScheme(u *url.URL) {
@@ -48,7 +54,7 @@ func removeDefaultPort(u *url.URL) {
if len(u.Host) > 0 {
scheme := strings.ToLower(u.Scheme)
u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) {
if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) {
return ""
}
return val

2
vendor/github.com/go-openapi/swag/.gitattributes generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# gofmt always uses LF, whereas Git uses CRLF on Windows.
*.go text eol=lf

View File

@@ -37,3 +37,18 @@ linters:
- gci
- gocognit
- paralleltest
- thelper
- ifshort
- gomoddirectives
- cyclop
- forcetypeassert
- ireturn
- tagliatelle
- varnamelen
- goimports
- tenv
- golint
- exhaustruct
- nilnil
- nonamedreturns
- nosnakecase

View File

@@ -1,37 +0,0 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
- 1.14.x
- 1.x
arch:
- amd64
jobs:
include:
# include arch ppc, but only for latest go version - skip testing for race
- go: 1.x
arch: ppc64le
install: ~
script:
- go test -v
#- go: 1.x
# arch: arm
# install: ~
# script:
# - go test -v
# include linting job, but only for latest go version and amd64 arch
- go: 1.x
arch: amd64
install:
go get github.com/golangci/golangci-lint/cmd/golangci-lint
script:
- golangci-lint run --new-from-rev master
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
language: go
notifications:
slack:
secure: QUWvCkBBK09GF7YtEvHHVt70JOkdlNBG0nIKu/5qc4/nW5HP8I2w0SEf/XR2je0eED1Qe3L/AfMCWwrEj+IUZc3l4v+ju8X8R3Lomhme0Eb0jd1MTMCuPcBT47YCj0M7RON7vXtbFfm1hFJ/jLe5+9FXz0hpXsR24PJc5ZIi/ogNwkaPqG4BmndzecpSh0vc2FJPZUD9LT0I09REY/vXR0oQAalLkW0asGD5taHZTUZq/kBpsNxaAFrLM23i4mUcf33M5fjLpvx5LRICrX/57XpBrDh2TooBU6Qj3CgoY0uPRYUmSNxbVx1czNzl2JtEpb5yjoxfVPQeg0BvQM00G8LJINISR+ohrjhkZmAqchDupAX+yFrxTtORa78CtnIL6z/aTNlgwwVD8kvL/1pFA/JWYmKDmz93mV/+6wubGzNSQCstzjkFA4/iZEKewKUoRIAi/fxyscP6L/rCpmY/4llZZvrnyTqVbt6URWpopUpH4rwYqreXAtJxJsfBJIeSmUIiDIOMGkCTvyTEW3fWGmGoqWtSHLoaWDyAIGb7azb+KvfpWtEcoPFWfSWU+LGee0A/YsUhBl7ADB9A0CJEuR8q4BPpKpfLwPKSiKSAXL7zDkyjExyhtgqbSl2jS+rKIHOZNL8JkCcTP2MKMVd563C5rC5FMKqu3S9m2b6380E=
script:
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...

View File

@@ -17,16 +17,15 @@ Package swag contains a bunch of helper functions for go-openapi and go-swagger
You may also use it standalone for your projects.
* convert between value and pointers for builtin types
* convert from string to builtin types (wraps strconv)
* fast json concatenation
* search in path
* load from file or http
* name mangling
- convert between value and pointers for builtin types
- convert from string to builtin types (wraps strconv)
- fast json concatenation
- search in path
- load from file or http
- name mangling
This repo has only few dependencies outside of the standard library:
* YAML utilities depend on gopkg.in/yaml.v2
- YAML utilities depend on gopkg.in/yaml.v2
*/
package swag

33
vendor/github.com/go-openapi/swag/file.go generated vendored Normal file
View File

@@ -0,0 +1,33 @@
// Copyright 2015 go-swagger maintainers
//
// 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 swag
import "mime/multipart"
// File represents an uploaded file.
type File struct {
Data multipart.File
Header *multipart.FileHeader
}
// Read bytes from the file
func (f *File) Read(p []byte) (n int, err error) {
return f.Data.Read(p)
}
// Close the file
func (f *File) Close() error {
return f.Data.Close()
}

View File

@@ -16,10 +16,11 @@ package swag
import (
"fmt"
"io/ioutil"
"io"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
@@ -40,13 +41,13 @@ var LoadHTTPCustomHeaders = map[string]string{}
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
func LoadFromFileOrHTTP(path string) ([]byte, error) {
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
}
// LoadFromFileOrHTTPWithTimeout loads the bytes from a file or a remote http server based on the path passed in
// timeout arg allows for per request overriding of the request timeout
func LoadFromFileOrHTTPWithTimeout(path string, timeout time.Duration) ([]byte, error) {
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(timeout))(path)
return LoadStrategy(path, os.ReadFile, loadHTTPBytes(timeout))(path)
}
// LoadStrategy returns a loader function for a given path or uri
@@ -86,7 +87,7 @@ func LoadStrategy(path string, local, remote func(string) ([]byte, error)) func(
func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
return func(path string) ([]byte, error) {
client := &http.Client{Timeout: timeout}
req, err := http.NewRequest("GET", path, nil) // nolint: noctx
req, err := http.NewRequest(http.MethodGet, path, nil) //nolint:noctx
if err != nil {
return nil, err
}
@@ -115,6 +116,6 @@ func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
return nil, fmt.Errorf("could not access document at %q [%s] ", path, resp.Status)
}
return ioutil.ReadAll(resp.Body)
return io.ReadAll(resp.Body)
}
}

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build go1.8
// +build go1.8
package swag

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build go1.9
// +build go1.9
package swag

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !go1.8
// +build !go1.8
package swag

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !go1.9
// +build !go1.9
package swag

View File

@@ -99,10 +99,11 @@ const (
)
// JoinByFormat joins a string array by a known format (e.g. swagger's collectionFormat attribute):
// ssv: space separated value
// tsv: tab separated value
// pipes: pipe (|) separated value
// csv: comma separated value (default)
//
// ssv: space separated value
// tsv: tab separated value
// pipes: pipe (|) separated value
// csv: comma separated value (default)
func JoinByFormat(data []string, format string) []string {
if len(data) == 0 {
return data
@@ -124,11 +125,11 @@ func JoinByFormat(data []string, format string) []string {
}
// SplitByFormat splits a string by a known format:
// ssv: space separated value
// tsv: tab separated value
// pipes: pipe (|) separated value
// csv: comma separated value (default)
//
// ssv: space separated value
// tsv: tab separated value
// pipes: pipe (|) separated value
// csv: comma separated value (default)
func SplitByFormat(data, format string) []string {
if data == "" {
return nil

View File

@@ -22,7 +22,7 @@ import (
"github.com/mailru/easyjson/jlexer"
"github.com/mailru/easyjson/jwriter"
yaml "gopkg.in/yaml.v2"
yaml "gopkg.in/yaml.v3"
)
// YAMLMatcher matches yaml
@@ -43,16 +43,126 @@ func YAMLToJSON(data interface{}) (json.RawMessage, error) {
// BytesToYAMLDoc converts a byte slice into a YAML document
func BytesToYAMLDoc(data []byte) (interface{}, error) {
var canary map[interface{}]interface{} // validate this is an object and not a different type
if err := yaml.Unmarshal(data, &canary); err != nil {
return nil, err
}
var document yaml.MapSlice // preserve order that is present in the document
var document yaml.Node // preserve order that is present in the document
if err := yaml.Unmarshal(data, &document); err != nil {
return nil, err
}
return document, nil
if document.Kind != yaml.DocumentNode || len(document.Content) != 1 || document.Content[0].Kind != yaml.MappingNode {
return nil, fmt.Errorf("only YAML documents that are objects are supported")
}
return &document, nil
}
func yamlNode(root *yaml.Node) (interface{}, error) {
switch root.Kind {
case yaml.DocumentNode:
return yamlDocument(root)
case yaml.SequenceNode:
return yamlSequence(root)
case yaml.MappingNode:
return yamlMapping(root)
case yaml.ScalarNode:
return yamlScalar(root)
case yaml.AliasNode:
return yamlNode(root.Alias)
default:
return nil, fmt.Errorf("unsupported YAML node type: %v", root.Kind)
}
}
func yamlDocument(node *yaml.Node) (interface{}, error) {
if len(node.Content) != 1 {
return nil, fmt.Errorf("unexpected YAML Document node content length: %d", len(node.Content))
}
return yamlNode(node.Content[0])
}
func yamlMapping(node *yaml.Node) (interface{}, error) {
m := make(JSONMapSlice, len(node.Content)/2)
var j int
for i := 0; i < len(node.Content); i += 2 {
var nmi JSONMapItem
k, err := yamlStringScalarC(node.Content[i])
if err != nil {
return nil, fmt.Errorf("unable to decode YAML map key: %w", err)
}
nmi.Key = k
v, err := yamlNode(node.Content[i+1])
if err != nil {
return nil, fmt.Errorf("unable to process YAML map value for key %q: %w", k, err)
}
nmi.Value = v
m[j] = nmi
j++
}
return m, nil
}
func yamlSequence(node *yaml.Node) (interface{}, error) {
s := make([]interface{}, 0)
for i := 0; i < len(node.Content); i++ {
v, err := yamlNode(node.Content[i])
if err != nil {
return nil, fmt.Errorf("unable to decode YAML sequence value: %w", err)
}
s = append(s, v)
}
return s, nil
}
const ( // See https://yaml.org/type/
yamlStringScalar = "tag:yaml.org,2002:str"
yamlIntScalar = "tag:yaml.org,2002:int"
yamlBoolScalar = "tag:yaml.org,2002:bool"
yamlFloatScalar = "tag:yaml.org,2002:float"
yamlTimestamp = "tag:yaml.org,2002:timestamp"
yamlNull = "tag:yaml.org,2002:null"
)
func yamlScalar(node *yaml.Node) (interface{}, error) {
switch node.LongTag() {
case yamlStringScalar:
return node.Value, nil
case yamlBoolScalar:
b, err := strconv.ParseBool(node.Value)
if err != nil {
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting bool content: %w", node.Value, err)
}
return b, nil
case yamlIntScalar:
i, err := strconv.ParseInt(node.Value, 10, 64)
if err != nil {
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting integer content: %w", node.Value, err)
}
return i, nil
case yamlFloatScalar:
f, err := strconv.ParseFloat(node.Value, 64)
if err != nil {
return nil, fmt.Errorf("unable to process scalar node. Got %q. Expecting float content: %w", node.Value, err)
}
return f, nil
case yamlTimestamp:
return node.Value, nil
case yamlNull:
return nil, nil
default:
return nil, fmt.Errorf("YAML tag %q is not supported", node.LongTag())
}
}
func yamlStringScalarC(node *yaml.Node) (string, error) {
if node.Kind != yaml.ScalarNode {
return "", fmt.Errorf("expecting a string scalar but got %q", node.Kind)
}
switch node.LongTag() {
case yamlStringScalar, yamlIntScalar, yamlFloatScalar:
return node.Value, nil
default:
return "", fmt.Errorf("YAML tag %q is not supported as map key", node.LongTag())
}
}
// JSONMapSlice represent a JSON object, with the order of keys maintained
@@ -105,6 +215,113 @@ func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
*s = result
}
func (s JSONMapSlice) MarshalYAML() (interface{}, error) {
var n yaml.Node
n.Kind = yaml.DocumentNode
var nodes []*yaml.Node
for _, item := range s {
nn, err := json2yaml(item.Value)
if err != nil {
return nil, err
}
ns := []*yaml.Node{
{
Kind: yaml.ScalarNode,
Tag: yamlStringScalar,
Value: item.Key,
},
nn,
}
nodes = append(nodes, ns...)
}
n.Content = []*yaml.Node{
{
Kind: yaml.MappingNode,
Content: nodes,
},
}
return yaml.Marshal(&n)
}
func json2yaml(item interface{}) (*yaml.Node, error) {
switch val := item.(type) {
case JSONMapSlice:
var n yaml.Node
n.Kind = yaml.MappingNode
for i := range val {
childNode, err := json2yaml(&val[i].Value)
if err != nil {
return nil, err
}
n.Content = append(n.Content, &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlStringScalar,
Value: val[i].Key,
}, childNode)
}
return &n, nil
case map[string]interface{}:
var n yaml.Node
n.Kind = yaml.MappingNode
for k, v := range val {
childNode, err := json2yaml(v)
if err != nil {
return nil, err
}
n.Content = append(n.Content, &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlStringScalar,
Value: k,
}, childNode)
}
return &n, nil
case []interface{}:
var n yaml.Node
n.Kind = yaml.SequenceNode
for i := range val {
childNode, err := json2yaml(val[i])
if err != nil {
return nil, err
}
n.Content = append(n.Content, childNode)
}
return &n, nil
case string:
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlStringScalar,
Value: val,
}, nil
case float64:
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlFloatScalar,
Value: strconv.FormatFloat(val, 'f', -1, 64),
}, nil
case int64:
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlIntScalar,
Value: strconv.FormatInt(val, 10),
}, nil
case uint64:
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlIntScalar,
Value: strconv.FormatUint(val, 10),
}, nil
case bool:
return &yaml.Node{
Kind: yaml.ScalarNode,
Tag: yamlBoolScalar,
Value: strconv.FormatBool(val),
}, nil
}
return nil, nil
}
// JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
type JSONMapItem struct {
Key string
@@ -173,23 +390,10 @@ func transformData(input interface{}) (out interface{}, err error) {
}
switch in := input.(type) {
case yaml.MapSlice:
o := make(JSONMapSlice, len(in))
for i, mi := range in {
var nmi JSONMapItem
if nmi.Key, err = format(mi.Key); err != nil {
return nil, err
}
v, ert := transformData(mi.Value)
if ert != nil {
return nil, ert
}
nmi.Value = v
o[i] = nmi
}
return o, nil
case yaml.Node:
return yamlNode(&in)
case *yaml.Node:
return yamlNode(in)
case map[interface{}]interface{}:
o := make(JSONMapSlice, 0, len(in))
for ke, va := range in {

View File

@@ -24,7 +24,7 @@ import (
"github.com/golang/protobuf/ptypes/any"
yaml "gopkg.in/yaml.v3"
extensions "github.com/google/gnostic/extensions"
extensions "github.com/google/gnostic-models/extensions"
)
// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.

View File

@@ -22,7 +22,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/google/gnostic/jsonschema"
"github.com/google/gnostic-models/jsonschema"
)
// compiler helper functions, usually called from generated code

View File

@@ -14,8 +14,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.18.1
// protoc-gen-go v1.27.1
// protoc v3.19.3
// source: extensions/extension.proto
package gnostic_extension_v1

View File

@@ -1,3 +1,16 @@
// Copyright 2017 Google LLC. All Rights Reserved.
//
// 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.
// THIS FILE IS AUTOMATICALLY GENERATED.
@@ -81,4 +94,4 @@ YXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5
IiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg
fSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6
IHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1
c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}
c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}

View File

@@ -23,7 +23,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/google/gnostic/compiler"
"github.com/google/gnostic-models/compiler"
)
// Version returns the package name (and OpenAPI version).

View File

@@ -16,8 +16,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.18.1
// protoc-gen-go v1.27.1
// protoc v3.19.3
// source: openapiv2/OpenAPIv2.proto
package openapi_v2

View File

@@ -17,7 +17,7 @@ package openapi_v2
import (
"gopkg.in/yaml.v3"
"github.com/google/gnostic/compiler"
"github.com/google/gnostic-models/compiler"
)
// ParseDocument reads an OpenAPI v2 description from a YAML/JSON representation.

View File

@@ -23,7 +23,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/google/gnostic/compiler"
"github.com/google/gnostic-models/compiler"
)
// Version returns the package name (and OpenAPI version).

View File

@@ -16,8 +16,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.18.1
// protoc-gen-go v1.27.1
// protoc v3.19.3
// source: openapiv3/OpenAPIv3.proto
package openapi_v3

View File

@@ -17,7 +17,7 @@ package openapi_v3
import (
"gopkg.in/yaml.v3"
"github.com/google/gnostic/compiler"
"github.com/google/gnostic-models/compiler"
)
// ParseDocument reads an OpenAPI v3 description from a YAML/JSON representation.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,18 @@
# Changelog
## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16)
### Features
* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3))
### Bug Fixes
* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06))
* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6))
## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12)

View File

@@ -17,6 +17,12 @@ var (
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
Nil UUID // empty UUID, all zeros
// The Max UUID is special form of UUID that is specified to have all 128 bits set to 1.
Max = UUID{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}
)
// NewHash returns a new UUID derived from the hash of space concatenated with

Some files were not shown because too many files have changed in this diff Show More