Merge pull request #3108 from crazy-max/v0.23-cherry-picks-rc2

[v0.23] cherry-picks for v0.23.0-rc2
This commit is contained in:
CrazyMax 2025-04-11 20:02:58 +02:00 committed by GitHub
commit f58f0221e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 1113 additions and 1196 deletions

View File

@ -424,6 +424,14 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
fmt.Fprintln(dockerCli.Out(), string(dt)) fmt.Fprintln(dockerCli.Out(), string(dt))
} }
for _, name := range names {
if sp, ok := resp[name]; ok {
if v, ok := sp.ExporterResponse["frontend.result.inlinemessage"]; ok {
fmt.Fprintf(dockerCli.Out(), "\n# %s\n%s\n", name, v)
}
}
}
if exitCode != 0 { if exitCode != 0 {
os.Exit(exitCode) os.Exit(exitCode)
} }

View File

@ -404,6 +404,10 @@ func runBuild(ctx context.Context, dockerCli command.Cli, options buildOptions)
os.Exit(exitcode) os.Exit(exitcode)
} }
} }
if v, ok := resp.ExporterResponse["frontend.result.inlinemessage"]; ok {
fmt.Fprintf(dockerCli.Out(), "\n%s\n", v)
return nil
}
return nil return nil
} }

7
go.mod
View File

@ -6,7 +6,7 @@ require (
github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/semver/v3 v3.2.1
github.com/Microsoft/go-winio v0.6.2 github.com/Microsoft/go-winio v0.6.2
github.com/aws/aws-sdk-go-v2/config v1.27.27 github.com/aws/aws-sdk-go-v2/config v1.27.27
github.com/compose-spec/compose-go/v2 v2.4.9 github.com/compose-spec/compose-go/v2 v2.6.0
github.com/containerd/console v1.0.4 github.com/containerd/console v1.0.4
github.com/containerd/containerd/v2 v2.0.4 github.com/containerd/containerd/v2 v2.0.4
github.com/containerd/continuity v0.4.5 github.com/containerd/continuity v0.4.5
@ -29,7 +29,7 @@ require (
github.com/hashicorp/hcl/v2 v2.23.0 github.com/hashicorp/hcl/v2 v2.23.0
github.com/in-toto/in-toto-golang v0.5.0 github.com/in-toto/in-toto-golang v0.5.0
github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/hashstructure/v2 v2.0.2
github.com/moby/buildkit v0.21.0-rc1 github.com/moby/buildkit v0.21.0-rc2
github.com/moby/sys/mountinfo v0.7.2 github.com/moby/sys/mountinfo v0.7.2
github.com/moby/sys/signal v0.7.1 github.com/moby/sys/signal v0.7.1
github.com/morikuni/aec v1.0.0 github.com/morikuni/aec v1.0.0
@ -44,7 +44,7 @@ require (
github.com/spf13/cobra v1.9.1 github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6 github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/tonistiigi/fsutil v0.0.0-20250318190121-d73a4b3b8a7e github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4
github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117 github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117
github.com/zclconf/go-cty v1.16.0 github.com/zclconf/go-cty v1.16.0
@ -168,7 +168,6 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.31.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect
golang.org/x/crypto v0.37.0 // indirect golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
golang.org/x/net v0.39.0 // indirect golang.org/x/net v0.39.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/time v0.11.0 // indirect golang.org/x/time v0.11.0 // indirect

14
go.sum
View File

@ -70,8 +70,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= 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/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
github.com/compose-spec/compose-go/v2 v2.4.9 h1:2K4TDw+1ba2idiR6empXHKRXvWYpnvAKoNQy93/sSOs= github.com/compose-spec/compose-go/v2 v2.6.0 h1:/+oBD2ixSENOeN/TlJqWZmUak0xM8A7J08w/z661Wd4=
github.com/compose-spec/compose-go/v2 v2.4.9/go.mod h1:6k5l/0TxCg0/2uLEhRVEsoBWBprS2uvZi32J7xub3lo= github.com/compose-spec/compose-go/v2 v2.6.0/go.mod h1:vPlkN0i+0LjLf9rv52lodNMUTJF5YHVfHVGLLIP67NA=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
@ -279,8 +279,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/buildkit v0.21.0-rc1 h1:QWTyHpHUtsyUMH0CH7QStisI/FmS9njRC1FK4vVYeaE= github.com/moby/buildkit v0.21.0-rc2 h1:JxocuYzqoGLPzftFiDi/Afb85RbXWqt3ObEADRdFFE0=
github.com/moby/buildkit v0.21.0-rc1/go.mod h1:coiVDxJmP1PD+79HAnTJvBMetLTdCws8gpWiYX2vcH8= github.com/moby/buildkit v0.21.0-rc2/go.mod h1:mBq0D44uCyz2PdX8T/qym5LBbkBO3GGv0wqgX9ABYYw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@ -417,8 +417,8 @@ github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4D
github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4= github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4=
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY= github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
github.com/tonistiigi/fsutil v0.0.0-20250318190121-d73a4b3b8a7e h1:AiXT0JHwQA52AEOVMsxRytSI9mdJSie5gUp6OQ1R8fU= github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583 h1:mK+ZskNt7SG4dxfKIi27C7qHAQzyjAVt1iyTf0hmsNc=
github.com/tonistiigi/fsutil v0.0.0-20250318190121-d73a4b3b8a7e/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98= github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 h1:7I5c2Ig/5FgqkYOh/N87NzoyI9U15qUPXhDD8uCupv8= github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4 h1:7I5c2Ig/5FgqkYOh/N87NzoyI9U15qUPXhDD8uCupv8=
github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE= github.com/tonistiigi/go-csvvalue v0.0.0-20240710180619-ddb21b71c0b4/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117 h1:XFwyh2JZwR5aiKLXHX2C1n0v5F11dCJpyGL1W/Cpl3U= github.com/tonistiigi/jaeger-ui-rest v0.0.0-20250408171107-3dd17559e117 h1:XFwyh2JZwR5aiKLXHX2C1n0v5F11dCJpyGL1W/Cpl3U=
@ -492,8 +492,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=

View File

@ -35,7 +35,7 @@ func GetEnvFromFile(currentEnv map[string]string, filenames []string) (map[strin
s, err := os.Stat(dotEnvFile) s, err := os.Stat(dotEnvFile)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return envMap, fmt.Errorf("Couldn't find env file: %s", dotEnvFile) return envMap, fmt.Errorf("couldn't find env file: %s", dotEnvFile)
} }
if err != nil { if err != nil {
return envMap, err return envMap, err
@ -50,7 +50,7 @@ func GetEnvFromFile(currentEnv map[string]string, filenames []string) (map[strin
b, err := os.ReadFile(dotEnvFile) b, err := os.ReadFile(dotEnvFile)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, fmt.Errorf("Couldn't read env file: %s", dotEnvFile) return nil, fmt.Errorf("couldn't read env file: %s", dotEnvFile)
} }
if err != nil { if err != nil {
return envMap, err return envMap, err

View File

@ -24,28 +24,28 @@ import (
const DotEnv = ".env" const DotEnv = ".env"
var formats = map[string]Parser{ var formats = map[string]Parser{
DotEnv: func(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error) { DotEnv: func(r io.Reader, filename string, vars map[string]string, lookup func(key string) (string, bool)) error {
m, err := ParseWithLookup(r, lookup) err := parseWithLookup(r, vars, lookup)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read %s: %w", filename, err) return fmt.Errorf("failed to read %s: %w", filename, err)
} }
return m, nil return nil
}, },
} }
type Parser func(r io.Reader, filename string, lookup func(key string) (string, bool)) (map[string]string, error) type Parser func(r io.Reader, filename string, vars map[string]string, lookup func(key string) (string, bool)) error
func RegisterFormat(format string, p Parser) { func RegisterFormat(format string, p Parser) {
formats[format] = p formats[format] = p
} }
func ParseWithFormat(r io.Reader, filename string, resolve LookupFn, format string) (map[string]string, error) { func ParseWithFormat(r io.Reader, filename string, vars map[string]string, resolve LookupFn, format string) error {
if format == "" { if format == "" {
format = DotEnv format = DotEnv
} }
fn, ok := formats[format] fn, ok := formats[format]
if !ok { if !ok {
return nil, fmt.Errorf("unsupported env_file format %q", format) return fmt.Errorf("unsupported env_file format %q", format)
} }
return fn(r, filename, resolve) return fn(r, filename, vars, resolve)
} }

View File

@ -41,16 +41,23 @@ func Parse(r io.Reader) (map[string]string, error) {
// ParseWithLookup reads an env file from io.Reader, returning a map of keys and values. // ParseWithLookup reads an env file from io.Reader, returning a map of keys and values.
func ParseWithLookup(r io.Reader, lookupFn LookupFn) (map[string]string, error) { func ParseWithLookup(r io.Reader, lookupFn LookupFn) (map[string]string, error) {
vars := map[string]string{}
err := parseWithLookup(r, vars, lookupFn)
return vars, err
}
// ParseWithLookup reads an env file from io.Reader, returning a map of keys and values.
func parseWithLookup(r io.Reader, vars map[string]string, lookupFn LookupFn) error {
data, err := io.ReadAll(r) data, err := io.ReadAll(r)
if err != nil { if err != nil {
return nil, err return err
} }
// seek past the UTF-8 BOM if it exists (particularly on Windows, some // seek past the UTF-8 BOM if it exists (particularly on Windows, some
// editors tend to add it, and it'll cause parsing to fail) // editors tend to add it, and it'll cause parsing to fail)
data = bytes.TrimPrefix(data, utf8BOM) data = bytes.TrimPrefix(data, utf8BOM)
return UnmarshalBytesWithLookup(data, lookupFn) return newParser().parse(string(data), vars, lookupFn)
} }
// Load will read your env file(s) and load them into ENV for this process. // Load will read your env file(s) and load them into ENV for this process.

View File

@ -18,11 +18,11 @@ package graph
import ( import (
"fmt" "fmt"
"slices"
"strings" "strings"
"github.com/compose-spec/compose-go/v2/types" "github.com/compose-spec/compose-go/v2/types"
"github.com/compose-spec/compose-go/v2/utils" "github.com/compose-spec/compose-go/v2/utils"
"golang.org/x/exp/slices"
) )
// CheckCycle analyze project's depends_on relation and report an error on cycle detection // CheckCycle analyze project's depends_on relation and report an error on cycle detection

View File

@ -18,9 +18,9 @@ package graph
import ( import (
"context" "context"
"slices"
"sync" "sync"
"golang.org/x/exp/slices"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )

View File

@ -26,6 +26,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"slices"
"strconv" "strconv"
"strings" "strings"
@ -42,7 +43,6 @@ import (
"github.com/compose-spec/compose-go/v2/validation" "github.com/compose-spec/compose-go/v2/validation"
"github.com/go-viper/mapstructure/v2" "github.com/go-viper/mapstructure/v2"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -337,7 +337,7 @@ func LoadModelWithContext(ctx context.Context, configDetails types.ConfigDetails
// LoadModelWithContext reads a ConfigDetails and returns a fully loaded configuration as a yaml dictionary // LoadModelWithContext reads a ConfigDetails and returns a fully loaded configuration as a yaml dictionary
func loadModelWithContext(ctx context.Context, configDetails *types.ConfigDetails, opts *Options) (map[string]any, error) { func loadModelWithContext(ctx context.Context, configDetails *types.ConfigDetails, opts *Options) (map[string]any, error) {
if len(configDetails.ConfigFiles) < 1 { if len(configDetails.ConfigFiles) < 1 {
return nil, errors.New("No files specified") return nil, errors.New("no compose file specified")
} }
err := projectName(configDetails, opts) err := projectName(configDetails, opts)
@ -432,7 +432,7 @@ func loadYamlFile(ctx context.Context,
} }
cfg, ok := converted.(map[string]interface{}) cfg, ok := converted.(map[string]interface{})
if !ok { if !ok {
return errors.New("Top-level object must be a mapping") return errors.New("top-level object must be a mapping")
} }
if opts.Interpolate != nil && !opts.SkipInterpolation { if opts.Interpolate != nil && !opts.SkipInterpolation {
@ -877,7 +877,7 @@ func formatInvalidKeyError(keyPrefix string, key interface{}) error {
} else { } else {
location = fmt.Sprintf("in %s", keyPrefix) location = fmt.Sprintf("in %s", keyPrefix)
} }
return fmt.Errorf("Non-string key %s: %#v", location, key) return fmt.Errorf("non-string key %s: %#v", location, key)
} }
// Windows path, c:\\my\\path\\shiny, need to be changed to be compatible with // Windows path, c:\\my\\path\\shiny, need to be changed to be compatible with

View File

@ -67,6 +67,8 @@ func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.No
p.paths = append(p.paths, path) p.paths = append(p.paths, path)
return node, nil return node, nil
} }
keys := map[string]int{}
switch node.Kind { switch node.Kind {
case yaml.SequenceNode: case yaml.SequenceNode:
var nodes []*yaml.Node var nodes []*yaml.Node
@ -87,6 +89,10 @@ func (p *ResetProcessor) resolveReset(node *yaml.Node, path tree.Path) (*yaml.No
for idx, v := range node.Content { for idx, v := range node.Content {
if idx%2 == 0 { if idx%2 == 0 {
key = v.Value key = v.Value
if line, seen := keys[key]; seen {
return nil, fmt.Errorf("line %d: mapping key %#v already defined at line %d", v.Line, key, line)
}
keys[key] = v.Line
} else { } else {
resolved, err := p.resolveReset(v, path.Next(key)) resolved, err := p.resolveReset(v, path.Next(key))
if err != nil { if err != nil {

View File

@ -29,7 +29,7 @@ import (
// checkConsistency validate a compose model is consistent // checkConsistency validate a compose model is consistent
func checkConsistency(project *types.Project) error { //nolint:gocyclo func checkConsistency(project *types.Project) error { //nolint:gocyclo
for name, s := range project.Services { for name, s := range project.Services {
if s.Build == nil && s.Image == "" { if s.Build == nil && s.Image == "" && s.Provider == nil {
return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid) return fmt.Errorf("service %q has neither an image nor a build context specified: %w", s.Name, errdefs.ErrInvalid)
} }

View File

@ -19,10 +19,9 @@ package override
import ( import (
"cmp" "cmp"
"fmt" "fmt"
"strings" "slices"
"github.com/compose-spec/compose-go/v2/tree" "github.com/compose-spec/compose-go/v2/tree"
"golang.org/x/exp/slices"
) )
// Merge applies overrides to a config model // Merge applies overrides to a config model
@ -62,6 +61,7 @@ func init() {
mergeSpecials["services.*.extra_hosts"] = mergeExtraHosts mergeSpecials["services.*.extra_hosts"] = mergeExtraHosts
mergeSpecials["services.*.healthcheck.test"] = override mergeSpecials["services.*.healthcheck.test"] = override
mergeSpecials["services.*.labels"] = mergeToSequence mergeSpecials["services.*.labels"] = mergeToSequence
mergeSpecials["services.*.volumes.*.volume.labels"] = mergeToSequence
mergeSpecials["services.*.logging"] = mergeLogging mergeSpecials["services.*.logging"] = mergeLogging
mergeSpecials["services.*.networks"] = mergeNetworks mergeSpecials["services.*.networks"] = mergeNetworks
mergeSpecials["services.*.sysctls"] = mergeToSequence mergeSpecials["services.*.sysctls"] = mergeToSequence
@ -104,7 +104,7 @@ func mergeYaml(e any, o any, p tree.Path) (any, error) {
func mergeMappings(mapping map[string]any, other map[string]any, p tree.Path) (map[string]any, error) { func mergeMappings(mapping map[string]any, other map[string]any, p tree.Path) (map[string]any, error) {
for k, v := range other { for k, v := range other {
e, ok := mapping[k] e, ok := mapping[k]
if !ok || strings.HasPrefix(k, "x-") { if !ok {
mapping[k] = v mapping[k] = v
continue continue
} }
@ -227,9 +227,17 @@ func mergeUlimit(_ any, o any, p tree.Path) (any, error) {
func mergeIPAMConfig(c any, o any, path tree.Path) (any, error) { func mergeIPAMConfig(c any, o any, path tree.Path) (any, error) {
var ipamConfigs []any var ipamConfigs []any
for _, original := range c.([]any) { configs, ok := c.([]any)
if !ok {
return o, fmt.Errorf("%s: unexpected type %T", path, c)
}
overrides, ok := o.([]any)
if !ok {
return o, fmt.Errorf("%s: unexpected type %T", path, c)
}
for _, original := range configs {
right := convertIntoMapping(original, nil) right := convertIntoMapping(original, nil)
for _, override := range o.([]any) { for _, override := range overrides {
left := convertIntoMapping(override, nil) left := convertIntoMapping(override, nil)
if left["subnet"] != right["subnet"] { if left["subnet"] != right["subnet"] {
// check if left is already in ipamConfigs, add it if not and continue with the next config // check if left is already in ipamConfigs, add it if not and continue with the next config

View File

@ -259,6 +259,20 @@
} }
] ]
}, },
"provider": {
"type": "object",
"properties": {
"type": {"type": "string"},
"options": {
"type": "object",
"patternProperties": {
"^.+$": {"type": ["string", "number", "null"]}
}
}
},
"additionalProperties": false,
"patternProperties": {"^x-": {}}
},
"external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "external_links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"extra_hosts": {"$ref": "#/definitions/extra_hosts"}, "extra_hosts": {"$ref": "#/definitions/extra_hosts"},
"gpus": {"$ref": "#/definitions/gpus"}, "gpus": {"$ref": "#/definitions/gpus"},
@ -279,7 +293,6 @@
"links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true}, "links": {"type": "array", "items": {"type": "string"}, "uniqueItems": true},
"logging": { "logging": {
"type": "object", "type": "object",
"properties": { "properties": {
"driver": {"type": "string"}, "driver": {"type": "string"},
"options": { "options": {
@ -405,7 +418,9 @@
"type": "object", "type": "object",
"required": ["type"], "required": ["type"],
"properties": { "properties": {
"type": {"type": "string"}, "type": {"type": "string",
"enum": ["bind", "volume", "tmpfs", "cluster", "image"]
},
"source": {"type": "string"}, "source": {"type": "string"},
"target": {"type": "string"}, "target": {"type": "string"},
"read_only": {"type": ["boolean", "string"]}, "read_only": {"type": ["boolean", "string"]},
@ -424,6 +439,7 @@
"volume": { "volume": {
"type": "object", "type": "object",
"properties": { "properties": {
"labels": {"$ref": "#/definitions/list_or_dict"},
"nocopy": {"type": ["boolean", "string"]}, "nocopy": {"type": ["boolean", "string"]},
"subpath": {"type": "string"} "subpath": {"type": "string"}
}, },
@ -443,6 +459,14 @@
}, },
"additionalProperties": false, "additionalProperties": false,
"patternProperties": {"^x-": {}} "patternProperties": {"^x-": {}}
},
"image": {
"type": "object",
"properties": {
"subpath": {"type": "string"}
},
"additionalProperties": false,
"patternProperties": {"^x-": {}}
} }
}, },
"additionalProperties": false, "additionalProperties": false,

View File

@ -355,9 +355,15 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} }
copy(dst.Entrypoint, src.Entrypoint) copy(dst.Entrypoint, src.Entrypoint)
} }
if src.Provider == nil {
dst.Provider = nil
} else {
dst.Provider = new(ServiceProviderConfig)
deriveDeepCopy_13(dst.Provider, src.Provider)
}
if src.Environment != nil { if src.Environment != nil {
dst.Environment = make(map[string]*string, len(src.Environment)) dst.Environment = make(map[string]*string, len(src.Environment))
deriveDeepCopy_13(dst.Environment, src.Environment) deriveDeepCopy_14(dst.Environment, src.Environment)
} else { } else {
dst.Environment = nil dst.Environment = nil
} }
@ -423,7 +429,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} }
if src.ExtraHosts != nil { if src.ExtraHosts != nil {
dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts)) dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts))
deriveDeepCopy_14(dst.ExtraHosts, src.ExtraHosts) deriveDeepCopy_15(dst.ExtraHosts, src.ExtraHosts)
} else { } else {
dst.ExtraHosts = nil dst.ExtraHosts = nil
} }
@ -461,14 +467,14 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.Gpus = make([]DeviceRequest, len(src.Gpus)) dst.Gpus = make([]DeviceRequest, len(src.Gpus))
} }
deriveDeepCopy_15(dst.Gpus, src.Gpus) deriveDeepCopy_16(dst.Gpus, src.Gpus)
} }
dst.Hostname = src.Hostname dst.Hostname = src.Hostname
if src.HealthCheck == nil { if src.HealthCheck == nil {
dst.HealthCheck = nil dst.HealthCheck = nil
} else { } else {
dst.HealthCheck = new(HealthCheckConfig) dst.HealthCheck = new(HealthCheckConfig)
deriveDeepCopy_16(dst.HealthCheck, src.HealthCheck) deriveDeepCopy_17(dst.HealthCheck, src.HealthCheck)
} }
dst.Image = src.Image dst.Image = src.Image
if src.Init == nil { if src.Init == nil {
@ -531,7 +537,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
dst.Logging = nil dst.Logging = nil
} else { } else {
dst.Logging = new(LoggingConfig) dst.Logging = new(LoggingConfig)
deriveDeepCopy_17(dst.Logging, src.Logging) deriveDeepCopy_18(dst.Logging, src.Logging)
} }
dst.LogDriver = src.LogDriver dst.LogDriver = src.LogDriver
if src.LogOpt != nil { if src.LogOpt != nil {
@ -549,7 +555,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
dst.NetworkMode = src.NetworkMode dst.NetworkMode = src.NetworkMode
if src.Networks != nil { if src.Networks != nil {
dst.Networks = make(map[string]*ServiceNetworkConfig, len(src.Networks)) dst.Networks = make(map[string]*ServiceNetworkConfig, len(src.Networks))
deriveDeepCopy_18(dst.Networks, src.Networks) deriveDeepCopy_19(dst.Networks, src.Networks)
} else { } else {
dst.Networks = nil dst.Networks = nil
} }
@ -574,7 +580,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.Ports = make([]ServicePortConfig, len(src.Ports)) dst.Ports = make([]ServicePortConfig, len(src.Ports))
} }
deriveDeepCopy_19(dst.Ports, src.Ports) deriveDeepCopy_20(dst.Ports, src.Ports)
} }
dst.Privileged = src.Privileged dst.Privileged = src.Privileged
dst.PullPolicy = src.PullPolicy dst.PullPolicy = src.PullPolicy
@ -603,7 +609,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets)) dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets))
} }
deriveDeepCopy_20(dst.Secrets, src.Secrets) deriveDeepCopy_21(dst.Secrets, src.Secrets)
} }
if src.SecurityOpt == nil { if src.SecurityOpt == nil {
dst.SecurityOpt = nil dst.SecurityOpt = nil
@ -665,7 +671,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
dst.Tty = src.Tty dst.Tty = src.Tty
if src.Ulimits != nil { if src.Ulimits != nil {
dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits)) dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits))
deriveDeepCopy_21(dst.Ulimits, src.Ulimits) deriveDeepCopy_22(dst.Ulimits, src.Ulimits)
} else { } else {
dst.Ulimits = nil dst.Ulimits = nil
} }
@ -689,7 +695,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.Volumes = make([]ServiceVolumeConfig, len(src.Volumes)) dst.Volumes = make([]ServiceVolumeConfig, len(src.Volumes))
} }
deriveDeepCopy_22(dst.Volumes, src.Volumes) deriveDeepCopy_23(dst.Volumes, src.Volumes)
} }
if src.VolumesFrom == nil { if src.VolumesFrom == nil {
dst.VolumesFrom = nil dst.VolumesFrom = nil
@ -726,7 +732,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.PostStart = make([]ServiceHook, len(src.PostStart)) dst.PostStart = make([]ServiceHook, len(src.PostStart))
} }
deriveDeepCopy_23(dst.PostStart, src.PostStart) deriveDeepCopy_24(dst.PostStart, src.PostStart)
} }
if src.PreStop == nil { if src.PreStop == nil {
dst.PreStop = nil dst.PreStop = nil
@ -744,7 +750,7 @@ func deriveDeepCopyService(dst, src *ServiceConfig) {
} else { } else {
dst.PreStop = make([]ServiceHook, len(src.PreStop)) dst.PreStop = make([]ServiceHook, len(src.PreStop))
} }
deriveDeepCopy_23(dst.PreStop, src.PreStop) deriveDeepCopy_24(dst.PreStop, src.PreStop)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -770,7 +776,7 @@ func deriveDeepCopy_(dst, src map[string]NetworkConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
func() { func() {
field := new(NetworkConfig) field := new(NetworkConfig)
deriveDeepCopy_24(field, &src_value) deriveDeepCopy_25(field, &src_value)
dst[src_key] = *field dst[src_key] = *field
}() }()
} }
@ -781,7 +787,7 @@ func deriveDeepCopy_1(dst, src map[string]VolumeConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
func() { func() {
field := new(VolumeConfig) field := new(VolumeConfig)
deriveDeepCopy_25(field, &src_value) deriveDeepCopy_26(field, &src_value)
dst[src_key] = *field dst[src_key] = *field
}() }()
} }
@ -792,7 +798,7 @@ func deriveDeepCopy_2(dst, src map[string]SecretConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
func() { func() {
field := new(SecretConfig) field := new(SecretConfig)
deriveDeepCopy_26(field, &src_value) deriveDeepCopy_27(field, &src_value)
dst[src_key] = *field dst[src_key] = *field
}() }()
} }
@ -803,7 +809,7 @@ func deriveDeepCopy_3(dst, src map[string]ConfigObjConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
func() { func() {
field := new(ConfigObjConfig) field := new(ConfigObjConfig)
deriveDeepCopy_27(field, &src_value) deriveDeepCopy_28(field, &src_value)
dst[src_key] = *field dst[src_key] = *field
}() }()
} }
@ -841,7 +847,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) {
} }
if src.Args != nil { if src.Args != nil {
dst.Args = make(map[string]*string, len(src.Args)) dst.Args = make(map[string]*string, len(src.Args))
deriveDeepCopy_13(dst.Args, src.Args) deriveDeepCopy_14(dst.Args, src.Args)
} else { } else {
dst.Args = nil dst.Args = nil
} }
@ -915,7 +921,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) {
dst.Pull = src.Pull dst.Pull = src.Pull
if src.ExtraHosts != nil { if src.ExtraHosts != nil {
dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts)) dst.ExtraHosts = make(map[string][]string, len(src.ExtraHosts))
deriveDeepCopy_14(dst.ExtraHosts, src.ExtraHosts) deriveDeepCopy_15(dst.ExtraHosts, src.ExtraHosts)
} else { } else {
dst.ExtraHosts = nil dst.ExtraHosts = nil
} }
@ -938,7 +944,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) {
} else { } else {
dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets)) dst.Secrets = make([]ServiceSecretConfig, len(src.Secrets))
} }
deriveDeepCopy_20(dst.Secrets, src.Secrets) deriveDeepCopy_21(dst.Secrets, src.Secrets)
} }
dst.ShmSize = src.ShmSize dst.ShmSize = src.ShmSize
if src.Tags == nil { if src.Tags == nil {
@ -961,7 +967,7 @@ func deriveDeepCopy_5(dst, src *BuildConfig) {
} }
if src.Ulimits != nil { if src.Ulimits != nil {
dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits)) dst.Ulimits = make(map[string]*UlimitsConfig, len(src.Ulimits))
deriveDeepCopy_21(dst.Ulimits, src.Ulimits) deriveDeepCopy_22(dst.Ulimits, src.Ulimits)
} else { } else {
dst.Ulimits = nil dst.Ulimits = nil
} }
@ -1010,7 +1016,7 @@ func deriveDeepCopy_6(dst, src *DevelopConfig) {
} else { } else {
dst.Watch = make([]Trigger, len(src.Watch)) dst.Watch = make([]Trigger, len(src.Watch))
} }
deriveDeepCopy_28(dst.Watch, src.Watch) deriveDeepCopy_29(dst.Watch, src.Watch)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -1039,7 +1045,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) {
} else { } else {
dst.WeightDevice = make([]WeightDevice, len(src.WeightDevice)) dst.WeightDevice = make([]WeightDevice, len(src.WeightDevice))
} }
deriveDeepCopy_29(dst.WeightDevice, src.WeightDevice) deriveDeepCopy_30(dst.WeightDevice, src.WeightDevice)
} }
if src.DeviceReadBps == nil { if src.DeviceReadBps == nil {
dst.DeviceReadBps = nil dst.DeviceReadBps = nil
@ -1057,7 +1063,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) {
} else { } else {
dst.DeviceReadBps = make([]ThrottleDevice, len(src.DeviceReadBps)) dst.DeviceReadBps = make([]ThrottleDevice, len(src.DeviceReadBps))
} }
deriveDeepCopy_30(dst.DeviceReadBps, src.DeviceReadBps) deriveDeepCopy_31(dst.DeviceReadBps, src.DeviceReadBps)
} }
if src.DeviceReadIOps == nil { if src.DeviceReadIOps == nil {
dst.DeviceReadIOps = nil dst.DeviceReadIOps = nil
@ -1075,7 +1081,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) {
} else { } else {
dst.DeviceReadIOps = make([]ThrottleDevice, len(src.DeviceReadIOps)) dst.DeviceReadIOps = make([]ThrottleDevice, len(src.DeviceReadIOps))
} }
deriveDeepCopy_30(dst.DeviceReadIOps, src.DeviceReadIOps) deriveDeepCopy_31(dst.DeviceReadIOps, src.DeviceReadIOps)
} }
if src.DeviceWriteBps == nil { if src.DeviceWriteBps == nil {
dst.DeviceWriteBps = nil dst.DeviceWriteBps = nil
@ -1093,7 +1099,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) {
} else { } else {
dst.DeviceWriteBps = make([]ThrottleDevice, len(src.DeviceWriteBps)) dst.DeviceWriteBps = make([]ThrottleDevice, len(src.DeviceWriteBps))
} }
deriveDeepCopy_30(dst.DeviceWriteBps, src.DeviceWriteBps) deriveDeepCopy_31(dst.DeviceWriteBps, src.DeviceWriteBps)
} }
if src.DeviceWriteIOps == nil { if src.DeviceWriteIOps == nil {
dst.DeviceWriteIOps = nil dst.DeviceWriteIOps = nil
@ -1111,7 +1117,7 @@ func deriveDeepCopy_7(dst, src *BlkioConfig) {
} else { } else {
dst.DeviceWriteIOps = make([]ThrottleDevice, len(src.DeviceWriteIOps)) dst.DeviceWriteIOps = make([]ThrottleDevice, len(src.DeviceWriteIOps))
} }
deriveDeepCopy_30(dst.DeviceWriteIOps, src.DeviceWriteIOps) deriveDeepCopy_31(dst.DeviceWriteIOps, src.DeviceWriteIOps)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -1126,7 +1132,7 @@ func deriveDeepCopy_8(dst, src []ServiceConfigObjConfig) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(ServiceConfigObjConfig) field := new(ServiceConfigObjConfig)
deriveDeepCopy_31(field, &src_value) deriveDeepCopy_32(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
} }
@ -1150,7 +1156,7 @@ func deriveDeepCopy_10(dst, src map[string]ServiceDependency) {
for src_key, src_value := range src { for src_key, src_value := range src {
func() { func() {
field := new(ServiceDependency) field := new(ServiceDependency)
deriveDeepCopy_32(field, &src_value) deriveDeepCopy_33(field, &src_value)
dst[src_key] = *field dst[src_key] = *field
}() }()
} }
@ -1175,28 +1181,28 @@ func deriveDeepCopy_11(dst, src *DeployConfig) {
dst.UpdateConfig = nil dst.UpdateConfig = nil
} else { } else {
dst.UpdateConfig = new(UpdateConfig) dst.UpdateConfig = new(UpdateConfig)
deriveDeepCopy_33(dst.UpdateConfig, src.UpdateConfig) deriveDeepCopy_34(dst.UpdateConfig, src.UpdateConfig)
} }
if src.RollbackConfig == nil { if src.RollbackConfig == nil {
dst.RollbackConfig = nil dst.RollbackConfig = nil
} else { } else {
dst.RollbackConfig = new(UpdateConfig) dst.RollbackConfig = new(UpdateConfig)
deriveDeepCopy_33(dst.RollbackConfig, src.RollbackConfig) deriveDeepCopy_34(dst.RollbackConfig, src.RollbackConfig)
} }
func() { func() {
field := new(Resources) field := new(Resources)
deriveDeepCopy_34(field, &src.Resources) deriveDeepCopy_35(field, &src.Resources)
dst.Resources = *field dst.Resources = *field
}() }()
if src.RestartPolicy == nil { if src.RestartPolicy == nil {
dst.RestartPolicy = nil dst.RestartPolicy = nil
} else { } else {
dst.RestartPolicy = new(RestartPolicy) dst.RestartPolicy = new(RestartPolicy)
deriveDeepCopy_35(dst.RestartPolicy, src.RestartPolicy) deriveDeepCopy_36(dst.RestartPolicy, src.RestartPolicy)
} }
func() { func() {
field := new(Placement) field := new(Placement)
deriveDeepCopy_36(field, &src.Placement) deriveDeepCopy_37(field, &src.Placement)
dst.Placement = *field dst.Placement = *field
}() }()
dst.EndpointMode = src.EndpointMode dst.EndpointMode = src.EndpointMode
@ -1213,14 +1219,31 @@ func deriveDeepCopy_12(dst, src []DeviceMapping) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(DeviceMapping) field := new(DeviceMapping)
deriveDeepCopy_37(field, &src_value) deriveDeepCopy_38(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
} }
} }
// deriveDeepCopy_13 recursively copies the contents of src into dst. // deriveDeepCopy_13 recursively copies the contents of src into dst.
func deriveDeepCopy_13(dst, src map[string]*string) { func deriveDeepCopy_13(dst, src *ServiceProviderConfig) {
dst.Type = src.Type
if src.Options != nil {
dst.Options = make(map[string]string, len(src.Options))
deriveDeepCopy_4(dst.Options, src.Options)
} else {
dst.Options = nil
}
if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions))
src.Extensions.DeepCopy(dst.Extensions)
} else {
dst.Extensions = nil
}
}
// deriveDeepCopy_14 recursively copies the contents of src into dst.
func deriveDeepCopy_14(dst, src map[string]*string) {
for src_key, src_value := range src { for src_key, src_value := range src {
if src_value == nil { if src_value == nil {
dst[src_key] = nil dst[src_key] = nil
@ -1234,8 +1257,8 @@ func deriveDeepCopy_13(dst, src map[string]*string) {
} }
} }
// deriveDeepCopy_14 recursively copies the contents of src into dst. // deriveDeepCopy_15 recursively copies the contents of src into dst.
func deriveDeepCopy_14(dst, src map[string][]string) { func deriveDeepCopy_15(dst, src map[string][]string) {
for src_key, src_value := range src { for src_key, src_value := range src {
if src_value == nil { if src_value == nil {
dst[src_key] = nil dst[src_key] = nil
@ -1261,19 +1284,19 @@ func deriveDeepCopy_14(dst, src map[string][]string) {
} }
} }
// deriveDeepCopy_15 recursively copies the contents of src into dst. // deriveDeepCopy_16 recursively copies the contents of src into dst.
func deriveDeepCopy_15(dst, src []DeviceRequest) { func deriveDeepCopy_16(dst, src []DeviceRequest) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(DeviceRequest) field := new(DeviceRequest)
deriveDeepCopy_38(field, &src_value) deriveDeepCopy_39(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
} }
} }
// deriveDeepCopy_16 recursively copies the contents of src into dst. // deriveDeepCopy_17 recursively copies the contents of src into dst.
func deriveDeepCopy_16(dst, src *HealthCheckConfig) { func deriveDeepCopy_17(dst, src *HealthCheckConfig) {
if src.Test == nil { if src.Test == nil {
dst.Test = nil dst.Test = nil
} else { } else {
@ -1331,8 +1354,8 @@ func deriveDeepCopy_16(dst, src *HealthCheckConfig) {
} }
} }
// deriveDeepCopy_17 recursively copies the contents of src into dst. // deriveDeepCopy_18 recursively copies the contents of src into dst.
func deriveDeepCopy_17(dst, src *LoggingConfig) { func deriveDeepCopy_18(dst, src *LoggingConfig) {
dst.Driver = src.Driver dst.Driver = src.Driver
if src.Options != nil { if src.Options != nil {
dst.Options = make(map[string]string, len(src.Options)) dst.Options = make(map[string]string, len(src.Options))
@ -1348,8 +1371,8 @@ func deriveDeepCopy_17(dst, src *LoggingConfig) {
} }
} }
// deriveDeepCopy_18 recursively copies the contents of src into dst. // deriveDeepCopy_19 recursively copies the contents of src into dst.
func deriveDeepCopy_18(dst, src map[string]*ServiceNetworkConfig) { func deriveDeepCopy_19(dst, src map[string]*ServiceNetworkConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
if src_value == nil { if src_value == nil {
dst[src_key] = nil dst[src_key] = nil
@ -1358,27 +1381,16 @@ func deriveDeepCopy_18(dst, src map[string]*ServiceNetworkConfig) {
dst[src_key] = nil dst[src_key] = nil
} else { } else {
dst[src_key] = new(ServiceNetworkConfig) dst[src_key] = new(ServiceNetworkConfig)
deriveDeepCopy_39(dst[src_key], src_value) deriveDeepCopy_40(dst[src_key], src_value)
} }
} }
} }
// deriveDeepCopy_19 recursively copies the contents of src into dst. // deriveDeepCopy_20 recursively copies the contents of src into dst.
func deriveDeepCopy_19(dst, src []ServicePortConfig) { func deriveDeepCopy_20(dst, src []ServicePortConfig) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(ServicePortConfig) field := new(ServicePortConfig)
deriveDeepCopy_40(field, &src_value)
dst[src_i] = *field
}()
}
}
// deriveDeepCopy_20 recursively copies the contents of src into dst.
func deriveDeepCopy_20(dst, src []ServiceSecretConfig) {
for src_i, src_value := range src {
func() {
field := new(ServiceSecretConfig)
deriveDeepCopy_41(field, &src_value) deriveDeepCopy_41(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
@ -1386,7 +1398,18 @@ func deriveDeepCopy_20(dst, src []ServiceSecretConfig) {
} }
// deriveDeepCopy_21 recursively copies the contents of src into dst. // deriveDeepCopy_21 recursively copies the contents of src into dst.
func deriveDeepCopy_21(dst, src map[string]*UlimitsConfig) { func deriveDeepCopy_21(dst, src []ServiceSecretConfig) {
for src_i, src_value := range src {
func() {
field := new(ServiceSecretConfig)
deriveDeepCopy_42(field, &src_value)
dst[src_i] = *field
}()
}
}
// deriveDeepCopy_22 recursively copies the contents of src into dst.
func deriveDeepCopy_22(dst, src map[string]*UlimitsConfig) {
for src_key, src_value := range src { for src_key, src_value := range src {
if src_value == nil { if src_value == nil {
dst[src_key] = nil dst[src_key] = nil
@ -1395,27 +1418,16 @@ func deriveDeepCopy_21(dst, src map[string]*UlimitsConfig) {
dst[src_key] = nil dst[src_key] = nil
} else { } else {
dst[src_key] = new(UlimitsConfig) dst[src_key] = new(UlimitsConfig)
deriveDeepCopy_42(dst[src_key], src_value) deriveDeepCopy_43(dst[src_key], src_value)
} }
} }
} }
// deriveDeepCopy_22 recursively copies the contents of src into dst. // deriveDeepCopy_23 recursively copies the contents of src into dst.
func deriveDeepCopy_22(dst, src []ServiceVolumeConfig) { func deriveDeepCopy_23(dst, src []ServiceVolumeConfig) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(ServiceVolumeConfig) field := new(ServiceVolumeConfig)
deriveDeepCopy_43(field, &src_value)
dst[src_i] = *field
}()
}
}
// deriveDeepCopy_23 recursively copies the contents of src into dst.
func deriveDeepCopy_23(dst, src []ServiceHook) {
for src_i, src_value := range src {
func() {
field := new(ServiceHook)
deriveDeepCopy_44(field, &src_value) deriveDeepCopy_44(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
@ -1423,7 +1435,18 @@ func deriveDeepCopy_23(dst, src []ServiceHook) {
} }
// deriveDeepCopy_24 recursively copies the contents of src into dst. // deriveDeepCopy_24 recursively copies the contents of src into dst.
func deriveDeepCopy_24(dst, src *NetworkConfig) { func deriveDeepCopy_24(dst, src []ServiceHook) {
for src_i, src_value := range src {
func() {
field := new(ServiceHook)
deriveDeepCopy_45(field, &src_value)
dst[src_i] = *field
}()
}
}
// deriveDeepCopy_25 recursively copies the contents of src into dst.
func deriveDeepCopy_25(dst, src *NetworkConfig) {
dst.Name = src.Name dst.Name = src.Name
dst.Driver = src.Driver dst.Driver = src.Driver
if src.DriverOpts != nil { if src.DriverOpts != nil {
@ -1434,7 +1457,7 @@ func deriveDeepCopy_24(dst, src *NetworkConfig) {
} }
func() { func() {
field := new(IPAMConfig) field := new(IPAMConfig)
deriveDeepCopy_45(field, &src.Ipam) deriveDeepCopy_46(field, &src.Ipam)
dst.Ipam = *field dst.Ipam = *field
}() }()
dst.External = src.External dst.External = src.External
@ -1472,8 +1495,8 @@ func deriveDeepCopy_24(dst, src *NetworkConfig) {
} }
} }
// deriveDeepCopy_25 recursively copies the contents of src into dst. // deriveDeepCopy_26 recursively copies the contents of src into dst.
func deriveDeepCopy_25(dst, src *VolumeConfig) { func deriveDeepCopy_26(dst, src *VolumeConfig) {
dst.Name = src.Name dst.Name = src.Name
dst.Driver = src.Driver dst.Driver = src.Driver
if src.DriverOpts != nil { if src.DriverOpts != nil {
@ -1503,38 +1526,8 @@ func deriveDeepCopy_25(dst, src *VolumeConfig) {
} }
} }
// deriveDeepCopy_26 recursively copies the contents of src into dst.
func deriveDeepCopy_26(dst, src *SecretConfig) {
dst.Name = src.Name
dst.File = src.File
dst.Environment = src.Environment
dst.Content = src.Content
dst.marshallContent = src.marshallContent
dst.External = src.External
if src.Labels != nil {
dst.Labels = make(map[string]string, len(src.Labels))
deriveDeepCopy_4(dst.Labels, src.Labels)
} else {
dst.Labels = nil
}
dst.Driver = src.Driver
if src.DriverOpts != nil {
dst.DriverOpts = make(map[string]string, len(src.DriverOpts))
deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts)
} else {
dst.DriverOpts = nil
}
dst.TemplateDriver = src.TemplateDriver
if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions))
src.Extensions.DeepCopy(dst.Extensions)
} else {
dst.Extensions = nil
}
}
// deriveDeepCopy_27 recursively copies the contents of src into dst. // deriveDeepCopy_27 recursively copies the contents of src into dst.
func deriveDeepCopy_27(dst, src *ConfigObjConfig) { func deriveDeepCopy_27(dst, src *SecretConfig) {
dst.Name = src.Name dst.Name = src.Name
dst.File = src.File dst.File = src.File
dst.Environment = src.Environment dst.Environment = src.Environment
@ -1564,21 +1557,40 @@ func deriveDeepCopy_27(dst, src *ConfigObjConfig) {
} }
// deriveDeepCopy_28 recursively copies the contents of src into dst. // deriveDeepCopy_28 recursively copies the contents of src into dst.
func deriveDeepCopy_28(dst, src []Trigger) { func deriveDeepCopy_28(dst, src *ConfigObjConfig) {
for src_i, src_value := range src { dst.Name = src.Name
func() { dst.File = src.File
field := new(Trigger) dst.Environment = src.Environment
deriveDeepCopy_46(field, &src_value) dst.Content = src.Content
dst[src_i] = *field dst.marshallContent = src.marshallContent
}() dst.External = src.External
if src.Labels != nil {
dst.Labels = make(map[string]string, len(src.Labels))
deriveDeepCopy_4(dst.Labels, src.Labels)
} else {
dst.Labels = nil
}
dst.Driver = src.Driver
if src.DriverOpts != nil {
dst.DriverOpts = make(map[string]string, len(src.DriverOpts))
deriveDeepCopy_4(dst.DriverOpts, src.DriverOpts)
} else {
dst.DriverOpts = nil
}
dst.TemplateDriver = src.TemplateDriver
if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions))
src.Extensions.DeepCopy(dst.Extensions)
} else {
dst.Extensions = nil
} }
} }
// deriveDeepCopy_29 recursively copies the contents of src into dst. // deriveDeepCopy_29 recursively copies the contents of src into dst.
func deriveDeepCopy_29(dst, src []WeightDevice) { func deriveDeepCopy_29(dst, src []Trigger) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(WeightDevice) field := new(Trigger)
deriveDeepCopy_47(field, &src_value) deriveDeepCopy_47(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
@ -1586,10 +1598,10 @@ func deriveDeepCopy_29(dst, src []WeightDevice) {
} }
// deriveDeepCopy_30 recursively copies the contents of src into dst. // deriveDeepCopy_30 recursively copies the contents of src into dst.
func deriveDeepCopy_30(dst, src []ThrottleDevice) { func deriveDeepCopy_30(dst, src []WeightDevice) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(ThrottleDevice) field := new(WeightDevice)
deriveDeepCopy_48(field, &src_value) deriveDeepCopy_48(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
@ -1597,7 +1609,18 @@ func deriveDeepCopy_30(dst, src []ThrottleDevice) {
} }
// deriveDeepCopy_31 recursively copies the contents of src into dst. // deriveDeepCopy_31 recursively copies the contents of src into dst.
func deriveDeepCopy_31(dst, src *ServiceConfigObjConfig) { func deriveDeepCopy_31(dst, src []ThrottleDevice) {
for src_i, src_value := range src {
func() {
field := new(ThrottleDevice)
deriveDeepCopy_49(field, &src_value)
dst[src_i] = *field
}()
}
}
// deriveDeepCopy_32 recursively copies the contents of src into dst.
func deriveDeepCopy_32(dst, src *ServiceConfigObjConfig) {
dst.Source = src.Source dst.Source = src.Source
dst.Target = src.Target dst.Target = src.Target
dst.UID = src.UID dst.UID = src.UID
@ -1616,8 +1639,8 @@ func deriveDeepCopy_31(dst, src *ServiceConfigObjConfig) {
} }
} }
// deriveDeepCopy_32 recursively copies the contents of src into dst. // deriveDeepCopy_33 recursively copies the contents of src into dst.
func deriveDeepCopy_32(dst, src *ServiceDependency) { func deriveDeepCopy_33(dst, src *ServiceDependency) {
dst.Condition = src.Condition dst.Condition = src.Condition
dst.Restart = src.Restart dst.Restart = src.Restart
if src.Extensions != nil { if src.Extensions != nil {
@ -1629,8 +1652,8 @@ func deriveDeepCopy_32(dst, src *ServiceDependency) {
dst.Required = src.Required dst.Required = src.Required
} }
// deriveDeepCopy_33 recursively copies the contents of src into dst. // deriveDeepCopy_34 recursively copies the contents of src into dst.
func deriveDeepCopy_33(dst, src *UpdateConfig) { func deriveDeepCopy_34(dst, src *UpdateConfig) {
if src.Parallelism == nil { if src.Parallelism == nil {
dst.Parallelism = nil dst.Parallelism = nil
} else { } else {
@ -1650,19 +1673,19 @@ func deriveDeepCopy_33(dst, src *UpdateConfig) {
} }
} }
// deriveDeepCopy_34 recursively copies the contents of src into dst. // deriveDeepCopy_35 recursively copies the contents of src into dst.
func deriveDeepCopy_34(dst, src *Resources) { func deriveDeepCopy_35(dst, src *Resources) {
if src.Limits == nil { if src.Limits == nil {
dst.Limits = nil dst.Limits = nil
} else { } else {
dst.Limits = new(Resource) dst.Limits = new(Resource)
deriveDeepCopy_49(dst.Limits, src.Limits) deriveDeepCopy_50(dst.Limits, src.Limits)
} }
if src.Reservations == nil { if src.Reservations == nil {
dst.Reservations = nil dst.Reservations = nil
} else { } else {
dst.Reservations = new(Resource) dst.Reservations = new(Resource)
deriveDeepCopy_49(dst.Reservations, src.Reservations) deriveDeepCopy_50(dst.Reservations, src.Reservations)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -1672,8 +1695,8 @@ func deriveDeepCopy_34(dst, src *Resources) {
} }
} }
// deriveDeepCopy_35 recursively copies the contents of src into dst. // deriveDeepCopy_36 recursively copies the contents of src into dst.
func deriveDeepCopy_35(dst, src *RestartPolicy) { func deriveDeepCopy_36(dst, src *RestartPolicy) {
dst.Condition = src.Condition dst.Condition = src.Condition
if src.Delay == nil { if src.Delay == nil {
dst.Delay = nil dst.Delay = nil
@ -1701,8 +1724,8 @@ func deriveDeepCopy_35(dst, src *RestartPolicy) {
} }
} }
// deriveDeepCopy_36 recursively copies the contents of src into dst. // deriveDeepCopy_37 recursively copies the contents of src into dst.
func deriveDeepCopy_36(dst, src *Placement) { func deriveDeepCopy_37(dst, src *Placement) {
if src.Constraints == nil { if src.Constraints == nil {
dst.Constraints = nil dst.Constraints = nil
} else { } else {
@ -1737,7 +1760,7 @@ func deriveDeepCopy_36(dst, src *Placement) {
} else { } else {
dst.Preferences = make([]PlacementPreferences, len(src.Preferences)) dst.Preferences = make([]PlacementPreferences, len(src.Preferences))
} }
deriveDeepCopy_50(dst.Preferences, src.Preferences) deriveDeepCopy_51(dst.Preferences, src.Preferences)
} }
dst.MaxReplicas = src.MaxReplicas dst.MaxReplicas = src.MaxReplicas
if src.Extensions != nil { if src.Extensions != nil {
@ -1748,8 +1771,8 @@ func deriveDeepCopy_36(dst, src *Placement) {
} }
} }
// deriveDeepCopy_37 recursively copies the contents of src into dst. // deriveDeepCopy_38 recursively copies the contents of src into dst.
func deriveDeepCopy_37(dst, src *DeviceMapping) { func deriveDeepCopy_38(dst, src *DeviceMapping) {
dst.Source = src.Source dst.Source = src.Source
dst.Target = src.Target dst.Target = src.Target
dst.Permissions = src.Permissions dst.Permissions = src.Permissions
@ -1761,8 +1784,8 @@ func deriveDeepCopy_37(dst, src *DeviceMapping) {
} }
} }
// deriveDeepCopy_38 recursively copies the contents of src into dst. // deriveDeepCopy_39 recursively copies the contents of src into dst.
func deriveDeepCopy_38(dst, src *DeviceRequest) { func deriveDeepCopy_39(dst, src *DeviceRequest) {
if src.Capabilities == nil { if src.Capabilities == nil {
dst.Capabilities = nil dst.Capabilities = nil
} else { } else {
@ -1809,8 +1832,8 @@ func deriveDeepCopy_38(dst, src *DeviceRequest) {
} }
} }
// deriveDeepCopy_39 recursively copies the contents of src into dst. // deriveDeepCopy_40 recursively copies the contents of src into dst.
func deriveDeepCopy_39(dst, src *ServiceNetworkConfig) { func deriveDeepCopy_40(dst, src *ServiceNetworkConfig) {
dst.Priority = src.Priority dst.Priority = src.Priority
dst.GatewayPriority = src.GatewayPriority dst.GatewayPriority = src.GatewayPriority
if src.Aliases == nil { if src.Aliases == nil {
@ -1866,8 +1889,8 @@ func deriveDeepCopy_39(dst, src *ServiceNetworkConfig) {
} }
} }
// deriveDeepCopy_40 recursively copies the contents of src into dst. // deriveDeepCopy_41 recursively copies the contents of src into dst.
func deriveDeepCopy_40(dst, src *ServicePortConfig) { func deriveDeepCopy_41(dst, src *ServicePortConfig) {
dst.Name = src.Name dst.Name = src.Name
dst.Mode = src.Mode dst.Mode = src.Mode
dst.HostIP = src.HostIP dst.HostIP = src.HostIP
@ -1883,8 +1906,8 @@ func deriveDeepCopy_40(dst, src *ServicePortConfig) {
} }
} }
// deriveDeepCopy_41 recursively copies the contents of src into dst. // deriveDeepCopy_42 recursively copies the contents of src into dst.
func deriveDeepCopy_41(dst, src *ServiceSecretConfig) { func deriveDeepCopy_42(dst, src *ServiceSecretConfig) {
dst.Source = src.Source dst.Source = src.Source
dst.Target = src.Target dst.Target = src.Target
dst.UID = src.UID dst.UID = src.UID
@ -1903,8 +1926,8 @@ func deriveDeepCopy_41(dst, src *ServiceSecretConfig) {
} }
} }
// deriveDeepCopy_42 recursively copies the contents of src into dst. // deriveDeepCopy_43 recursively copies the contents of src into dst.
func deriveDeepCopy_42(dst, src *UlimitsConfig) { func deriveDeepCopy_43(dst, src *UlimitsConfig) {
dst.Single = src.Single dst.Single = src.Single
dst.Soft = src.Soft dst.Soft = src.Soft
dst.Hard = src.Hard dst.Hard = src.Hard
@ -1916,8 +1939,8 @@ func deriveDeepCopy_42(dst, src *UlimitsConfig) {
} }
} }
// deriveDeepCopy_43 recursively copies the contents of src into dst. // deriveDeepCopy_44 recursively copies the contents of src into dst.
func deriveDeepCopy_43(dst, src *ServiceVolumeConfig) { func deriveDeepCopy_44(dst, src *ServiceVolumeConfig) {
dst.Type = src.Type dst.Type = src.Type
dst.Source = src.Source dst.Source = src.Source
dst.Target = src.Target dst.Target = src.Target
@ -1927,19 +1950,25 @@ func deriveDeepCopy_43(dst, src *ServiceVolumeConfig) {
dst.Bind = nil dst.Bind = nil
} else { } else {
dst.Bind = new(ServiceVolumeBind) dst.Bind = new(ServiceVolumeBind)
deriveDeepCopy_51(dst.Bind, src.Bind) deriveDeepCopy_52(dst.Bind, src.Bind)
} }
if src.Volume == nil { if src.Volume == nil {
dst.Volume = nil dst.Volume = nil
} else { } else {
dst.Volume = new(ServiceVolumeVolume) dst.Volume = new(ServiceVolumeVolume)
deriveDeepCopy_52(dst.Volume, src.Volume) deriveDeepCopy_53(dst.Volume, src.Volume)
} }
if src.Tmpfs == nil { if src.Tmpfs == nil {
dst.Tmpfs = nil dst.Tmpfs = nil
} else { } else {
dst.Tmpfs = new(ServiceVolumeTmpfs) dst.Tmpfs = new(ServiceVolumeTmpfs)
deriveDeepCopy_53(dst.Tmpfs, src.Tmpfs) deriveDeepCopy_54(dst.Tmpfs, src.Tmpfs)
}
if src.Image == nil {
dst.Image = nil
} else {
dst.Image = new(ServiceVolumeImage)
deriveDeepCopy_55(dst.Image, src.Image)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -1949,8 +1978,8 @@ func deriveDeepCopy_43(dst, src *ServiceVolumeConfig) {
} }
} }
// deriveDeepCopy_44 recursively copies the contents of src into dst. // deriveDeepCopy_45 recursively copies the contents of src into dst.
func deriveDeepCopy_44(dst, src *ServiceHook) { func deriveDeepCopy_45(dst, src *ServiceHook) {
if src.Command == nil { if src.Command == nil {
dst.Command = nil dst.Command = nil
} else { } else {
@ -1974,7 +2003,7 @@ func deriveDeepCopy_44(dst, src *ServiceHook) {
dst.WorkingDir = src.WorkingDir dst.WorkingDir = src.WorkingDir
if src.Environment != nil { if src.Environment != nil {
dst.Environment = make(map[string]*string, len(src.Environment)) dst.Environment = make(map[string]*string, len(src.Environment))
deriveDeepCopy_13(dst.Environment, src.Environment) deriveDeepCopy_14(dst.Environment, src.Environment)
} else { } else {
dst.Environment = nil dst.Environment = nil
} }
@ -1986,8 +2015,8 @@ func deriveDeepCopy_44(dst, src *ServiceHook) {
} }
} }
// deriveDeepCopy_45 recursively copies the contents of src into dst. // deriveDeepCopy_46 recursively copies the contents of src into dst.
func deriveDeepCopy_45(dst, src *IPAMConfig) { func deriveDeepCopy_46(dst, src *IPAMConfig) {
dst.Driver = src.Driver dst.Driver = src.Driver
if src.Config == nil { if src.Config == nil {
dst.Config = nil dst.Config = nil
@ -2005,7 +2034,7 @@ func deriveDeepCopy_45(dst, src *IPAMConfig) {
} else { } else {
dst.Config = make([]*IPAMPool, len(src.Config)) dst.Config = make([]*IPAMPool, len(src.Config))
} }
deriveDeepCopy_54(dst.Config, src.Config) deriveDeepCopy_56(dst.Config, src.Config)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -2015,14 +2044,14 @@ func deriveDeepCopy_45(dst, src *IPAMConfig) {
} }
} }
// deriveDeepCopy_46 recursively copies the contents of src into dst. // deriveDeepCopy_47 recursively copies the contents of src into dst.
func deriveDeepCopy_46(dst, src *Trigger) { func deriveDeepCopy_47(dst, src *Trigger) {
dst.Path = src.Path dst.Path = src.Path
dst.Action = src.Action dst.Action = src.Action
dst.Target = src.Target dst.Target = src.Target
func() { func() {
field := new(ServiceHook) field := new(ServiceHook)
deriveDeepCopy_44(field, &src.Exec) deriveDeepCopy_45(field, &src.Exec)
dst.Exec = *field dst.Exec = *field
}() }()
if src.Include == nil { if src.Include == nil {
@ -2069,8 +2098,8 @@ func deriveDeepCopy_46(dst, src *Trigger) {
} }
} }
// deriveDeepCopy_47 recursively copies the contents of src into dst. // deriveDeepCopy_48 recursively copies the contents of src into dst.
func deriveDeepCopy_47(dst, src *WeightDevice) { func deriveDeepCopy_48(dst, src *WeightDevice) {
dst.Path = src.Path dst.Path = src.Path
dst.Weight = src.Weight dst.Weight = src.Weight
if src.Extensions != nil { if src.Extensions != nil {
@ -2081,8 +2110,8 @@ func deriveDeepCopy_47(dst, src *WeightDevice) {
} }
} }
// deriveDeepCopy_48 recursively copies the contents of src into dst. // deriveDeepCopy_49 recursively copies the contents of src into dst.
func deriveDeepCopy_48(dst, src *ThrottleDevice) { func deriveDeepCopy_49(dst, src *ThrottleDevice) {
dst.Path = src.Path dst.Path = src.Path
dst.Rate = src.Rate dst.Rate = src.Rate
if src.Extensions != nil { if src.Extensions != nil {
@ -2093,8 +2122,8 @@ func deriveDeepCopy_48(dst, src *ThrottleDevice) {
} }
} }
// deriveDeepCopy_49 recursively copies the contents of src into dst. // deriveDeepCopy_50 recursively copies the contents of src into dst.
func deriveDeepCopy_49(dst, src *Resource) { func deriveDeepCopy_50(dst, src *Resource) {
dst.NanoCPUs = src.NanoCPUs dst.NanoCPUs = src.NanoCPUs
dst.MemoryBytes = src.MemoryBytes dst.MemoryBytes = src.MemoryBytes
dst.Pids = src.Pids dst.Pids = src.Pids
@ -2114,7 +2143,7 @@ func deriveDeepCopy_49(dst, src *Resource) {
} else { } else {
dst.Devices = make([]DeviceRequest, len(src.Devices)) dst.Devices = make([]DeviceRequest, len(src.Devices))
} }
deriveDeepCopy_15(dst.Devices, src.Devices) deriveDeepCopy_16(dst.Devices, src.Devices)
} }
if src.GenericResources == nil { if src.GenericResources == nil {
dst.GenericResources = nil dst.GenericResources = nil
@ -2132,7 +2161,7 @@ func deriveDeepCopy_49(dst, src *Resource) {
} else { } else {
dst.GenericResources = make([]GenericResource, len(src.GenericResources)) dst.GenericResources = make([]GenericResource, len(src.GenericResources))
} }
deriveDeepCopy_55(dst.GenericResources, src.GenericResources) deriveDeepCopy_57(dst.GenericResources, src.GenericResources)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -2142,19 +2171,19 @@ func deriveDeepCopy_49(dst, src *Resource) {
} }
} }
// deriveDeepCopy_50 recursively copies the contents of src into dst. // deriveDeepCopy_51 recursively copies the contents of src into dst.
func deriveDeepCopy_50(dst, src []PlacementPreferences) { func deriveDeepCopy_51(dst, src []PlacementPreferences) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(PlacementPreferences) field := new(PlacementPreferences)
deriveDeepCopy_56(field, &src_value) deriveDeepCopy_58(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
} }
} }
// deriveDeepCopy_51 recursively copies the contents of src into dst. // deriveDeepCopy_52 recursively copies the contents of src into dst.
func deriveDeepCopy_51(dst, src *ServiceVolumeBind) { func deriveDeepCopy_52(dst, src *ServiceVolumeBind) {
dst.SELinux = src.SELinux dst.SELinux = src.SELinux
dst.Propagation = src.Propagation dst.Propagation = src.Propagation
dst.CreateHostPath = src.CreateHostPath dst.CreateHostPath = src.CreateHostPath
@ -2167,8 +2196,14 @@ func deriveDeepCopy_51(dst, src *ServiceVolumeBind) {
} }
} }
// deriveDeepCopy_52 recursively copies the contents of src into dst. // deriveDeepCopy_53 recursively copies the contents of src into dst.
func deriveDeepCopy_52(dst, src *ServiceVolumeVolume) { func deriveDeepCopy_53(dst, src *ServiceVolumeVolume) {
if src.Labels != nil {
dst.Labels = make(map[string]string, len(src.Labels))
deriveDeepCopy_4(dst.Labels, src.Labels)
} else {
dst.Labels = nil
}
dst.NoCopy = src.NoCopy dst.NoCopy = src.NoCopy
dst.Subpath = src.Subpath dst.Subpath = src.Subpath
if src.Extensions != nil { if src.Extensions != nil {
@ -2179,8 +2214,8 @@ func deriveDeepCopy_52(dst, src *ServiceVolumeVolume) {
} }
} }
// deriveDeepCopy_53 recursively copies the contents of src into dst. // deriveDeepCopy_54 recursively copies the contents of src into dst.
func deriveDeepCopy_53(dst, src *ServiceVolumeTmpfs) { func deriveDeepCopy_54(dst, src *ServiceVolumeTmpfs) {
dst.Size = src.Size dst.Size = src.Size
dst.Mode = src.Mode dst.Mode = src.Mode
if src.Extensions != nil { if src.Extensions != nil {
@ -2191,31 +2226,42 @@ func deriveDeepCopy_53(dst, src *ServiceVolumeTmpfs) {
} }
} }
// deriveDeepCopy_54 recursively copies the contents of src into dst. // deriveDeepCopy_55 recursively copies the contents of src into dst.
func deriveDeepCopy_54(dst, src []*IPAMPool) { func deriveDeepCopy_55(dst, src *ServiceVolumeImage) {
dst.SubPath = src.SubPath
if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions))
src.Extensions.DeepCopy(dst.Extensions)
} else {
dst.Extensions = nil
}
}
// deriveDeepCopy_56 recursively copies the contents of src into dst.
func deriveDeepCopy_56(dst, src []*IPAMPool) {
for src_i, src_value := range src { for src_i, src_value := range src {
if src_value == nil { if src_value == nil {
dst[src_i] = nil dst[src_i] = nil
} else { } else {
dst[src_i] = new(IPAMPool) dst[src_i] = new(IPAMPool)
deriveDeepCopy_57(dst[src_i], src_value) deriveDeepCopy_59(dst[src_i], src_value)
} }
} }
} }
// deriveDeepCopy_55 recursively copies the contents of src into dst. // deriveDeepCopy_57 recursively copies the contents of src into dst.
func deriveDeepCopy_55(dst, src []GenericResource) { func deriveDeepCopy_57(dst, src []GenericResource) {
for src_i, src_value := range src { for src_i, src_value := range src {
func() { func() {
field := new(GenericResource) field := new(GenericResource)
deriveDeepCopy_58(field, &src_value) deriveDeepCopy_60(field, &src_value)
dst[src_i] = *field dst[src_i] = *field
}() }()
} }
} }
// deriveDeepCopy_56 recursively copies the contents of src into dst. // deriveDeepCopy_58 recursively copies the contents of src into dst.
func deriveDeepCopy_56(dst, src *PlacementPreferences) { func deriveDeepCopy_58(dst, src *PlacementPreferences) {
dst.Spread = src.Spread dst.Spread = src.Spread
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -2225,8 +2271,8 @@ func deriveDeepCopy_56(dst, src *PlacementPreferences) {
} }
} }
// deriveDeepCopy_57 recursively copies the contents of src into dst. // deriveDeepCopy_59 recursively copies the contents of src into dst.
func deriveDeepCopy_57(dst, src *IPAMPool) { func deriveDeepCopy_59(dst, src *IPAMPool) {
dst.Subnet = src.Subnet dst.Subnet = src.Subnet
dst.Gateway = src.Gateway dst.Gateway = src.Gateway
dst.IPRange = src.IPRange dst.IPRange = src.IPRange
@ -2244,13 +2290,13 @@ func deriveDeepCopy_57(dst, src *IPAMPool) {
} }
} }
// deriveDeepCopy_58 recursively copies the contents of src into dst. // deriveDeepCopy_60 recursively copies the contents of src into dst.
func deriveDeepCopy_58(dst, src *GenericResource) { func deriveDeepCopy_60(dst, src *GenericResource) {
if src.DiscreteResourceSpec == nil { if src.DiscreteResourceSpec == nil {
dst.DiscreteResourceSpec = nil dst.DiscreteResourceSpec = nil
} else { } else {
dst.DiscreteResourceSpec = new(DiscreteGenericResource) dst.DiscreteResourceSpec = new(DiscreteGenericResource)
deriveDeepCopy_59(dst.DiscreteResourceSpec, src.DiscreteResourceSpec) deriveDeepCopy_61(dst.DiscreteResourceSpec, src.DiscreteResourceSpec)
} }
if src.Extensions != nil { if src.Extensions != nil {
dst.Extensions = make(map[string]any, len(src.Extensions)) dst.Extensions = make(map[string]any, len(src.Extensions))
@ -2260,8 +2306,8 @@ func deriveDeepCopy_58(dst, src *GenericResource) {
} }
} }
// deriveDeepCopy_59 recursively copies the contents of src into dst. // deriveDeepCopy_61 recursively copies the contents of src into dst.
func deriveDeepCopy_59(dst, src *DiscreteGenericResource) { func deriveDeepCopy_61(dst, src *DiscreteGenericResource) {
dst.Kind = src.Kind dst.Kind = src.Kind
dst.Value = src.Value dst.Value = src.Value
if src.Extensions != nil { if src.Extensions != nil {

View File

@ -21,8 +21,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"maps"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"sort" "sort"
"github.com/compose-spec/compose-go/v2/dotenv" "github.com/compose-spec/compose-go/v2/dotenv"
@ -30,7 +32,6 @@ import (
"github.com/compose-spec/compose-go/v2/utils" "github.com/compose-spec/compose-go/v2/utils"
"github.com/distribution/reference" "github.com/distribution/reference"
godigest "github.com/opencontainers/go-digest" godigest "github.com/opencontainers/go-digest"
"golang.org/x/exp/maps"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -120,21 +121,21 @@ func (p *Project) ServicesWithBuild() []string {
servicesBuild := p.Services.Filter(func(s ServiceConfig) bool { servicesBuild := p.Services.Filter(func(s ServiceConfig) bool {
return s.Build != nil && s.Build.Context != "" return s.Build != nil && s.Build.Context != ""
}) })
return maps.Keys(servicesBuild) return slices.Collect(maps.Keys(servicesBuild))
} }
func (p *Project) ServicesWithExtends() []string { func (p *Project) ServicesWithExtends() []string {
servicesExtends := p.Services.Filter(func(s ServiceConfig) bool { servicesExtends := p.Services.Filter(func(s ServiceConfig) bool {
return s.Extends != nil && *s.Extends != (ExtendsConfig{}) return s.Extends != nil && *s.Extends != (ExtendsConfig{})
}) })
return maps.Keys(servicesExtends) return slices.Collect(maps.Keys(servicesExtends))
} }
func (p *Project) ServicesWithDependsOn() []string { func (p *Project) ServicesWithDependsOn() []string {
servicesDependsOn := p.Services.Filter(func(s ServiceConfig) bool { servicesDependsOn := p.Services.Filter(func(s ServiceConfig) bool {
return len(s.DependsOn) > 0 return len(s.DependsOn) > 0
}) })
return maps.Keys(servicesDependsOn) return slices.Collect(maps.Keys(servicesDependsOn))
} }
func (p *Project) ServicesWithCapabilities() ([]string, []string, []string) { func (p *Project) ServicesWithCapabilities() ([]string, []string, []string) {
@ -156,9 +157,10 @@ func (p *Project) ServicesWithCapabilities() ([]string, []string, []string) {
capabilities = append(capabilities, service.Name) capabilities = append(capabilities, service.Name)
} }
for _, c := range d.Capabilities { for _, c := range d.Capabilities {
if c == "gpu" { switch c {
case "gpu":
gpu = append(gpu, service.Name) gpu = append(gpu, service.Name)
} else if c == "tpu" { case "tpu":
tpu = append(tpu, service.Name) tpu = append(tpu, service.Name)
} }
} }
@ -188,16 +190,25 @@ func (p *Project) getServicesByNames(names ...string) (Services, []string) {
if len(names) == 0 { if len(names) == 0 {
return p.Services, nil return p.Services, nil
} }
services := Services{} services := Services{}
var servicesNotFound []string var servicesNotFound []string
for _, name := range names { for _, name := range names {
service, ok := p.Services[name] matched := false
if !ok {
servicesNotFound = append(servicesNotFound, name) for serviceName, service := range p.Services {
continue match, _ := filepath.Match(name, serviceName)
if match {
services[serviceName] = service
matched = true
}
}
if !matched {
servicesNotFound = append(servicesNotFound, name)
} }
services[name] = service
} }
return services, servicesNotFound return services, servicesNotFound
} }
@ -298,16 +309,25 @@ func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]b
return nil return nil
} }
func (p *Project) GetDependentsForService(s ServiceConfig) []string { func (p *Project) GetDependentsForService(s ServiceConfig, filter ...func(ServiceDependency) bool) []string {
return utils.MapKeys(p.dependentsForService(s)) return utils.MapKeys(p.dependentsForService(s, filter...))
} }
func (p *Project) dependentsForService(s ServiceConfig) map[string]ServiceDependency { func (p *Project) dependentsForService(s ServiceConfig, filter ...func(ServiceDependency) bool) map[string]ServiceDependency {
dependent := make(map[string]ServiceDependency) dependent := make(map[string]ServiceDependency)
for _, service := range p.Services { for _, service := range p.Services {
for name, dependency := range service.DependsOn { for name, dependency := range service.DependsOn {
if name == s.Name { if name == s.Name {
dependent[service.Name] = dependency depends := true
for _, f := range filter {
if !f(dependency) {
depends = false
break
}
}
if depends {
dependent[service.Name] = dependency
}
} }
} }
} }
@ -630,25 +650,25 @@ func (p Project) WithServicesEnvironmentResolved(discardEnvFiles bool) (*Project
for i, service := range newProject.Services { for i, service := range newProject.Services {
service.Environment = service.Environment.Resolve(newProject.Environment.Resolve) service.Environment = service.Environment.Resolve(newProject.Environment.Resolve)
environment := MappingWithEquals{} environment := service.Environment.ToMapping()
// resolve variables based on other files we already parsed, + project's environment
var resolve dotenv.LookupFn = func(s string) (string, bool) {
v, ok := environment[s]
if ok && v != nil {
return *v, ok
}
return newProject.Environment.Resolve(s)
}
for _, envFile := range service.EnvFiles { for _, envFile := range service.EnvFiles {
vars, err := loadEnvFile(envFile, resolve) err := loadEnvFile(envFile, environment, func(k string) (string, bool) {
// project.env has precedence doing interpolation
if resolve, ok := p.Environment.Resolve(k); ok {
return resolve, true
}
// then service.environment
if s, ok := service.Environment[k]; ok {
return *s, true
}
return "", false
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
environment.OverrideBy(vars.ToMappingWithEquals())
} }
service.Environment = environment.OverrideBy(service.Environment) service.Environment = environment.ToMappingWithEquals().OverrideBy(service.Environment)
if discardEnvFiles { if discardEnvFiles {
service.EnvFiles = nil service.EnvFiles = nil
@ -696,15 +716,16 @@ func (p Project) WithServicesLabelsResolved(discardLabelFiles bool) (*Project, e
return newProject, nil return newProject, nil
} }
func loadEnvFile(envFile EnvFile, resolve dotenv.LookupFn) (Mapping, error) { func loadEnvFile(envFile EnvFile, environment Mapping, resolve dotenv.LookupFn) error {
if _, err := os.Stat(envFile.Path); os.IsNotExist(err) { if _, err := os.Stat(envFile.Path); os.IsNotExist(err) {
if envFile.Required { if envFile.Required {
return nil, fmt.Errorf("env file %s not found: %w", envFile.Path, err) return fmt.Errorf("env file %s not found: %w", envFile.Path, err)
} }
return nil, nil return nil
} }
return loadMappingFile(envFile.Path, envFile.Format, resolve) err := loadMappingFile(envFile.Path, envFile.Format, environment, resolve)
return err
} }
func loadLabelFile(labelFile string, resolve dotenv.LookupFn) (Mapping, error) { func loadLabelFile(labelFile string, resolve dotenv.LookupFn) (Mapping, error) {
@ -712,21 +733,19 @@ func loadLabelFile(labelFile string, resolve dotenv.LookupFn) (Mapping, error) {
return nil, fmt.Errorf("label file %s not found: %w", labelFile, err) return nil, fmt.Errorf("label file %s not found: %w", labelFile, err)
} }
return loadMappingFile(labelFile, "", resolve) labels := Mapping{}
err := loadMappingFile(labelFile, "", labels, resolve)
return labels, err
} }
func loadMappingFile(path string, format string, resolve dotenv.LookupFn) (Mapping, error) { func loadMappingFile(path string, format string, vars Mapping, resolve dotenv.LookupFn) error {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
return nil, err return err
} }
defer file.Close() defer file.Close()
fileVars, err := dotenv.ParseWithFormat(file, path, resolve, format) return dotenv.ParseWithFormat(file, path, vars, resolve, format)
if err != nil {
return nil, err
}
return fileVars, nil
} }
func (p *Project) deepCopy() *Project { func (p *Project) deepCopy() *Project {

View File

@ -75,8 +75,8 @@ type ServiceConfig struct {
// If set, overrides ENTRYPOINT from the image. // If set, overrides ENTRYPOINT from the image.
// //
// Set to `[]` or an empty string to clear the entrypoint from the image. // Set to `[]` or an empty string to clear the entrypoint from the image.
Entrypoint ShellCommand `yaml:"entrypoint,omitempty" json:"entrypoint"` // NOTE: we can NOT omitempty for JSON! see ShellCommand type for details. Entrypoint ShellCommand `yaml:"entrypoint,omitempty" json:"entrypoint"` // NOTE: we can NOT omitempty for JSON! see ShellCommand type for details.
Provider *ServiceProviderConfig `yaml:"provider,omitempty" json:"provider,omitempty"`
Environment MappingWithEquals `yaml:"environment,omitempty" json:"environment,omitempty"` Environment MappingWithEquals `yaml:"environment,omitempty" json:"environment,omitempty"`
EnvFiles []EnvFile `yaml:"env_file,omitempty" json:"env_file,omitempty"` EnvFiles []EnvFile `yaml:"env_file,omitempty" json:"env_file,omitempty"`
Expose StringOrNumberList `yaml:"expose,omitempty" json:"expose,omitempty"` Expose StringOrNumberList `yaml:"expose,omitempty" json:"expose,omitempty"`
@ -142,6 +142,12 @@ type ServiceConfig struct {
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
} }
type ServiceProviderConfig struct {
Type string `yaml:"type,omitempty" json:"driver,omitempty"`
Options Options `yaml:"options,omitempty" json:"options,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
}
// MarshalYAML makes ServiceConfig implement yaml.Marshaller // MarshalYAML makes ServiceConfig implement yaml.Marshaller
func (s ServiceConfig) MarshalYAML() (interface{}, error) { func (s ServiceConfig) MarshalYAML() (interface{}, error) {
type t ServiceConfig type t ServiceConfig
@ -535,6 +541,7 @@ type ServiceVolumeConfig struct {
Bind *ServiceVolumeBind `yaml:"bind,omitempty" json:"bind,omitempty"` Bind *ServiceVolumeBind `yaml:"bind,omitempty" json:"bind,omitempty"`
Volume *ServiceVolumeVolume `yaml:"volume,omitempty" json:"volume,omitempty"` Volume *ServiceVolumeVolume `yaml:"volume,omitempty" json:"volume,omitempty"`
Tmpfs *ServiceVolumeTmpfs `yaml:"tmpfs,omitempty" json:"tmpfs,omitempty"` Tmpfs *ServiceVolumeTmpfs `yaml:"tmpfs,omitempty" json:"tmpfs,omitempty"`
Image *ServiceVolumeImage `yaml:"image,omitempty" json:"image,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
} }
@ -569,6 +576,8 @@ const (
VolumeTypeNamedPipe = "npipe" VolumeTypeNamedPipe = "npipe"
// VolumeTypeCluster is the type for mounting container storage interface (CSI) volumes // VolumeTypeCluster is the type for mounting container storage interface (CSI) volumes
VolumeTypeCluster = "cluster" VolumeTypeCluster = "cluster"
// VolumeTypeImage is the tpe for mounting an image
VolumeTypeImage = "image"
// SElinuxShared share the volume content // SElinuxShared share the volume content
SElinuxShared = "z" SElinuxShared = "z"
@ -612,8 +621,9 @@ const (
// ServiceVolumeVolume are options for a service volume of type volume // ServiceVolumeVolume are options for a service volume of type volume
type ServiceVolumeVolume struct { type ServiceVolumeVolume struct {
NoCopy bool `yaml:"nocopy,omitempty" json:"nocopy,omitempty"` Labels Mapping `yaml:"labels,omitempty" json:"labels,omitempty"`
Subpath string `yaml:"subpath,omitempty" json:"subpath,omitempty"` NoCopy bool `yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
Subpath string `yaml:"subpath,omitempty" json:"subpath,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
} }
@ -627,6 +637,11 @@ type ServiceVolumeTmpfs struct {
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"` Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
} }
type ServiceVolumeImage struct {
SubPath string `yaml:"subpath,omitempty" json:"subpath,omitempty"`
Extensions Extensions `yaml:"#extensions,inline,omitempty" json:"-"`
}
type FileMode int64 type FileMode int64
// FileReferenceConfig for a reference to a swarm file object // FileReferenceConfig for a reference to a swarm file object

View File

@ -17,15 +17,13 @@
package utils package utils
import ( import (
"golang.org/x/exp/constraints" "cmp"
"golang.org/x/exp/maps" "maps"
"golang.org/x/exp/slices" "slices"
) )
func MapKeys[T constraints.Ordered, U any](theMap map[T]U) []T { func MapKeys[T cmp.Ordered, U any](theMap map[T]U) []T {
result := maps.Keys(theMap) return slices.Sorted(maps.Keys(theMap))
slices.Sort(result)
return result
} }
func MapsAppend[T comparable, U any](target map[T]U, source map[T]U) map[T]U { func MapsAppend[T comparable, U any](target map[T]U, source map[T]U) map[T]U {

View File

@ -405,6 +405,7 @@ type SolveRequest struct {
Internal bool `protobuf:"varint,11,opt,name=Internal,proto3" json:"Internal,omitempty"` // Internal builds are not recorded in build history Internal bool `protobuf:"varint,11,opt,name=Internal,proto3" json:"Internal,omitempty"` // Internal builds are not recorded in build history
SourcePolicy *pb1.Policy `protobuf:"bytes,12,opt,name=SourcePolicy,proto3" json:"SourcePolicy,omitempty"` SourcePolicy *pb1.Policy `protobuf:"bytes,12,opt,name=SourcePolicy,proto3" json:"SourcePolicy,omitempty"`
Exporters []*Exporter `protobuf:"bytes,13,rep,name=Exporters,proto3" json:"Exporters,omitempty"` Exporters []*Exporter `protobuf:"bytes,13,rep,name=Exporters,proto3" json:"Exporters,omitempty"`
EnableSessionExporter bool `protobuf:"varint,14,opt,name=EnableSessionExporter,proto3" json:"EnableSessionExporter,omitempty"`
} }
func (x *SolveRequest) Reset() { func (x *SolveRequest) Reset() {
@ -528,6 +529,13 @@ func (x *SolveRequest) GetExporters() []*Exporter {
return nil return nil
} }
func (x *SolveRequest) GetEnableSessionExporter() bool {
if x != nil {
return x.EnableSessionExporter
}
return false
}
type CacheOptions struct { type CacheOptions struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -2087,7 +2095,7 @@ var file_github_com_moby_buildkit_api_services_control_control_proto_rawDesc = [
0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x0a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06,
0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x68, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x53, 0x68,
0x61, 0x72, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x61, 0x72, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x18,
0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbe, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xf4,
0x07, 0x0a, 0x0c, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x07, 0x0a, 0x0c, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65,
0x66, 0x12, 0x2e, 0x0a, 0x0a, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x66, 0x12, 0x2e, 0x0a, 0x0a, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18,
@ -2133,371 +2141,374 @@ var file_github_com_moby_buildkit_api_services_control_control_proto_rawDesc = [
0x6c, 0x69, 0x63, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72,
0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62,
0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x72, 0x52, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x73, 0x1a, 0x4a, 0x74, 0x65, 0x72, 0x52, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x73, 0x12, 0x34,
0x0a, 0x1c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x0a, 0x15, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45,
0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x45,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x72, 0x74, 0x65, 0x72, 0x1a, 0x4a, 0x0a, 0x1c, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x40, 0x0a, 0x12, 0x46, 0x72, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x45,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x13, 0x1a, 0x40, 0x0a, 0x12, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72,
0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x38, 0x01, 0x1a, 0x51, 0x0a, 0x13, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x49, 0x6e,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0xad, 0x03, 0x0a, 0x0c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x05, 0x76,
0x12, 0x30, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x66, 0x44, 0x65, 0x70, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e,
0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x45, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x66, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xad, 0x03, 0x0a, 0x0c, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f,
0x65, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x66, 0x73, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x65, 0x66, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20,
0x52, 0x14, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x66, 0x73, 0x44, 0x65, 0x70, 0x72, 0x01, 0x28, 0x09, 0x52, 0x13, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x66, 0x44, 0x65,
0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x14, 0x49, 0x6d, 0x70, 0x6f,
0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x72, 0x74, 0x52, 0x65, 0x66, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64,
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x66, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x15,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x74, 0x74, 0x72, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65,
0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x6d, 0x6f,
0x52, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43,
0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x07, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x45, 0x78, 0x70, 0x6f,
0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x72, 0x74, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x74,
0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x45, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3d, 0x0a,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x07, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x07, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76,
0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e,
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x49, 0x6d, 0x74, 0x72, 0x79, 0x52, 0x07, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x07,
0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x48, 0x0a, 0x1a, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e,
0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x07, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x48, 0x0a, 0x1a, 0x45,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x74, 0x74, 0x72, 0x73, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63,
0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa7, 0x01, 0x0a, 0x11, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54,
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12,
0x44, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05,
0x41, 0x74, 0x74, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
0xa7, 0x01, 0x0a, 0x11, 0x43, 0x61, 0x63, 0x68, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0xb7, 0x01, 0x0a, 0x0d, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73,
0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x44, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6d, 0x6f,
0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x63, 0x68, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x70,
0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74,
0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x41, 0x74, 0x74, 0x72, 0x73, 0x1a, 0x72, 0x79, 0x52, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x38, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x43, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb7, 0x01, 0x0a, 0x0d, 0x53, 0x6f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x21, 0x0a, 0x0d, 0x53, 0x74, 0x61,
0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x10, 0x45, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x52, 0x65,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x22, 0xf0, 0x01, 0x0a,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x34, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x45, 0x78, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x52, 0x08, 0x76, 0x65, 0x72,
0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x43, 0x74, 0x65, 0x78, 0x65, 0x73, 0x12, 0x3a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65,
0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62,
0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x02, 0x38, 0x01, 0x22, 0x21, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x1b, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f,
0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x67, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c,
0x74, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6f, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x57, 0x61,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22,
0x65, 0x72, 0x74, 0x65, 0x78, 0x52, 0x08, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x65, 0x73, 0x12, 0xa3, 0x02, 0x0a, 0x06, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69,
0x3a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65,
0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
0x73, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x2f, 0x0a, 0x04, 0x6c, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16,
0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65,
0x74, 0x65, 0x78, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76,
0x31, 0x2e, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x52,
0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xa3, 0x02, 0x0a, 0x06, 0x56, 0x65,
0x72, 0x74, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e,
0x70, 0x75, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68,
0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64,
0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73,
0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64,
0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x37, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65,
0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70,
0x52, 0x0d, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
0xa4, 0x02, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44,
0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18,
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65,
0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09,
0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x6f, 0x6d,
0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x87, 0x01, 0x0a, 0x09, 0x56, 0x65, 0x72, 0x74, 0x65, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
0x78, 0x4c, 0x6f, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x18, 0x01, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x37, 0x0a, 0x0d,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x08, 0x20,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73,
0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73,
0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xa4, 0x02, 0x0a, 0x0c, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x10, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78,
0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x12, 0x12,
0x22, 0xc4, 0x01, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20,
0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74,
0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x10, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x07,
0x12, 0x22, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x69, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18,
0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x22, 0x0a, 0x0c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2c, 0x0a, 0x12, 0x4c, 0x70, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x87, 0x01, 0x0a,
0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x09, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4c, 0x6f, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65,
0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x72, 0x74, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x72, 0x74,
0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x53, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x65, 0x78, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x12, 0x3c, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
0x32, 0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06,
0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x73, 0x74,
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x22, 0x0d, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x61, 0x0a, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0xc4, 0x01, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x74, 0x65,
0x0c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x78, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x74,
0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x65,
0x74, 0x61, 0x69, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x22, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x06, 0x72, 0x61,
0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x62, 0x2e,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x22, 0x0a,
0x0c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74,
0x61, 0x22, 0x2c, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65,
0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22,
0x53, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75,
0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x06, 0x72, 0x65,
0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x22, 0x0d, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75,
0x22, 0x93, 0x01, 0x0a, 0x13, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x74, 0x22, 0x61, 0x0a, 0x0c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56,
0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x41, 0x63, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d,
0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x61, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56, 0x65,
0x72, 0x6c, 0x79, 0x45, 0x78, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x45, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x56,
0x61, 0x72, 0x6c, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x93, 0x01, 0x0a, 0x13, 0x42, 0x75, 0x69, 0x6c, 0x64,
0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e,
0x12, 0x14, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01,
0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x28, 0x08, 0x52, 0x0a, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x10,
0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66,
0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x6d, 0x6f, 0x62, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x61, 0x72, 0x6c, 0x79, 0x45, 0x78, 0x69, 0x74, 0x18, 0x03, 0x20,
0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x01, 0x28, 0x08, 0x52, 0x09, 0x45, 0x61, 0x72, 0x6c, 0x79, 0x45, 0x78, 0x69, 0x74, 0x12, 0x16,
0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06,
0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18,
0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x8e, 0x01, 0x0a,
0x11, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x27, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74,
0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
0x3c, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x22, 0xd3, 0x09,
0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65,
0x63, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65,
0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65,
0x6e, 0x64, 0x12, 0x5d, 0x0a, 0x0d, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74,
0x74, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6d, 0x6f, 0x62, 0x79,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69,
0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e,
0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x22, 0xd3, 0x09, 0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74,
0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x72, 0x79, 0x52, 0x0d, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72,
0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04,
0x12, 0x1a, 0x0a, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c,
0x28, 0x09, 0x52, 0x08, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x12, 0x5d, 0x0a, 0x0d, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72,
0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x18, 0x03, 0x20, 0x52, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x65,
0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f,
0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05,
0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x46, 0x72, 0x41, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x45, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x07,
0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x72, 0x74, 0x65, 0x72, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x30, 0x0a,
0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f,
0x38, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x06, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6d,
0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x43, 0x6f, 0x6d, 0x70,
0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x30, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18,
0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x66, 0x0a, 0x10, 0x45, 0x78, 0x70,
0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64,
0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74,
0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x39, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x4b, 0x0a, 0x07,
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e,
0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x52, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x47, 0x65, 0x6e,
0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x47,
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x74, 0x72, 0x61,
0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a,
0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70,
0x69, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x43, 0x61, 0x63, 0x68,
0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e,
0x75, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x24, 0x0a,
0x0d, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x10,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74,
0x65, 0x70, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x6e, 0x75, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
0x74, 0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11,
0x6e, 0x75, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, 0x65, 0x70,
0x73, 0x12, 0x42, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,
0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6e, 0x75, 0x6d, 0x57, 0x61, 0x72, 0x6e,
0x69, 0x6e, 0x67, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x57,
0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x46, 0x72, 0x6f, 0x6e, 0x74,
0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x43, 0x0a, 0x15, 0x45, 0x78, 0x70,
0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5d,
0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x21, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x79, 0x0a,
0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74,
0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x52, 0x65,
0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06,
0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x50, 0x69,
0x6e, 0x6e, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08,
0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74,
0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61,
0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04,
0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65,
0x12, 0x4f, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x22, 0xc1, 0x02, 0x0a, 0x0f, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x44,
0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x10, 0x52,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12,
0x40, 0x0a, 0x0c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x52, 0x0c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x12, 0x48, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b,
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x58, 0x0a, 0x0c, 0x52,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d,
0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e,
0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74,
0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x41, 0x74, 0x74, 0x72, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65,
0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x41, 0x74,
0x74, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x3f, 0x0a,
0x15, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65,
0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45,
0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10,
0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x02, 0x32, 0x89,
0x06, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x54, 0x0a, 0x09, 0x44, 0x69,
0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62,
0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x55,
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x6f,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12,
0x12, 0x48, 0x0a, 0x05, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x66, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x75, 0x6e, 0x73, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x6d, 0x6f, 0x62, 0x79,
0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x61, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e,
0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x30, 0x01, 0x12, 0x48, 0x0a, 0x05, 0x53, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x6c, 0x76, 0x65, 0x12, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52,
0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62,
0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x52, 0x65, 0x73, 0x75,
0x6c, 0x74, 0x12, 0x4b, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x0b, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64,
0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74,
0x6f, 0x72, 0x79, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12,
0x1e, 0x0a, 0x0a, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0a, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x32, 0x0a, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76,
0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x74, 0x72,
0x20, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x0e, 0x20,
0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x6e,
0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x75, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x0f, 0x20,
0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x75, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x64, 0x53, 0x74,
0x65, 0x70, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x53,
0x74, 0x65, 0x70, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x54,
0x6f, 0x74, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x6e, 0x75, 0x6d,
0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x11,
0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x6e, 0x75, 0x6d, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
0x65, 0x64, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x42, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76,
0x31, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1e, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0d, 0x65, 0x78,
0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6e,
0x31, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x75, 0x6d, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x05,
0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x40, 0x0a,
0x73, 0x12, 0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x12, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
0x43, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x02, 0x38, 0x01, 0x1a, 0x5d, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65,
0x73, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x02, 0x38, 0x01, 0x22, 0x79, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69,
0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x10, 0x0a, 0x03, 0x52, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52,
0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x52, 0x06, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x22, 0x1c,
0x0a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73,
0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe8, 0x01, 0x0a,
0x0a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6d,
0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69,
0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65,
0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6d, 0x6f,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc1, 0x02, 0x0a, 0x0f, 0x42, 0x75, 0x69, 0x6c,
0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x10, 0x52,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x6f, 0x72, 0x52, 0x10, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x65, 0x70, 0x72, 0x65,
0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x40, 0x0a, 0x0c, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0c, 0x41, 0x74, 0x74, 0x65, 0x73,
0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c,
0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x65, 0x73, 0x75,
0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
0x73, 0x1a, 0x58, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b,
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x08,
0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x05,
0x41, 0x74, 0x74, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x6f,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45,
0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x72, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x05, 0x41, 0x74, 0x74, 0x72, 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x41, 0x74, 0x74,
0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x02, 0x38, 0x01, 0x2a, 0x3f, 0x0a, 0x15, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74,
0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07,
0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4d,
0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54,
0x45, 0x44, 0x10, 0x02, 0x32, 0x89, 0x06, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x12, 0x54, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x2e,
0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31,
0x2e, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69,
0x74, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x05, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x12,
0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x72, 0x75, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1d, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x30, 0x01,
0x12, 0x48, 0x0a, 0x05, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x12, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x6c,
0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x6f, 0x62, 0x79,
0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x6c,
0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4d, 0x0a, 0x06, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c,
0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x07, 0x53, 0x65, 0x73,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c,
0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x1a, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c,
0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x5a, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74,
0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62,
0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57,
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e,
0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31,
0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x6d,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x42,
0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x2e, 0x6d, 0x6f,
0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42,
0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b,
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f,
0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x6f, 0x0a, 0x12, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12,
0x2b, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e,
0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69,
0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d,
0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x6f,
0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x49,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x62, 0x79, 0x2f, 0x62, 0x75, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x12, 0x4c,
0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
0x63, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3b, 0x6d, 0x6f, 0x62, 0x79, 0x79, 0x12, 0x25, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69,
0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
0x6f, 0x74, 0x6f, 0x33, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e,
0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c,
0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12,
0x6f, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x69,
0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x2b, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42,
0x75, 0x69, 0x6c, 0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x6f, 0x62, 0x79, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b,
0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x75, 0x69, 0x6c,
0x64, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d,
0x6f, 0x62, 0x79, 0x2f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x3b, 0x6d, 0x6f, 0x62, 0x79, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x5f,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

View File

@ -74,6 +74,7 @@ message SolveRequest {
bool Internal = 11; // Internal builds are not recorded in build history bool Internal = 11; // Internal builds are not recorded in build history
moby.buildkit.v1.sourcepolicy.Policy SourcePolicy = 12; moby.buildkit.v1.sourcepolicy.Policy SourcePolicy = 12;
repeated Exporter Exporters = 13; repeated Exporter Exporters = 13;
bool EnableSessionExporter = 14;
} }
message CacheOptions { message CacheOptions {

View File

@ -140,6 +140,7 @@ func (m *SolveRequest) CloneVT() *SolveRequest {
r.Cache = m.Cache.CloneVT() r.Cache = m.Cache.CloneVT()
r.Internal = m.Internal r.Internal = m.Internal
r.SourcePolicy = m.SourcePolicy.CloneVT() r.SourcePolicy = m.SourcePolicy.CloneVT()
r.EnableSessionExporter = m.EnableSessionExporter
if rhs := m.ExporterAttrsDeprecated; rhs != nil { if rhs := m.ExporterAttrsDeprecated; rhs != nil {
tmpContainer := make(map[string]string, len(rhs)) tmpContainer := make(map[string]string, len(rhs))
for k, v := range rhs { for k, v := range rhs {
@ -1031,6 +1032,9 @@ func (this *SolveRequest) EqualVT(that *SolveRequest) bool {
} }
} }
} }
if this.EnableSessionExporter != that.EnableSessionExporter {
return false
}
return string(this.unknownFields) == string(that.unknownFields) return string(this.unknownFields) == string(that.unknownFields)
} }
@ -2232,6 +2236,16 @@ func (m *SolveRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
i -= len(m.unknownFields) i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields) copy(dAtA[i:], m.unknownFields)
} }
if m.EnableSessionExporter {
i--
if m.EnableSessionExporter {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x70
}
if len(m.Exporters) > 0 { if len(m.Exporters) > 0 {
for iNdEx := len(m.Exporters) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.Exporters) - 1; iNdEx >= 0; iNdEx-- {
size, err := m.Exporters[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) size, err := m.Exporters[iNdEx].MarshalToSizedBufferVT(dAtA[:i])
@ -4130,6 +4144,9 @@ func (m *SolveRequest) SizeVT() (n int) {
n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
} }
} }
if m.EnableSessionExporter {
n += 2
}
n += len(m.unknownFields) n += len(m.unknownFields)
return n return n
} }
@ -6211,6 +6228,26 @@ func (m *SolveRequest) UnmarshalVT(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 14:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EnableSessionExporter", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.EnableSessionExporter = bool(v != 0)
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := protohelpers.Skip(dAtA[iNdEx:]) skippy, err := protohelpers.Skip(dAtA[iNdEx:])

View File

@ -53,7 +53,8 @@ func (c *Client) Build(ctx context.Context, opt SolveOpt, product string, buildF
return err return err
} }
gwClient.caps = g.BuildOpts().Caps caps := g.BuildOpts().Caps
gwClient.caps = &caps
if err := g.Run(ctx, buildFunc); err != nil { if err := g.Run(ctx, buildFunc); err != nil {
return errors.Wrap(err, "failed to run Build function") return errors.Wrap(err, "failed to run Build function")
@ -72,10 +73,14 @@ func (c *Client) gatewayClientForBuild(buildid string) *gatewayClientForBuild {
} }
} }
func (c *Client) GatewayClientForBuild(buildid string) gatewayapi.LLBBridgeClient {
return c.gatewayClientForBuild(buildid)
}
type gatewayClientForBuild struct { type gatewayClientForBuild struct {
gateway gatewayapi.LLBBridgeClient gateway gatewayapi.LLBBridgeClient
buildID string buildID string
caps apicaps.CapSet caps *apicaps.CapSet
} }
func (g *gatewayClientForBuild) ResolveImageConfig(ctx context.Context, in *gatewayapi.ResolveImageConfigRequest, opts ...grpc.CallOption) (*gatewayapi.ResolveImageConfigResponse, error) { func (g *gatewayClientForBuild) ResolveImageConfig(ctx context.Context, in *gatewayapi.ResolveImageConfigRequest, opts ...grpc.CallOption) (*gatewayapi.ResolveImageConfigResponse, error) {
@ -99,29 +104,35 @@ func (g *gatewayClientForBuild) ReadFile(ctx context.Context, in *gatewayapi.Rea
} }
func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) { func (g *gatewayClientForBuild) ReadDir(ctx context.Context, in *gatewayapi.ReadDirRequest, opts ...grpc.CallOption) (*gatewayapi.ReadDirResponse, error) {
if err := g.caps.Supports(gatewayapi.CapReadDir); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapReadDir); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.ReadDir(ctx, in, opts...) return g.gateway.ReadDir(ctx, in, opts...)
} }
func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) { func (g *gatewayClientForBuild) StatFile(ctx context.Context, in *gatewayapi.StatFileRequest, opts ...grpc.CallOption) (*gatewayapi.StatFileResponse, error) {
if err := g.caps.Supports(gatewayapi.CapStatFile); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapStatFile); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.StatFile(ctx, in, opts...) return g.gateway.StatFile(ctx, in, opts...)
} }
func (g *gatewayClientForBuild) Evaluate(ctx context.Context, in *gatewayapi.EvaluateRequest, opts ...grpc.CallOption) (*gatewayapi.EvaluateResponse, error) { func (g *gatewayClientForBuild) Evaluate(ctx context.Context, in *gatewayapi.EvaluateRequest, opts ...grpc.CallOption) (*gatewayapi.EvaluateResponse, error) {
if err := g.caps.Supports(gatewayapi.CapGatewayEvaluate); err != nil { if g.caps != nil {
if err2 := g.caps.Supports(gatewayapi.CapStatFile); err2 != nil { if err := g.caps.Supports(gatewayapi.CapGatewayEvaluate); err != nil {
return nil, err if err2 := g.caps.Supports(gatewayapi.CapStatFile); err2 != nil {
return nil, err
}
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
_, err := g.gateway.StatFile(ctx, &gatewayapi.StatFileRequest{Ref: in.Ref, Path: "."}, opts...)
return &gatewayapi.EvaluateResponse{}, err
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
_, err := g.gateway.StatFile(ctx, &gatewayapi.StatFileRequest{Ref: in.Ref, Path: "."}, opts...)
return &gatewayapi.EvaluateResponse{}, err
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.Evaluate(ctx, in, opts...) return g.gateway.Evaluate(ctx, in, opts...)
@ -138,32 +149,40 @@ func (g *gatewayClientForBuild) Return(ctx context.Context, in *gatewayapi.Retur
} }
func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) { func (g *gatewayClientForBuild) Inputs(ctx context.Context, in *gatewayapi.InputsRequest, opts ...grpc.CallOption) (*gatewayapi.InputsResponse, error) {
if err := g.caps.Supports(gatewayapi.CapFrontendInputs); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapFrontendInputs); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.Inputs(ctx, in, opts...) return g.gateway.Inputs(ctx, in, opts...)
} }
func (g *gatewayClientForBuild) NewContainer(ctx context.Context, in *gatewayapi.NewContainerRequest, opts ...grpc.CallOption) (*gatewayapi.NewContainerResponse, error) { func (g *gatewayClientForBuild) NewContainer(ctx context.Context, in *gatewayapi.NewContainerRequest, opts ...grpc.CallOption) (*gatewayapi.NewContainerResponse, error) {
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.NewContainer(ctx, in, opts...) return g.gateway.NewContainer(ctx, in, opts...)
} }
func (g *gatewayClientForBuild) ReleaseContainer(ctx context.Context, in *gatewayapi.ReleaseContainerRequest, opts ...grpc.CallOption) (*gatewayapi.ReleaseContainerResponse, error) { func (g *gatewayClientForBuild) ReleaseContainer(ctx context.Context, in *gatewayapi.ReleaseContainerRequest, opts ...grpc.CallOption) (*gatewayapi.ReleaseContainerResponse, error) {
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.ReleaseContainer(ctx, in, opts...) return g.gateway.ReleaseContainer(ctx, in, opts...)
} }
func (g *gatewayClientForBuild) ExecProcess(ctx context.Context, opts ...grpc.CallOption) (gatewayapi.LLBBridge_ExecProcessClient, error) { func (g *gatewayClientForBuild) ExecProcess(ctx context.Context, opts ...grpc.CallOption) (gatewayapi.LLBBridge_ExecProcessClient, error) {
if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil { if g.caps != nil {
return nil, err if err := g.caps.Supports(gatewayapi.CapGatewayExec); err != nil {
return nil, err
}
} }
ctx = buildid.AppendToOutgoingContext(ctx, g.buildID) ctx = buildid.AppendToOutgoingContext(ctx, g.buildID)
return g.gateway.ExecProcess(ctx, opts...) return g.gateway.ExecProcess(ctx, opts...)

View File

@ -435,6 +435,13 @@ func Local(name string, opts ...LocalOption) State {
addCap(&gi.Constraints, pb.CapSourceLocalDiffer) addCap(&gi.Constraints, pb.CapSourceLocalDiffer)
} }
} }
if gi.MetadataOnlyCollector {
attrs[pb.AttrMetadataTransfer] = "true"
if gi.MetadataOnlyExceptions != "" {
attrs[pb.AttrMetadataTransferExclude] = gi.MetadataOnlyExceptions
}
addCap(&gi.Constraints, pb.CapSourceMetadataTransfer)
}
addCap(&gi.Constraints, pb.CapSourceLocal) addCap(&gi.Constraints, pb.CapSourceLocal)
@ -506,6 +513,18 @@ func Differ(t DiffType, required bool) LocalOption {
}) })
} }
func MetadataOnlyTransfer(exceptions []string) LocalOption {
return localOptionFunc(func(li *LocalInfo) {
li.MetadataOnlyCollector = true
if len(exceptions) == 0 {
li.MetadataOnlyExceptions = ""
} else {
dt, _ := json.Marshal(exceptions) // empty on error
li.MetadataOnlyExceptions = string(dt)
}
})
}
func OCILayout(ref string, opts ...OCILayoutOption) State { func OCILayout(ref string, opts ...OCILayoutOption) State {
gi := &OCILayoutInfo{} gi := &OCILayoutInfo{}
@ -578,12 +597,14 @@ type DifferInfo struct {
type LocalInfo struct { type LocalInfo struct {
constraintsWrapper constraintsWrapper
SessionID string SessionID string
IncludePatterns string IncludePatterns string
ExcludePatterns string ExcludePatterns string
FollowPaths string FollowPaths string
SharedKeyHint string SharedKeyHint string
Differ DifferInfo Differ DifferInfo
MetadataOnlyCollector bool
MetadataOnlyExceptions string
} }
func HTTP(url string, opts ...HTTPOption) State { func HTTP(url string, opts ...HTTPOption) State {

View File

@ -35,6 +35,7 @@ import (
type SolveOpt struct { type SolveOpt struct {
Exports []ExportEntry Exports []ExportEntry
EnableSessionExporter bool
LocalDirs map[string]string // Deprecated: use LocalMounts LocalDirs map[string]string // Deprecated: use LocalMounts
LocalMounts map[string]fsutil.FS LocalMounts map[string]fsutil.FS
OCIStores map[string]content.Store OCIStores map[string]content.Store
@ -270,6 +271,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
Exporters: exports, Exporters: exports,
ExporterDeprecated: exportDeprecated, ExporterDeprecated: exportDeprecated,
ExporterAttrsDeprecated: exportAttrDeprecated, ExporterAttrsDeprecated: exportAttrDeprecated,
EnableSessionExporter: opt.EnableSessionExporter,
Session: s.ID(), Session: s.ID(),
Frontend: opt.Frontend, Frontend: opt.Frontend,
FrontendAttrs: frontendAttrs, FrontendAttrs: frontendAttrs,

View File

@ -83,7 +83,7 @@ func (wc *streamWriterCloser) Close() error {
return nil return nil
} }
func recvDiffCopy(ds grpc.ClientStream, dest string, cu CacheUpdater, progress progressCb, differ fsutil.DiffType, filter func(string, *fstypes.Stat) bool) (err error) { func recvDiffCopy(ds grpc.ClientStream, dest string, cu CacheUpdater, progress progressCb, differ fsutil.DiffType, filter, metadataOnlyFilter func(string, *fstypes.Stat) bool) (err error) {
st := time.Now() st := time.Now()
defer func() { defer func() {
bklog.G(ds.Context()).Debugf("diffcopy took: %v", time.Since(st)) bklog.G(ds.Context()).Debugf("diffcopy took: %v", time.Since(st))
@ -107,6 +107,7 @@ func recvDiffCopy(ds grpc.ClientStream, dest string, cu CacheUpdater, progress p
ProgressCb: progress, ProgressCb: progress,
Filter: fsutil.FilterFunc(filter), Filter: fsutil.FilterFunc(filter),
Differ: differ, Differ: differ,
MetadataOnly: metadataOnlyFilter,
})) }))
} }

View File

@ -3,7 +3,7 @@ package filesync
import ( import (
"context" "context"
"fmt" "fmt"
io "io" "io"
"net/url" "net/url"
"os" "os"
"strconv" "strconv"
@ -145,7 +145,7 @@ type progressCb func(int, bool)
type protocol struct { type protocol struct {
name string name string
sendFn func(stream Stream, fs fsutil.FS, progress progressCb) error sendFn func(stream Stream, fs fsutil.FS, progress progressCb) error
recvFn func(stream grpc.ClientStream, destDir string, cu CacheUpdater, progress progressCb, differ fsutil.DiffType, mapFunc func(string, *fstypes.Stat) bool) error recvFn func(stream grpc.ClientStream, destDir string, cu CacheUpdater, progress progressCb, differ fsutil.DiffType, mapFunc, metadataOnlyFilter func(string, *fstypes.Stat) bool) error
} }
var supportedProtocols = []protocol{ var supportedProtocols = []protocol{
@ -158,15 +158,17 @@ var supportedProtocols = []protocol{
// FSSendRequestOpt defines options for FSSend request // FSSendRequestOpt defines options for FSSend request
type FSSendRequestOpt struct { type FSSendRequestOpt struct {
Name string Name string
IncludePatterns []string IncludePatterns []string
ExcludePatterns []string ExcludePatterns []string
FollowPaths []string FollowPaths []string
DestDir string DestDir string
CacheUpdater CacheUpdater CacheUpdater CacheUpdater
ProgressCb func(int, bool) ProgressCb func(int, bool)
Filter func(string, *fstypes.Stat) bool Filter func(string, *fstypes.Stat) bool
Differ fsutil.DiffType Differ fsutil.DiffType
MetadataOnly bool
MetadataOnlyFilter func(string, *fstypes.Stat) bool
} }
// CacheUpdater is an object capable of sending notifications for the cache hash changes // CacheUpdater is an object capable of sending notifications for the cache hash changes
@ -233,7 +235,16 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error {
panic(fmt.Sprintf("invalid protocol: %q", pr.name)) panic(fmt.Sprintf("invalid protocol: %q", pr.name))
} }
return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb, opt.Differ, opt.Filter) var metadataOnlyFilter func(string, *fstypes.Stat) bool
if opt.MetadataOnly {
if opt.MetadataOnlyFilter != nil {
metadataOnlyFilter = opt.MetadataOnlyFilter
} else {
metadataOnlyFilter = func(string, *fstypes.Stat) bool { return false }
}
}
return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb, opt.Differ, opt.Filter, metadataOnlyFilter)
} }
type FSSyncTarget interface { type FSSyncTarget interface {
@ -264,34 +275,39 @@ func WithFSSyncDir(id int, outdir string) FSSyncTarget {
} }
} }
func NewFSSyncTarget(targets ...FSSyncTarget) session.Attachable { func NewFSSyncTarget(targets ...FSSyncTarget) *SyncTarget {
fs := make(map[int]FileOutputFunc) st := &SyncTarget{
outdirs := make(map[int]string) fs: make(map[int]FileOutputFunc),
for _, t := range targets { outdirs: make(map[int]string),
t := t.target()
if t.f != nil {
fs[t.id] = t.f
}
if t.outdir != "" {
outdirs[t.id] = t.outdir
}
}
return &fsSyncAttachable{
fs: fs,
outdirs: outdirs,
} }
st.Add(targets...)
return st
} }
type fsSyncAttachable struct { type SyncTarget struct {
fs map[int]FileOutputFunc fs map[int]FileOutputFunc
outdirs map[int]string outdirs map[int]string
} }
func (sp *fsSyncAttachable) Register(server *grpc.Server) { var _ session.Attachable = &SyncTarget{}
func (sp *SyncTarget) Add(targets ...FSSyncTarget) {
for _, t := range targets {
t := t.target()
if t.f != nil {
sp.fs[t.id] = t.f
}
if t.outdir != "" {
sp.outdirs[t.id] = t.outdir
}
}
}
func (sp *SyncTarget) Register(server *grpc.Server) {
RegisterFileSendServer(server, sp) RegisterFileSendServer(server, sp)
} }
func (sp *fsSyncAttachable) chooser(ctx context.Context) int { func (sp *SyncTarget) chooser(ctx context.Context) int {
md, ok := metadata.FromIncomingContext(ctx) md, ok := metadata.FromIncomingContext(ctx)
if !ok { if !ok {
return 0 return 0
@ -307,7 +323,7 @@ func (sp *fsSyncAttachable) chooser(ctx context.Context) int {
return int(id) return int(id)
} }
func (sp *fsSyncAttachable) DiffCopy(stream FileSend_DiffCopyServer) (err error) { func (sp *SyncTarget) DiffCopy(stream FileSend_DiffCopyServer) (err error) {
id := sp.chooser(stream.Context()) id := sp.chooser(stream.Context())
if outdir, ok := sp.outdirs[id]; ok { if outdir, ok := sp.outdirs[id]; ok {
return syncTargetDiffCopy(stream, outdir) return syncTargetDiffCopy(stream, outdir)

View File

@ -12,6 +12,8 @@ const AttrIncludePatterns = "local.includepattern"
const AttrFollowPaths = "local.followpaths" const AttrFollowPaths = "local.followpaths"
const AttrExcludePatterns = "local.excludepatterns" const AttrExcludePatterns = "local.excludepatterns"
const AttrSharedKeyHint = "local.sharedkeyhint" const AttrSharedKeyHint = "local.sharedkeyhint"
const AttrMetadataTransfer = "local.metadatatransfer"
const AttrMetadataTransferExclude = "local.metadatatransferexclude"
const AttrLLBDefinitionFilename = "llbbuild.filename" const AttrLLBDefinitionFilename = "llbbuild.filename"

View File

@ -21,6 +21,7 @@ const (
CapSourceLocalExcludePatterns apicaps.CapID = "source.local.excludepatterns" CapSourceLocalExcludePatterns apicaps.CapID = "source.local.excludepatterns"
CapSourceLocalSharedKeyHint apicaps.CapID = "source.local.sharedkeyhint" CapSourceLocalSharedKeyHint apicaps.CapID = "source.local.sharedkeyhint"
CapSourceLocalDiffer apicaps.CapID = "source.local.differ" CapSourceLocalDiffer apicaps.CapID = "source.local.differ"
CapSourceMetadataTransfer apicaps.CapID = "source.local.metadatatransfer"
CapSourceGit apicaps.CapID = "source.git" CapSourceGit apicaps.CapID = "source.git"
CapSourceGitKeepDir apicaps.CapID = "source.git.keepgitdir" CapSourceGitKeepDir apicaps.CapID = "source.git.keepgitdir"
@ -95,6 +96,7 @@ const (
CapSourceDateEpoch apicaps.CapID = "exporter.sourcedateepoch" CapSourceDateEpoch apicaps.CapID = "exporter.sourcedateepoch"
CapMultipleExporters apicaps.CapID = "exporter.multiple" CapMultipleExporters apicaps.CapID = "exporter.multiple"
CapSessionExporter apicaps.CapID = "exporter.session"
CapSourcePolicy apicaps.CapID = "source.policy" CapSourcePolicy apicaps.CapID = "source.policy"
@ -172,6 +174,12 @@ func init() {
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapSourceMetadataTransfer,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapSourceGit, ID: CapSourceGit,
Enabled: true, Enabled: true,
@ -519,6 +527,12 @@ func init() {
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapSessionExporter,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapSourcePolicy, ID: CapSourcePolicy,
Enabled: true, Enabled: true,

44
vendor/github.com/tonistiigi/fsutil/buffer.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
package fsutil
import (
"io"
)
const chunkSize = 32 * 1024
type buffer struct {
chunks [][]byte
}
func (b *buffer) alloc(n int) []byte {
if n > chunkSize {
buf := make([]byte, n)
b.chunks = append(b.chunks, buf)
return buf
}
if len(b.chunks) != 0 {
lastChunk := b.chunks[len(b.chunks)-1]
l := len(lastChunk)
if l+n <= cap(lastChunk) {
lastChunk = lastChunk[:l+n]
b.chunks[len(b.chunks)-1] = lastChunk
return lastChunk[l : l+n]
}
}
buf := make([]byte, n, chunkSize)
b.chunks = append(b.chunks, buf)
return buf
}
func (b *buffer) WriteTo(w io.Writer) (n int64, err error) {
for _, c := range b.chunks {
m, err := w.Write(c)
n += int64(m)
if err != nil {
return n, err
}
}
return n, nil
}

View File

@ -32,6 +32,7 @@ package fsutil
import ( import (
"context" "context"
"encoding/binary"
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
@ -51,6 +52,8 @@ const (
DiffContent DiffContent
) )
const metadataPath = ".fsutil-metadata"
type ReceiveOpt struct { type ReceiveOpt struct {
NotifyHashed ChangeFunc NotifyHashed ChangeFunc
ContentHasher ContentHasher ContentHasher ContentHasher
@ -58,6 +61,7 @@ type ReceiveOpt struct {
Merge bool Merge bool
Filter FilterFunc Filter FilterFunc
Differ DiffType Differ DiffType
MetadataOnly FilterFunc
} }
func Receive(ctx context.Context, conn Stream, dest string, opt ReceiveOpt) error { func Receive(ctx context.Context, conn Stream, dest string, opt ReceiveOpt) error {
@ -75,21 +79,23 @@ func Receive(ctx context.Context, conn Stream, dest string, opt ReceiveOpt) erro
merge: opt.Merge, merge: opt.Merge,
filter: opt.Filter, filter: opt.Filter,
differ: opt.Differ, differ: opt.Differ,
metadataOnly: opt.MetadataOnly,
} }
return r.run(ctx) return r.run(ctx)
} }
type receiver struct { type receiver struct {
dest string dest string
conn Stream conn Stream
files map[string]uint32 files map[string]uint32
pipes map[uint32]io.WriteCloser pipes map[uint32]io.WriteCloser
mu sync.RWMutex mu sync.RWMutex
muPipes sync.RWMutex muPipes sync.RWMutex
progressCb func(int, bool) progressCb func(int, bool)
merge bool merge bool
filter FilterFunc filter FilterFunc
differ DiffType differ DiffType
metadataOnly FilterFunc
notifyHashed ChangeFunc notifyHashed ChangeFunc
contentHasher ContentHasher contentHasher ContentHasher
@ -164,6 +170,11 @@ func (r *receiver) run(ctx context.Context) error {
} }
w := newDynamicWalker() w := newDynamicWalker()
metadataTransfer := r.metadataOnly != nil
// buffer Stat metadata in framed proto
metadataBuffer := &buffer{}
// stack of parent paths that can be replayed if metadata filter matches
metadataParents := newStack[*currentPath]()
g.Go(func() (retErr error) { g.Go(func() (retErr error) {
defer func() { defer func() {
@ -223,10 +234,26 @@ func (r *receiver) run(ctx context.Context) error {
// e.g. a linux path foo/bar\baz cannot be represented on windows // e.g. a linux path foo/bar\baz cannot be represented on windows
return errors.WithStack(&os.PathError{Path: p.Stat.Path, Err: syscall.EINVAL, Op: "unrepresentable path"}) return errors.WithStack(&os.PathError{Path: p.Stat.Path, Err: syscall.EINVAL, Op: "unrepresentable path"})
} }
var metaOnly bool
if metadataTransfer {
if path == metadataPath {
continue
}
n := p.Stat.SizeVT()
dt := metadataBuffer.alloc(n + 4)
binary.LittleEndian.PutUint32(dt[0:4], uint32(n))
_, err := p.Stat.MarshalToSizedBufferVT(dt[4:])
if err != nil {
return err
}
if !r.metadataOnly(path, p.Stat) {
metaOnly = true
}
}
p.Stat.Path = path p.Stat.Path = path
p.Stat.Linkname = filepath.FromSlash(p.Stat.Linkname) p.Stat.Linkname = filepath.FromSlash(p.Stat.Linkname)
if fileCanRequestData(os.FileMode(p.Stat.Mode)) { if !metaOnly && fileCanRequestData(os.FileMode(p.Stat.Mode)) {
r.mu.Lock() r.mu.Lock()
r.files[p.Stat.Path] = i r.files[p.Stat.Path] = i
r.mu.Unlock() r.mu.Unlock()
@ -240,6 +267,31 @@ func (r *receiver) run(ctx context.Context) error {
if err := r.hlValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil { if err := r.hlValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil {
return err return err
} }
if metadataTransfer {
parent := filepath.Dir(cp.path)
isDir := os.FileMode(p.Stat.Mode).IsDir()
for {
last, ok := metadataParents.peek()
if !ok || parent == last.path {
break
}
metadataParents.pop()
}
if isDir {
metadataParents.push(cp)
}
if metaOnly {
continue
} else {
for _, cp := range metadataParents.items {
if err := w.update(cp); err != nil {
return err
}
}
metadataParents.clear()
}
}
if err := w.update(cp); err != nil { if err := w.update(cp); err != nil {
return err return err
} }
@ -272,7 +324,27 @@ func (r *receiver) run(ctx context.Context) error {
} }
} }
}) })
return g.Wait()
if err := g.Wait(); err != nil {
return err
}
if !metadataTransfer {
return nil
}
// although we don't allow tranferring metadataPath, make sure there was no preexisting file/symlink
os.Remove(filepath.Join(r.dest, metadataPath))
f, err := os.OpenFile(filepath.Join(r.dest, metadataPath), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
if _, err := metadataBuffer.WriteTo(f); err != nil {
f.Close()
return err
}
return f.Close()
} }
func (r *receiver) asyncDataFunc(ctx context.Context, p string, wc io.WriteCloser) error { func (r *receiver) asyncDataFunc(ctx context.Context, p string, wc io.WriteCloser) error {
@ -327,3 +399,39 @@ func (w *wrappedWriteCloser) Wait(ctx context.Context) error {
return w.err return w.err
} }
} }
type stack[T any] struct {
items []T
}
func newStack[T any]() *stack[T] {
return &stack[T]{
items: make([]T, 0, 8),
}
}
func (s *stack[T]) push(v T) {
s.items = append(s.items, v)
}
func (s *stack[T]) pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
v := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return v, true
}
func (s *stack[T]) peek() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
return s.items[len(s.items)-1], true
}
func (s *stack[T]) clear() {
s.items = s.items[:0]
}

27
vendor/golang.org/x/exp/LICENSE generated vendored
View File

@ -1,27 +0,0 @@
Copyright 2009 The Go Authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
vendor/golang.org/x/exp/PATENTS generated vendored
View File

@ -1,22 +0,0 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View File

@ -1,54 +0,0 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package constraints defines a set of useful constraints to be used
// with type parameters.
package constraints
import "cmp"
// Signed is a constraint that permits any signed integer type.
// If future releases of Go add new predeclared signed integer types,
// this constraint will be modified to include them.
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
// Unsigned is a constraint that permits any unsigned integer type.
// If future releases of Go add new predeclared unsigned integer types,
// this constraint will be modified to include them.
type Unsigned interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
// Integer is a constraint that permits any integer type.
// If future releases of Go add new predeclared integer types,
// this constraint will be modified to include them.
type Integer interface {
Signed | Unsigned
}
// Float is a constraint that permits any floating-point type.
// If future releases of Go add new predeclared floating-point types,
// this constraint will be modified to include them.
type Float interface {
~float32 | ~float64
}
// Complex is a constraint that permits any complex numeric type.
// If future releases of Go add new predeclared complex numeric types,
// this constraint will be modified to include them.
type Complex interface {
~complex64 | ~complex128
}
// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
//
// This type is redundant since Go 1.21 introduced [cmp.Ordered].
//
//go:fix inline
type Ordered = cmp.Ordered

86
vendor/golang.org/x/exp/maps/maps.go generated vendored
View File

@ -1,86 +0,0 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package maps defines various functions useful with maps of any type.
package maps
import "maps"
// Keys returns the keys of the map m.
// The keys will be in an indeterminate order.
//
// The simplest true equivalent using the standard library is:
//
// slices.AppendSeq(make([]K, 0, len(m)), maps.Keys(m))
func Keys[M ~map[K]V, K comparable, V any](m M) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
// Values returns the values of the map m.
// The values will be in an indeterminate order.
//
// The simplest true equivalent using the standard library is:
//
// slices.AppendSeq(make([]V, 0, len(m)), maps.Values(m))
func Values[M ~map[K]V, K comparable, V any](m M) []V {
r := make([]V, 0, len(m))
for _, v := range m {
r = append(r, v)
}
return r
}
// Equal reports whether two maps contain the same key/value pairs.
// Values are compared using ==.
//
//go:fix inline
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool {
return maps.Equal(m1, m2)
}
// EqualFunc is like Equal, but compares values using eq.
// Keys are still compared with ==.
//
//go:fix inline
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool {
return maps.EqualFunc(m1, m2, eq)
}
// Clear removes all entries from m, leaving it empty.
//
//go:fix inline
func Clear[M ~map[K]V, K comparable, V any](m M) {
clear(m)
}
// Clone returns a copy of m. This is a shallow clone:
// the new keys and values are set using ordinary assignment.
//
//go:fix inline
func Clone[M ~map[K]V, K comparable, V any](m M) M {
return maps.Clone(m)
}
// Copy copies all key/value pairs in src adding them to dst.
// When a key in src is already present in dst,
// the value in dst will be overwritten by the value associated
// with the key in src.
//
//go:fix inline
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) {
maps.Copy(dst, src)
}
// DeleteFunc deletes any key/value pairs from m for which del returns true.
//
//go:fix inline
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) {
maps.DeleteFunc(m, del)
}

View File

@ -1,182 +0,0 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package slices defines various functions useful with slices of any type.
package slices
import (
"cmp"
"slices"
)
// Equal reports whether two slices are equal: the same length and all
// elements equal. If the lengths are different, Equal returns false.
// Otherwise, the elements are compared in increasing index order, and the
// comparison stops at the first unequal pair.
// Floating point NaNs are not considered equal.
//
//go:fix inline
func Equal[S ~[]E, E comparable](s1, s2 S) bool {
return slices.Equal(s1, s2)
}
// EqualFunc reports whether two slices are equal using an equality
// function on each pair of elements. If the lengths are different,
// EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index
// for which eq returns false.
//
//go:fix inline
func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
return slices.EqualFunc(s1, s2, eq)
}
// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
// of elements. The elements are compared sequentially, starting at index 0,
// until one element is not equal to the other.
// The result of comparing the first non-matching elements is returned.
// If both slices are equal until one of them ends, the shorter slice is
// considered less than the longer one.
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
//
//go:fix inline
func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int {
return slices.Compare(s1, s2)
}
// CompareFunc is like [Compare] but uses a custom comparison function on each
// pair of elements.
// The result is the first non-zero result of cmp; if cmp always
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
// and +1 if len(s1) > len(s2).
//
//go:fix inline
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
return slices.CompareFunc(s1, s2, cmp)
}
// Index returns the index of the first occurrence of v in s,
// or -1 if not present.
//
//go:fix inline
func Index[S ~[]E, E comparable](s S, v E) int {
return slices.Index(s, v)
}
// IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do.
//
//go:fix inline
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
return slices.IndexFunc(s, f)
}
// Contains reports whether v is present in s.
//
//go:fix inline
func Contains[S ~[]E, E comparable](s S, v E) bool {
return slices.Contains(s, v)
}
// ContainsFunc reports whether at least one
// element e of s satisfies f(e).
//
//go:fix inline
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
return slices.ContainsFunc(s, f)
}
// Insert inserts the values v... into s at index i,
// returning the modified slice.
// The elements at s[i:] are shifted up to make room.
// In the returned slice r, r[i] == v[0],
// and r[i+len(v)] == value originally at r[i].
// Insert panics if i is out of range.
// This function is O(len(s) + len(v)).
//
//go:fix inline
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
return slices.Insert(s, i, v...)
}
// Delete removes the elements s[i:j] from s, returning the modified slice.
// Delete panics if j > len(s) or s[i:j] is not a valid slice of s.
// Delete is O(len(s)-i), so if many items must be deleted, it is better to
// make a single call deleting them all together than to delete one at a time.
// Delete zeroes the elements s[len(s)-(j-i):len(s)].
//
//go:fix inline
func Delete[S ~[]E, E any](s S, i, j int) S {
return slices.Delete(s, i, j)
}
// DeleteFunc removes any elements from s for which del returns true,
// returning the modified slice.
// DeleteFunc zeroes the elements between the new length and the original length.
//
//go:fix inline
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
return slices.DeleteFunc(s, del)
}
// Replace replaces the elements s[i:j] by the given v, and returns the
// modified slice. Replace panics if s[i:j] is not a valid slice of s.
// When len(v) < (j-i), Replace zeroes the elements between the new length and the original length.
//
//go:fix inline
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
return slices.Replace(s, i, j, v...)
}
// Clone returns a copy of the slice.
// The elements are copied using assignment, so this is a shallow clone.
//
//go:fix inline
func Clone[S ~[]E, E any](s S) S {
return slices.Clone(s)
}
// Compact replaces consecutive runs of equal elements with a single copy.
// This is like the uniq command found on Unix.
// Compact modifies the contents of the slice s and returns the modified slice,
// which may have a smaller length.
// Compact zeroes the elements between the new length and the original length.
//
//go:fix inline
func Compact[S ~[]E, E comparable](s S) S {
return slices.Compact(s)
}
// CompactFunc is like [Compact] but uses an equality function to compare elements.
// For runs of elements that compare equal, CompactFunc keeps the first one.
// CompactFunc zeroes the elements between the new length and the original length.
//
//go:fix inline
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
return slices.CompactFunc(s, eq)
}
// Grow increases the slice's capacity, if necessary, to guarantee space for
// another n elements. After Grow(n), at least n elements can be appended
// to the slice without another allocation. If n is negative or too large to
// allocate the memory, Grow panics.
//
//go:fix inline
func Grow[S ~[]E, E any](s S, n int) S {
return slices.Grow(s, n)
}
// Clip removes unused capacity from the slice, returning s[:len(s):len(s)].
//
//go:fix inline
func Clip[S ~[]E, E any](s S) S {
return slices.Clip(s)
}
// Reverse reverses the elements of the slice in place.
//
//go:fix inline
func Reverse[S ~[]E, E any](s S) {
slices.Reverse(s)
}

View File

@ -1,115 +0,0 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package slices
import (
"cmp"
"slices"
)
// Sort sorts a slice of any ordered type in ascending order.
// When sorting floating-point numbers, NaNs are ordered before other values.
//
//go:fix inline
func Sort[S ~[]E, E cmp.Ordered](x S) {
slices.Sort(x)
}
// SortFunc sorts the slice x in ascending order as determined by the cmp
// function. This sort is not guaranteed to be stable.
// cmp(a, b) should return a negative number when a < b, a positive number when
// a > b and zero when a == b or when a is not comparable to b in the sense
// of the formal definition of Strict Weak Ordering.
//
// SortFunc requires that cmp is a strict weak ordering.
// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
// To indicate 'uncomparable', return 0 from the function.
//
//go:fix inline
func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
slices.SortFunc(x, cmp)
}
// SortStableFunc sorts the slice x while keeping the original order of equal
// elements, using cmp to compare elements in the same way as [SortFunc].
//
//go:fix inline
func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
slices.SortStableFunc(x, cmp)
}
// IsSorted reports whether x is sorted in ascending order.
//
//go:fix inline
func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
return slices.IsSorted(x)
}
// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
// comparison function as defined by [SortFunc].
//
//go:fix inline
func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
return slices.IsSortedFunc(x, cmp)
}
// Min returns the minimal value in x. It panics if x is empty.
// For floating-point numbers, Min propagates NaNs (any NaN value in x
// forces the output to be NaN).
//
//go:fix inline
func Min[S ~[]E, E cmp.Ordered](x S) E {
return slices.Min(x)
}
// MinFunc returns the minimal value in x, using cmp to compare elements.
// It panics if x is empty. If there is more than one minimal element
// according to the cmp function, MinFunc returns the first one.
//
//go:fix inline
func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
return slices.MinFunc(x, cmp)
}
// Max returns the maximal value in x. It panics if x is empty.
// For floating-point E, Max propagates NaNs (any NaN value in x
// forces the output to be NaN).
//
//go:fix inline
func Max[S ~[]E, E cmp.Ordered](x S) E {
return slices.Max(x)
}
// MaxFunc returns the maximal value in x, using cmp to compare elements.
// It panics if x is empty. If there is more than one maximal element
// according to the cmp function, MaxFunc returns the first one.
//
//go:fix inline
func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
return slices.MaxFunc(x, cmp)
}
// BinarySearch searches for target in a sorted slice and returns the position
// where target is found, or the position where target would appear in the
// sort order; it also returns a bool saying whether the target is really found
// in the slice. The slice must be sorted in increasing order.
//
//go:fix inline
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
return slices.BinarySearch(x, target)
}
// BinarySearchFunc works like [BinarySearch], but uses a custom comparison
// function. The slice must be sorted in increasing order, where "increasing"
// is defined by cmp. cmp should return 0 if the slice element matches
// the target, a negative number if the slice element precedes the target,
// or a positive number if the slice element follows the target.
// cmp must implement the same ordering as the slice, such that if
// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
//
//go:fix inline
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
return slices.BinarySearchFunc(x, target, cmp)
}

11
vendor/modules.txt vendored
View File

@ -128,7 +128,7 @@ github.com/cenkalti/backoff/v4
# github.com/cespare/xxhash/v2 v2.3.0 # github.com/cespare/xxhash/v2 v2.3.0
## explicit; go 1.11 ## explicit; go 1.11
github.com/cespare/xxhash/v2 github.com/cespare/xxhash/v2
# github.com/compose-spec/compose-go/v2 v2.4.9 # github.com/compose-spec/compose-go/v2 v2.6.0
## explicit; go 1.23 ## explicit; go 1.23
github.com/compose-spec/compose-go/v2/cli github.com/compose-spec/compose-go/v2/cli
github.com/compose-spec/compose-go/v2/consts github.com/compose-spec/compose-go/v2/consts
@ -479,7 +479,7 @@ github.com/mitchellh/go-wordwrap
# github.com/mitchellh/hashstructure/v2 v2.0.2 # github.com/mitchellh/hashstructure/v2 v2.0.2
## explicit; go 1.14 ## explicit; go 1.14
github.com/mitchellh/hashstructure/v2 github.com/mitchellh/hashstructure/v2
# github.com/moby/buildkit v0.21.0-rc1 # github.com/moby/buildkit v0.21.0-rc2
## explicit; go 1.23.0 ## explicit; go 1.23.0
github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types github.com/moby/buildkit/api/types
@ -702,7 +702,7 @@ github.com/stretchr/testify/require
# github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 # github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323
## explicit; go 1.21 ## explicit; go 1.21
github.com/tonistiigi/dchapes-mode github.com/tonistiigi/dchapes-mode
# github.com/tonistiigi/fsutil v0.0.0-20250318190121-d73a4b3b8a7e # github.com/tonistiigi/fsutil v0.0.0-20250410151801-5b74a7ad7583
## explicit; go 1.21 ## explicit; go 1.21
github.com/tonistiigi/fsutil github.com/tonistiigi/fsutil
github.com/tonistiigi/fsutil/copy github.com/tonistiigi/fsutil/copy
@ -858,11 +858,6 @@ golang.org/x/crypto/nacl/sign
golang.org/x/crypto/ssh golang.org/x/crypto/ssh
golang.org/x/crypto/ssh/agent golang.org/x/crypto/ssh/agent
golang.org/x/crypto/ssh/internal/bcrypt_pbkdf golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
# golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0
## explicit; go 1.23.0
golang.org/x/exp/constraints
golang.org/x/exp/maps
golang.org/x/exp/slices
# golang.org/x/mod v0.24.0 # golang.org/x/mod v0.24.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
golang.org/x/mod/internal/lazyregexp golang.org/x/mod/internal/lazyregexp